From 3f8c31353d5ddec282966a5d14c0a520ae32fe71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Theodor=20Angerg=C3=A5rd?= Date: Fri, 6 Sep 2024 17:10:01 +0200 Subject: [PATCH] Reset client secret --- .../adapter/primary/web/ApiKeyController.java | 20 +++----- .../primary/web/ClientsController.java | 49 ++++++++++++++----- .../gamma/app/client/ClientFacade.java | 4 +- .../client-details/client-credentials.html | 2 +- .../templates/client-details/page.html | 8 ++- .../templates/pages/api-key-details.html | 13 +++-- 6 files changed, 61 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/it/chalmers/gamma/adapter/primary/web/ApiKeyController.java b/app/src/main/java/it/chalmers/gamma/adapter/primary/web/ApiKeyController.java index 0152b00f6..d07457114 100644 --- a/app/src/main/java/it/chalmers/gamma/adapter/primary/web/ApiKeyController.java +++ b/app/src/main/java/it/chalmers/gamma/adapter/primary/web/ApiKeyController.java @@ -49,13 +49,14 @@ public ModelAndView getApiKeys( return mv; } - private ModelAndView createGetApiKey(boolean htmxRequest, String apiKeyId, @Nullable String token) { + private ModelAndView createGetApiKey( + boolean htmxRequest, String apiKeyId, @Nullable String token) { if (!isValidUUID(apiKeyId)) { return createApiKeyNotFound(apiKeyId, htmxRequest); } Optional maybeApiKey = - this.apiKeyFacade.getById(UUID.fromString(apiKeyId)); + this.apiKeyFacade.getById(UUID.fromString(apiKeyId)); if (maybeApiKey.isEmpty()) { return createApiKeyNotFound(apiKeyId, htmxRequest); @@ -198,8 +199,6 @@ public ModelAndView createApiKey( @DeleteMapping("/api-keys/{id}") public ModelAndView deleteApiKey( @RequestHeader(value = "HX-Request", required = false) boolean htmxRequest, - @RequestHeader(value = "return-empty-on-delete", required = false) - boolean returnEmptyOnDelete, HttpServletResponse response, @PathVariable("id") UUID id) { try { @@ -208,12 +207,7 @@ public ModelAndView deleteApiKey( throw new RuntimeException(e); } - if (returnEmptyOnDelete) { - response.addHeader("HX-Reswap", "delete"); - response.addHeader("HX-Retarget", "closest article"); - } else { - response.addHeader("HX-Redirect", "/api-keys"); - } + response.addHeader("HX-Redirect", "/api-keys"); return new ModelAndView("common/empty"); } @@ -292,12 +286,10 @@ public ModelAndView updateSettings( @PostMapping("/api-keys/{apiKeyId}/reset") public ModelAndView resetApiKeyToken( - @RequestHeader(value = "HX-Request", required = false) boolean htmxRequest, - @PathVariable("apiKeyId") UUID apiKeyId - ) { + @RequestHeader(value = "HX-Request", required = false) boolean htmxRequest, + @PathVariable("apiKeyId") UUID apiKeyId) { String newToken = this.apiKeyFacade.resetApiKey(apiKeyId); return createGetApiKey(htmxRequest, apiKeyId.toString(), newToken); } - } diff --git a/app/src/main/java/it/chalmers/gamma/adapter/primary/web/ClientsController.java b/app/src/main/java/it/chalmers/gamma/adapter/primary/web/ClientsController.java index f0908b3f9..43f357ed2 100644 --- a/app/src/main/java/it/chalmers/gamma/adapter/primary/web/ClientsController.java +++ b/app/src/main/java/it/chalmers/gamma/adapter/primary/web/ClientsController.java @@ -10,10 +10,12 @@ import it.chalmers.gamma.app.client.domain.authority.AuthorityName.AuthorityNameValidator; import it.chalmers.gamma.app.client.domain.authority.ClientAuthorityRepository; import it.chalmers.gamma.app.common.PrettyName.PrettyNameValidator; +import it.chalmers.gamma.app.common.TextValue; import it.chalmers.gamma.app.supergroup.SuperGroupFacade; import it.chalmers.gamma.app.user.UserFacade; import it.chalmers.gamma.security.authentication.AuthenticationExtractor; import it.chalmers.gamma.security.authentication.UserAuthentication; +import jakarta.annotation.Nullable; import jakarta.servlet.http.HttpServletResponse; import java.util.*; import java.util.stream.Collectors; @@ -65,10 +67,11 @@ public ModelAndView getClients( return mv; } - @GetMapping("/clients/{id}") - public ModelAndView getClient( - @RequestHeader(value = "HX-Request", required = false) boolean htmxRequest, - @PathVariable("id") String clientUid) { + private ModelAndView createGetClient( + boolean htmxRequest, + String clientUid, + @Nullable String clientSecret, + @Nullable String apiKeyToken) { if (!isValidUUID(clientUid)) { return createClientNotFound(clientUid, htmxRequest); } @@ -112,10 +115,13 @@ public ModelAndView getClient( } } + mv.addObject("clientSecret", clientSecret); + mv.addObject("apiKeyToken", apiKeyToken); + return mv; } - public ModelAndView createClientNotFound(String clientUid, boolean htmxRequest) { + private ModelAndView createClientNotFound(String clientUid, boolean htmxRequest) { ModelAndView mv = new ModelAndView(); if (htmxRequest) { mv.setViewName("client-details/not-found"); @@ -129,6 +135,13 @@ public ModelAndView createClientNotFound(String clientUid, boolean htmxRequest) return mv; } + @GetMapping("/clients/{id}") + public ModelAndView getClient( + @RequestHeader(value = "HX-Request", required = false) boolean htmxRequest, + @PathVariable("id") String clientUid) { + return createGetClient(htmxRequest, clientUid, null, null); + } + public static final class CreateClient { @ValidatedWith(ClientRedirectUrlValidator.class) @@ -137,8 +150,12 @@ public static final class CreateClient { @ValidatedWith(PrettyNameValidator.class) private String prettyName; + @ValidatedWith(TextValue.TextValueValidator.class) private String svDescription; + + @ValidatedWith(TextValue.TextValueValidator.class) private String enDescription; + private boolean generateApiKey; private boolean emailScope; @@ -304,16 +321,13 @@ public ModelAndView getCreateClient( mv.setViewName("client-details/page"); - mv.addObject("clientUid", result.client().clientUid()); - mv.addObject("client", result.client()); - mv.addObject("clientAuthorities", new ArrayList<>()); - mv.addObject("userApprovals", new ArrayList<>()); - mv.addObject("clientSecret", result.clientSecret()); - mv.addObject("apiKeyToken", result.apiKeyToken()); - response.addHeader("HX-Push-Url", "/clients/" + result.client().clientUid()); - return mv; + return createGetClient( + htmxRequest, + result.client().clientUid().toString(), + result.clientSecret(), + result.apiKeyToken()); } @GetMapping("/clients/{id}/authorities") @@ -512,4 +526,13 @@ public ModelAndView deleteClientAuthority( return new ModelAndView("client-details/deleted-client-authority"); } + + @PostMapping("/clients/{uid}/reset") + public ModelAndView resetClientSecret( + @RequestHeader(value = "HX-Request", required = true) boolean htmxRequest, + @PathVariable("uid") UUID clientUid) { + String clientSecret = this.clientFacade.resetClientSecret(clientUid); + + return createGetClient(htmxRequest, clientUid.toString(), clientSecret, null); + } } diff --git a/app/src/main/java/it/chalmers/gamma/app/client/ClientFacade.java b/app/src/main/java/it/chalmers/gamma/app/client/ClientFacade.java index 0887612ad..e6b69a990 100644 --- a/app/src/main/java/it/chalmers/gamma/app/client/ClientFacade.java +++ b/app/src/main/java/it/chalmers/gamma/app/client/ClientFacade.java @@ -177,12 +177,12 @@ public List getAllMyClients() { throw new IllegalStateException(); } - public String resetClientSecret(UUID clientUid) throws ClientNotFoundException { + public String resetClientSecret(UUID clientUid) { ClientUid uid = new ClientUid(clientUid); this.accessGuard.requireEither(isAdmin(), ownerOfClient(uid)); - Client client = this.clientRepository.get(uid).orElseThrow(ClientNotFoundException::new); + Client client = this.clientRepository.get(uid).orElseThrow(); ClientSecret.GeneratedClientSecret generated = ClientSecret.generate(passwordEncoder); Client newClient = client.withClientSecret(generated.clientSecret()); diff --git a/app/src/main/resources/templates/client-details/client-credentials.html b/app/src/main/resources/templates/client-details/client-credentials.html index 7d7cc16ec..d1a498c7a 100644 --- a/app/src/main/resources/templates/client-details/client-credentials.html +++ b/app/src/main/resources/templates/client-details/client-credentials.html @@ -4,7 +4,7 @@

These are the credentials for your client. They will not be shown again.

-
+
Client secret:
diff --git a/app/src/main/resources/templates/client-details/page.html b/app/src/main/resources/templates/client-details/page.html index 01d41d81f..65587d5e8 100644 --- a/app/src/main/resources/templates/client-details/page.html +++ b/app/src/main/resources/templates/client-details/page.html @@ -40,6 +40,10 @@