Skip to content

Commit 26431b8

Browse files
authored
Merge pull request #7 from helioauth/feature/rpid-from-application
Read relying party config from application (re-trigger)
2 parents d09cc0a + 457066e commit 26431b8

25 files changed

Lines changed: 428 additions & 128 deletions

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
HELP.md
2+
TODO.md
23
target/
34
!.mvn/wrapper/maven-wrapper.jar
45
!**/src/main/**/target/
@@ -31,3 +32,4 @@ build/
3132

3233
### VS Code ###
3334
.vscode/
35+
.aider*
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
type: object
2-
description: Request to add a new client application. Contains the name of the application.
2+
description: Request to add a new client application
33
properties:
44
name:
55
type: string
66
description: Name of the new application.
7+
relyingPartyHostname:
8+
type: string
9+
description: Hostname of the application, e.g. example.com

docs/openapi/components/schemas/Application.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@ properties:
1616
type: string
1717
format: date-time
1818
description: Timestamp when the application was last updated.
19+
relyingPartyHostname:
20+
type: string
21+
description: Hostname of the relying party.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
type: object
2+
description: Represents a request to edit an application.
3+
properties:
4+
name:
5+
type: string
6+
description: Name of the application.
7+
relyingPartyHostname:
8+
type: string
9+
description: Hostname of the relying party.

docs/openapi/paths/admin_v1_apps_id.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ put:
4141
content:
4242
application/json:
4343
schema:
44-
type: string
44+
$ref: ../components/schemas/EditApplicationRequest.yaml
4545
required: true
4646
responses:
4747
'200':

src/main/java/com/helioauth/passkeys/api/auth/ApplicationApiKeyAuthenticationProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ public Authentication authenticate(Authentication authentication) throws Authent
4747
.orElseThrow(() -> new BadCredentialsException("Invalid api key"));
4848

4949
PreAuthenticatedAuthenticationToken authenticatedToken = new PreAuthenticatedAuthenticationToken(
50-
clientApp.getId(),
5150
clientApp,
51+
clientApp.getApiKey(),
5252
List.of(new SimpleGrantedAuthority("ROLE_APPLICATION"))
5353
);
5454
authenticatedToken.setDetails(clientApp);

src/main/java/com/helioauth/passkeys/api/auth/ApplicationIdAuthenticationProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ public Authentication authenticate(Authentication authentication) throws Authent
5050
.orElseThrow(() -> new BadCredentialsException("Invalid application ID"));
5151

5252
PreAuthenticatedAuthenticationToken authenticatedToken = new PreAuthenticatedAuthenticationToken(
53-
clientApp.getId(),
5453
clientApp,
54+
clientApp.getId(),
5555
List.of(new SimpleGrantedAuthority("ROLE_FRONTEND_APPLICATION"))
5656
);
5757
authenticatedToken.setDetails(clientApp);

src/main/java/com/helioauth/passkeys/api/config/WebSecurityConfig.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import jakarta.servlet.http.HttpServletResponse;
4040
import java.util.List;
4141

42+
4243
/**
4344
* @author Viktor Stanchev
4445
*/

src/main/java/com/helioauth/passkeys/api/controller/ClientApplicationController.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020
import com.helioauth.passkeys.api.generated.models.AddApplicationRequest;
2121
import com.helioauth.passkeys.api.generated.models.Application;
2222
import com.helioauth.passkeys.api.generated.models.ApplicationApiKey;
23+
import com.helioauth.passkeys.api.generated.models.EditApplicationRequest;
2324
import com.helioauth.passkeys.api.service.ClientApplicationService;
25+
26+
import jakarta.validation.Valid;
2427
import lombok.RequiredArgsConstructor;
2528
import lombok.val;
2629
import org.springframework.http.ResponseEntity;
@@ -39,9 +42,9 @@
3942
@RequiredArgsConstructor
4043
public class ClientApplicationController implements ApplicationsApi {
4144

42-
private final ClientApplicationService clientApplicationService;
45+
private final ClientApplicationService clientApplicationService;
4346

44-
public ResponseEntity<List<Application>> listAll() {
47+
public ResponseEntity<List<Application>> listAll() {
4548
return ResponseEntity.ok(clientApplicationService.listAll());
4649
}
4750

@@ -58,14 +61,14 @@ public ResponseEntity<ApplicationApiKey> getApiKey(@PathVariable UUID id) {
5861
}
5962

6063
public ResponseEntity<Application> add(@RequestBody AddApplicationRequest request) {
61-
Application created = clientApplicationService.add(request.getName());
64+
Application created = clientApplicationService.add(request);
6265

6366
return ResponseEntity.created(URI.create("/admin/v1/apps/" + created.getId()))
6467
.body(created);
6568
}
6669

67-
public ResponseEntity<Application> edit(@PathVariable UUID id, @RequestBody String name) {
68-
val updated = clientApplicationService.edit(id, name);
70+
public ResponseEntity<Application> edit(@PathVariable UUID id, @RequestBody @Valid EditApplicationRequest request) {
71+
val updated = clientApplicationService.edit(id, request);
6972

7073
return updated
7174
.map(ResponseEntity::ok)

src/main/java/com/helioauth/passkeys/api/controller/CredentialsController.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.helioauth.passkeys.api.controller;
1818

1919
import com.fasterxml.jackson.core.JsonProcessingException;
20+
import com.helioauth.passkeys.api.domain.ClientApplication;
2021
import com.helioauth.passkeys.api.generated.api.SignInApi;
2122
import com.helioauth.passkeys.api.generated.api.SignUpApi;
2223
import com.helioauth.passkeys.api.generated.models.SignInFinishRequest;
@@ -29,11 +30,14 @@
2930
import com.helioauth.passkeys.api.generated.models.SignUpStartResponse;
3031
import com.helioauth.passkeys.api.service.UserSignInService;
3132
import com.helioauth.passkeys.api.service.UserSignupService;
33+
import com.helioauth.passkeys.api.service.dto.UserSignupStartRequest;
3234
import com.helioauth.passkeys.api.service.exception.SignInFailedException;
3335
import lombok.RequiredArgsConstructor;
3436
import lombok.extern.slf4j.Slf4j;
3537
import org.springframework.http.HttpStatus;
3638
import org.springframework.http.ResponseEntity;
39+
import org.springframework.security.core.Authentication;
40+
import org.springframework.security.core.context.SecurityContextHolder;
3741
import org.springframework.web.bind.annotation.CrossOrigin;
3842
import org.springframework.web.bind.annotation.RequestBody;
3943
import org.springframework.web.bind.annotation.RestController;
@@ -46,16 +50,35 @@
4650
*/
4751
@Slf4j
4852
@RestController
49-
@CrossOrigin(origins = "*")
5053
@RequiredArgsConstructor
54+
@CrossOrigin(origins = "*")
5155
public class CredentialsController implements SignUpApi, SignInApi {
5256

5357
private final UserSignInService userSignInService;
5458
private final UserSignupService userSignupService;
5559

5660
public ResponseEntity<SignUpStartResponse> postSignupStart(@RequestBody @Valid SignUpStartRequest request) {
61+
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
62+
if (authentication == null || !(authentication.getPrincipal() instanceof ClientApplication clientApp)) {
63+
log.error("Signup start request received without valid ClientApplication authentication.");
64+
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Client application not authenticated");
65+
}
66+
67+
String rpId = clientApp.getRelyingPartyHostname();
68+
String rpName = clientApp.getRelyingPartyName();
69+
70+
if (rpId == null || rpId.isBlank()) {
71+
log.error("Authenticated ClientApplication (ID: {}) is missing a valid relyingPartyHostname.", clientApp.getId());
72+
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Client application configuration error: Missing RP hostname");
73+
}
74+
5775
return ResponseEntity.ok(
58-
userSignupService.startRegistration(request.getName())
76+
userSignupService.startRegistration(UserSignupStartRequest.builder()
77+
.name(request.getName())
78+
.rpId(rpId)
79+
.rpName(rpName)
80+
.build()
81+
)
5982
);
6083
}
6184

@@ -88,4 +111,4 @@ public ResponseEntity<SignInFinishResponse> finishSignInCredential(@RequestBody
88111
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Sign in failed");
89112
}
90113
}
91-
}
114+
}

0 commit comments

Comments
 (0)