Skip to content

Commit 95fc434

Browse files
authored
Merge pull request #20 from Jalen-Stephens/7-api-implement-authcontroller-endpoints
7 api implement authcontroller endpoints
2 parents a305d16 + 5a22ffb commit 95fc434

File tree

16 files changed

+1013
-116
lines changed

16 files changed

+1013
-116
lines changed

citations.md

Lines changed: 231 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,4 +495,234 @@ Assisted in drafting a unit test suite for the `UserService` to validate identit
495495

496496
> Portions of this test suite and build configuration were generated with assistance from OpenAI ChatGPT (GPT-5) on February 27, 2025. All AI-generated content was reviewed, verified, and finalized by the development team.
497497
498-
---
498+
---
499+
500+
### **Commit / Ticket Reference**
501+
502+
* **Commit:** `feat(auth): add Supabase auth proxy + /auth endpoints + JWKS resource server config (refs #7)`
503+
* **Ticket:** `#7 — Implement Supabase-backed authentication`
504+
* **Date:** October 21, 2025
505+
* **Team Member:** Jalen Stephens
506+
507+
---
508+
509+
### **AI Tool Information**
510+
511+
* **Tool Used:** OpenAI ChatGPT (GPT-5)
512+
* **Access Method:** ChatGPT Web (.edu academic access)
513+
* **Configuration:** Default model settings
514+
* **Cost:** $0 (no paid API calls)
515+
516+
---
517+
518+
### **Purpose of AI Assistance**
519+
520+
The AI assisted in designing and scaffolding the Supabase authentication proxy integration. This included creating the `AuthProxyService`, generating a preconfigured `WebClient` for Supabase Auth endpoints, adding `/auth` controller routes, wiring JWT validation through Supabase’s JWKS, and ensuring all components passed Checkstyle and compilation checks. The AI also provided setup guidance for environment variables and secure configuration management.
521+
522+
---
523+
524+
### **Prompts / Interaction Summary**
525+
526+
* Repeat full proxy wiring code block for AuthController and SupabaseClientConfig
527+
* Add missing Javadoc comments for Checkstyle compliance
528+
* Resolve `HttpStatus` vs `HttpStatusCode` compilation mismatch
529+
* Provide environment variable export commands using `set -a` and `.env.local`
530+
* Validate correct JWKS configuration in Spring Boot (`spring.security.oauth2.resourceserver.jwt.jwk-set-uri`)
531+
* Generate `AuthControllerTest` for endpoint validation
532+
533+
---
534+
535+
### **Resulting Artifacts**
536+
537+
* **New:** `SupabaseClientConfig.java`
538+
* **New:** `AuthProxyService.java`
539+
* **Modified:** `AuthController.java` (added `/auth/signup`, `/auth/login`, `/auth/refresh`, `/auth/me`)
540+
* **Modified:** `Dtos.java` (added `RefreshRequest` record)
541+
* **Modified:** `application.properties` (added Supabase env-based config and JWKS endpoint)
542+
* **Modified:** `pom.xml` (added WebFlux dependency)
543+
* **Moved:** `UserServiceTest.java` (to `service/` directory)
544+
545+
---
546+
547+
### **Verification**
548+
549+
* Verified build using `mvn checkstyle:check` (0 violations)
550+
* Successfully compiled with `mvn -DskipTests compile` after resolving HttpStatusCode changes
551+
* Confirmed application startup with valid Supabase URL and key configuration
552+
* Manual test planned for `/auth/signup` and `/auth/me` endpoints once live Supabase credentials are applied
553+
554+
---
555+
556+
### **Attribution Statement**
557+
558+
> Portions of this commit and configuration were generated with assistance from OpenAI ChatGPT (GPT-5) on October 21, 2025. All AI-generated content was reviewed, verified, and finalized by the development team.
559+
560+
---
561+
562+
### **Commit / Ticket Reference**
563+
564+
* **Commit:** `test(auth): add controller slice tests + security test config for Supabase proxy (refs #7)`
565+
* **Ticket:** `#7 — Integrate Supabase Auth Proxy + Resource Server`
566+
* **Date:** October 21, 2025
567+
* **Team Member:** Jalen Stephens
568+
569+
---
570+
571+
### **AI Tool Information**
572+
573+
* **Tool Used:** OpenAI ChatGPT (GPT-5)
574+
* **Access Method:** ChatGPT Web (.edu academic access)
575+
* **Configuration:** Default model settings
576+
* **Cost:** $0 (no paid API calls)
577+
578+
---
579+
580+
### **Purpose of AI Assistance**
581+
582+
The AI assisted in designing and drafting controller-slice tests for the `/auth/*` endpoints, as well as creating a dedicated Spring Security test configuration to allow unauthenticated access for the proxy tests. It also helped refine the JSON content-type enforcement in the proxy response so the controller tests aligned with expected client behavior.
583+
584+
---
585+
586+
### **Prompts / Interaction Summary**
587+
588+
* Requested a controller-level test suite for `AuthController`.
589+
* Noticed 403 and 401 blocking proxy tests → requested correction for security config.
590+
* Asked for `SecurityTestConfig` to disable CSRF and allow passthrough behavior.
591+
* AI provided corrections to enable `application/json` for returned `ResponseEntity`.
592+
593+
---
594+
595+
### **Resulting Artifacts**
596+
597+
* Updated logic in `AuthController.java` (exception handler → JSON passthrough)
598+
* Updated `AuthProxyService.java` (explicit JSON content type)
599+
* Added `SecurityTestConfig.java` for test slice security
600+
* Added `AuthControllerTest.java`, covering success and error paths
601+
602+
---
603+
604+
### **Verification**
605+
606+
Changes were validated by:
607+
608+
* Running `mvn clean test` to ensure all tests passed successfully
609+
* Confirming Spring Security configuration allowed test access to `/auth/*`
610+
* Inspecting JaCoCo coverage increase in controller and service layers
611+
* Manual code review for final consistency
612+
613+
---
614+
615+
### **Attribution Statement**
616+
617+
> Portions of this commit or configuration were generated with assistance from OpenAI ChatGPT (GPT-5) on October 21, 2025. All AI-generated content was reviewed, verified, and finalized by the development team.
618+
619+
---
620+
621+
### Commit / Ticket Reference
622+
- Commit: test(auth): add AuthProxyService + config tests and branch coverage for /auth refresh (refs #7)
623+
- Ticket: #7 — Supabase Auth Integration
624+
- Date: October 21, 2025
625+
- Team Member: Jalen Stephens
626+
627+
---
628+
629+
### AI Tool Information
630+
- Tool Used: OpenAI ChatGPT (GPT-5)
631+
- Access Method: ChatGPT Web (.edu academic access)
632+
- Configuration: Default model settings
633+
- Cost: $0 (no paid API calls)
634+
635+
---
636+
637+
### Purpose of AI Assistance
638+
The AI assisted in improving controller branch coverage and validating proxy/auth configuration behavior by generating focused unit tests and updating Dtos coverage.
639+
640+
---
641+
642+
### Prompts / Interaction Summary
643+
Key prompts included:
644+
- “need to increase branch coverage in controllers”
645+
- “tweak my test cases for both these changes”
646+
- “write javadoc comment”
647+
- “fix refresh 400 test”
648+
- “generate commit message and citations”
649+
650+
---
651+
652+
### Resulting Artifacts
653+
- `src/test/java/dev/coms4156/project/metadetect/service/AuthProxyServiceTest.java`
654+
- `src/test/java/dev/coms4156/project/metadetect/config/SupabaseClientConfigTest.java`
655+
- `src/test/java/dev/coms4156/project/metadetect/controller/AuthControllerTest.java` (expanded branch coverage)
656+
- `src/test/java/dev/coms4156/project/metadetect/dto/DtosTest.java`
657+
- Javadoc correction for `/auth/refresh`
658+
- pom adjustments for test dependencies
659+
660+
---
661+
662+
### Verification
663+
Changes were validated via:
664+
- `mvn clean test` passing successfully
665+
- increased coverage reported in JaCoCo
666+
- manual review of error-path coverage in controller
667+
668+
---
669+
670+
### Attribution Statement
671+
> Portions of this commit or configuration were generated with assistance from OpenAI ChatGPT (GPT-5) on October 21, 2025. All AI-generated content was reviewed, verified, and finalized by the development team.
672+
---
673+
674+
### **Commit / Ticket Reference**
675+
676+
* **Commit:** `chore(security): clean SecurityConfig imports and finalize JWKS config for prod (refs #7)`
677+
* **Ticket:** `#7 — Supabase Auth Integration`
678+
* **Date:** October 21, 2025
679+
* **Team Member:** Jalen Stephens
680+
681+
---
682+
683+
### **AI Tool Information**
684+
685+
* **Tool Used:** OpenAI ChatGPT (GPT-5)
686+
* **Access Method:** ChatGPT Web (.edu academic access)
687+
* **Configuration:** Default model settings
688+
* **Cost:** $0 (no paid API calls)
689+
690+
---
691+
692+
### **Purpose of AI Assistance**
693+
694+
Guidance on finalizing Spring Security JWT resource server configuration for Supabase, correcting JWKS endpoint wiring, and addressing Checkstyle star-import violations in `SecurityConfig.java`.
695+
696+
---
697+
698+
### **Prompts / Interaction Summary**
699+
700+
* Asked how to allow unauthenticated signup/login while keeping `/auth/me` secured.
701+
* Verified JWKS vs. local symmetric-signature mode for development.
702+
* Asked for recommended commit message and proper citation entry wording.
703+
* Requested guidance on Checkstyle warnings and star-import cleanup.
704+
705+
---
706+
707+
### **Resulting Artifacts**
708+
709+
* Adjusted `SecurityConfig.java` (import cleanup and JWKS logic finalized).
710+
* Updated `application.properties` to cleanly reference `spring.security.oauth2.resourceserver.jwt.jwk-set-uri`.
711+
* Updated `citations.md` with this entry.
712+
713+
---
714+
715+
### **Verification**
716+
717+
* Local manual authentication test via curl using Supabase-issued token.
718+
* Confirmed access to `POST /auth/signup` and `POST /auth/login` without JWT.
719+
* Confirmed `GET /auth/me` returns 200 with valid JWT and 401 without.
720+
* Re-ran Checkstyle and confirmed zero violations.
721+
722+
---
723+
724+
### **Attribution Statement**
725+
726+
> Portions of this commit or configuration were generated with assistance from OpenAI ChatGPT (GPT-5) on October 21, 2025. All AI-generated content was reviewed, verified, and finalized by the development team.
727+
728+
---

pom.xml

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,32 @@
2020

2121
<properties>
2222
<java.version>17</java.version>
23-
<!-- makes the built jar name nice -->
2423
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
2524
</properties>
2625

26+
<dependencyManagement>
27+
<dependencies>
28+
<!-- Keep Netty versions consistent -->
29+
<dependency>
30+
<groupId>io.netty</groupId>
31+
<artifactId>netty-bom</artifactId>
32+
<version>4.1.119.Final</version>
33+
<type>pom</type>
34+
<scope>import</scope>
35+
</dependency>
36+
</dependencies>
37+
</dependencyManagement>
38+
2739
<dependencies>
40+
<!-- macOS native DNS resolver -->
41+
<dependency>
42+
<groupId>io.netty</groupId>
43+
<artifactId>netty-resolver-dns-native-macos</artifactId>
44+
<version>4.1.119.Final</version>
45+
<classifier>${os.detected.name}-${os.detected.arch}</classifier>
46+
<scope>runtime</scope>
47+
</dependency>
48+
2849
<!-- Spring Security core -->
2950
<dependency>
3051
<groupId>org.springframework.boot</groupId>
@@ -103,9 +124,27 @@
103124
<version>11.14.0</version>
104125
</dependency>
105126

127+
<dependency>
128+
<groupId>org.springframework.boot</groupId>
129+
<artifactId>spring-boot-starter-webflux</artifactId>
130+
</dependency>
131+
132+
<dependency>
133+
<groupId>com.squareup.okhttp3</groupId>
134+
<artifactId>mockwebserver</artifactId>
135+
<version>4.12.0</version>
136+
<scope>test</scope>
137+
</dependency>
106138
</dependencies>
107139

108140
<build>
141+
<extensions>
142+
<extension>
143+
<groupId>kr.motd.maven</groupId>
144+
<artifactId>os-maven-plugin</artifactId>
145+
<version>1.7.1</version>
146+
</extension>
147+
</extensions>
109148
<finalName>${project.artifactId}-${project.version}</finalName>
110149
<plugins>
111150
<plugin>
@@ -186,6 +225,13 @@
186225
</execution>
187226
</executions>
188227
</plugin>
228+
<plugin>
229+
<groupId>org.springframework.boot</groupId>
230+
<artifactId>spring-boot-maven-plugin</artifactId>
231+
<configuration>
232+
<jvmArguments>--enable-native-access=ALL-UNNAMED</jvmArguments>
233+
</configuration>
234+
</plugin>
189235
</plugins>
190236
</build>
191237
</project>
Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1-
// src/main/java/dev/coms4156/project/metadetect/config/SecurityConfig.java
2-
31
package dev.coms4156.project.metadetect.config;
42

5-
import java.util.Collection;
6-
import java.util.Collections;
3+
import java.nio.charset.StandardCharsets;
4+
import javax.crypto.spec.SecretKeySpec;
5+
import org.springframework.beans.factory.annotation.Value;
76
import org.springframework.context.annotation.Bean;
87
import org.springframework.context.annotation.Configuration;
98
import org.springframework.security.config.Customizer;
109
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
11-
import org.springframework.security.core.GrantedAuthority;
10+
import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator;
11+
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
12+
import org.springframework.security.oauth2.jose.jws.MacAlgorithm;
1213
import org.springframework.security.oauth2.jwt.Jwt;
13-
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
14+
import org.springframework.security.oauth2.jwt.JwtDecoder;
15+
import org.springframework.security.oauth2.jwt.JwtException;
16+
import org.springframework.security.oauth2.jwt.JwtValidators;
17+
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
1418
import org.springframework.security.web.SecurityFilterChain;
1519

1620
/**
@@ -24,26 +28,32 @@ public class SecurityConfig {
2428
@Bean
2529
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
2630
http
27-
.csrf(csrf -> csrf.disable())
28-
.authorizeHttpRequests(auth -> auth
29-
.requestMatchers("/health", "/actuator/**").permitAll()
31+
.csrf(csrf -> csrf.disable())
32+
.authorizeHttpRequests(auth -> auth
33+
.requestMatchers("/health", "/actuator/**", "/auth/signup", "/auth/login", "/auth/refresh")
34+
.permitAll()
3035
.anyRequest().authenticated()
3136
)
32-
.oauth2ResourceServer(oauth2 -> oauth2
33-
.jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthenticationConverter()))
34-
);
37+
.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()));
3538
return http.build();
3639
}
3740

3841
@Bean
39-
JwtAuthenticationConverter jwtAuthenticationConverter() {
40-
// Keep authorities empty for now; we only need claims (sub, email).
41-
JwtAuthenticationConverter conv = new JwtAuthenticationConverter();
42-
conv.setJwtGrantedAuthoritiesConverter(SecurityConfig::emptyAuthorities);
43-
return conv;
44-
}
42+
JwtDecoder jwtDecoder(
43+
@Value("${metadetect.supabase.jwtSecret}") String jwtSecret,
44+
@Value("${metadetect.supabase.url}") String issuer
45+
) {
46+
var key = new SecretKeySpec(jwtSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
47+
var decoder = NimbusJwtDecoder.withSecretKey(key)
48+
.macAlgorithm(MacAlgorithm.HS256)
49+
.build();
50+
51+
// Validate issuer + standard claims; audience in Supabase is "authenticated"
52+
OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(
53+
issuer + "/auth/v1");
54+
OAuth2TokenValidator<Jwt> validator = new DelegatingOAuth2TokenValidator<>(withIssuer);
55+
decoder.setJwtValidator(validator);
4556

46-
private static Collection<GrantedAuthority> emptyAuthorities(Jwt jwt) {
47-
return Collections.emptyList();
57+
return decoder;
4858
}
4959
}

0 commit comments

Comments
 (0)