From 695714f4eb771ac2db42f2b8df96e03ca90f518f Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Thu, 3 Jul 2025 19:13:38 +0200 Subject: [PATCH] implemented unlinking of oidc connection --- .../src/routes/user/ConnectedServices.svelte | 22 ++++++-- .../srsoftware/umbrella/user/UserModule.java | 51 ++++++++++++++++++- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/frontend/src/routes/user/ConnectedServices.svelte b/frontend/src/routes/user/ConnectedServices.svelte index 82a5786..b585d68 100644 --- a/frontend/src/routes/user/ConnectedServices.svelte +++ b/frontend/src/routes/user/ConnectedServices.svelte @@ -5,7 +5,7 @@ let connections = $state([]); - onMount(async () => { + async function loadConnections(){ let url = `${location.protocol}//${location.host.replace('5173','8080')}/api/user/oidc/connected`; let resp = await fetch(url,{credentials:'include'}); @@ -16,7 +16,23 @@ console.log(entry); } } - }); + } + + onMount(loadConnections); + + async function unlink(connection){ + const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/user/oidc/connected`; + const resp = fetch(url,{ + method: 'DELETE', + credentials: 'include', + body: JSON.stringify(connection) + }); + if (resp.ok){ + alert('succeeded'); + } else { + alert('failed'); + } + } {#if connections.length>0} @@ -36,7 +52,7 @@ {connection.service_id} {connection.foreign_id} - + {/each} diff --git a/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java b/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java index 2922124..ad87a62 100644 --- a/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java +++ b/user/src/main/java/de/srsoftware/umbrella/user/UserModule.java @@ -20,6 +20,7 @@ import static java.net.HttpURLConnection.*; import static java.nio.charset.StandardCharsets.UTF_8; import static java.text.MessageFormat.format; import static java.time.temporal.ChronoUnit.DAYS; +import static javax.security.auth.callback.ConfirmationCallback.OK; import com.sun.net.httpserver.HttpExchange; import de.srsoftware.tools.Path; @@ -81,11 +82,59 @@ public class UserModule extends PathHandler { headers.add("Access-Control-Allow-Origin", url); headers.add("Access-Control-Allow-Headers", "Content-Type"); headers.add("Access-Control-Allow-Credentials", "true"); - headers.add("Access-Control-Allow-Methods","GET, POST, PATCH"); + headers.add("Access-Control-Allow-Methods","DELETE, GET, POST, PATCH"); } return ex; } + private boolean deleteOIDC(HttpExchange ex, UmbrellaUser user, Path path) throws IOException { + var head = path.pop(); + return switch (head){ + case CONNECTED -> deleteServiceConnection(ex,user); + case null, default -> super.doGet(path,ex); + }; + } + + private boolean deleteServiceConnection(HttpExchange ex, UmbrellaUser user) throws IOException { + if (user == null) return sendContent(ex,HTTP_SERVER_ERROR,"Expected user object to be of type DbUser"); + JSONObject json; + try { + json = json(ex); + } catch (Exception e){ + LOG.log(WARNING,"Request does not contain valid JSON",e); + return sendContent(ex,HTTP_FAILED_DEPENDENCY,"Request does not contain valid JSON"); + } + if (!(json.has(FOREIGN_ID) && json.get(FOREIGN_ID) instanceof String foreignId && !foreignId.isBlank())) return sendContent(ex,HTTP_UNPROCESSABLE,format(ERROR_MISSING_FIELD,FOREIGN_ID)); + if (!(json.has(SERVICE_ID) && json.get(SERVICE_ID) instanceof String serviceId && !serviceId.isBlank())) return sendContent(ex,HTTP_UNPROCESSABLE,format(ERROR_MISSING_FIELD,SERVICE_ID)); + + + try { + logins.unlink(ForeignLogin.of(serviceId,foreignId,user.id())); + return sendEmptyResponse(OK,ex); + } catch (UmbrellaException e) { + return send(ex,e); + } + + } + + @Override + public boolean doDelete(Path path, HttpExchange ex) throws IOException { + UmbrellaUser user = null; + var sessionToken = SessionToken.from(ex).map(Token::of); + if (sessionToken.isPresent()) try { + user = users.load(users.load(sessionToken.get())); + } catch (UmbrellaException e) { + LOG.log(WARNING,e); + } + addCors(ex); + var head = path.pop(); + switch (head) { + case OIDC: return deleteOIDC(ex,user,path); + + }; + return super.doDelete(path, ex); + } + @Override public boolean doGet(Path path, HttpExchange ex) throws IOException { UmbrellaUser user = null;