From 5d1b7804133151fdaca6b21d0f1313dcad9040a3 Mon Sep 17 00:00:00 2001
From: Hugo Renard <hugo.renard@protonmail.com>
Date: Wed, 16 Feb 2022 14:00:24 +0100
Subject: [PATCH] add bearer auth

---
 .../libre/scim/core/BearerAuthentication.java | 20 +++++++++++++++++++
 .../java/sh/libre/scim/core/ScimClient.java   | 19 +++++++++++++-----
 .../sh/libre/scim/core/ScimDispatcher.java    |  2 +-
 .../storage/ScimStorageProviderFactory.java   | 14 +++++++++++++
 4 files changed, 49 insertions(+), 6 deletions(-)
 create mode 100644 src/main/java/sh/libre/scim/core/BearerAuthentication.java

diff --git a/src/main/java/sh/libre/scim/core/BearerAuthentication.java b/src/main/java/sh/libre/scim/core/BearerAuthentication.java
new file mode 100644
index 0000000..2b4133d
--- /dev/null
+++ b/src/main/java/sh/libre/scim/core/BearerAuthentication.java
@@ -0,0 +1,20 @@
+package sh.libre.scim.core;
+
+import java.io.IOException;
+
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientRequestFilter;
+
+public class BearerAuthentication implements ClientRequestFilter {
+    private final String token;
+
+    BearerAuthentication(String token) {
+        this.token = token;
+    }
+
+    @Override
+    public void filter(ClientRequestContext requestContext) throws IOException {
+        requestContext.getHeaders().add("Authorization", "Bearer " + this.token);
+
+    }
+}
diff --git a/src/main/java/sh/libre/scim/core/ScimClient.java b/src/main/java/sh/libre/scim/core/ScimClient.java
index 6fa9563..da34206 100644
--- a/src/main/java/sh/libre/scim/core/ScimClient.java
+++ b/src/main/java/sh/libre/scim/core/ScimClient.java
@@ -19,6 +19,7 @@ import javax.ws.rs.client.Client;
 
 import org.jboss.logging.Logger;
 import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
+import org.keycloak.component.ComponentModel;
 import org.keycloak.connections.jpa.JpaConnectionProvider;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.UserModel;
@@ -33,13 +34,21 @@ public class ScimClient {
     final private String name;
     final private KeycloakSession session;
     final private String contentType;
+    final private String authMode;
+    final private String bearerToken;
 
-    public ScimClient(String name, String url, String contentType, KeycloakSession session) {
-        this.name = name;
-        this.contentType = contentType;
+    public ScimClient(ComponentModel model, KeycloakSession session) {
+        this.name = model.getName();
+        this.contentType = model.get("content-type");
+        this.authMode = model.get("auth-mode");
+        this.bearerToken = model.get("auth-bearer-token");
 
         this.session = session;
-        var target = client.target(url);
+        var target = client.target(model.get("endpoint"));
+        if (this.authMode.equals("BEARER")) {
+            target = target.register(new BearerAuthentication(this.bearerToken));
+        }
+
         scimService = new ScimService(target);
 
         RetryConfig retryConfig = RetryConfig.custom()
@@ -92,7 +101,7 @@ public class ScimClient {
                 }
             });
         } catch (NoResultException e) {
-            LOGGER.warnf("Failde to repalce user %s, scim mapping not found", kcUser.getId());
+            LOGGER.warnf("Failed to repalce user %s, scim mapping not found", kcUser.getId());
         } catch (Exception e) {
             LOGGER.error(e);
         }
diff --git a/src/main/java/sh/libre/scim/core/ScimDispatcher.java b/src/main/java/sh/libre/scim/core/ScimDispatcher.java
index ea6a763..db00e58 100644
--- a/src/main/java/sh/libre/scim/core/ScimDispatcher.java
+++ b/src/main/java/sh/libre/scim/core/ScimDispatcher.java
@@ -21,7 +21,7 @@ public class ScimDispatcher {
                 })
                 .forEach(m -> {
                     LOGGER.infof("%s %s %s %s", m.getId(), m.getName(), m.getProviderId(), m.getProviderType());
-                    var client = new ScimClient(m.getName(), m.get("endpoint"), m.get("content-type"), session);
+                    var client = new ScimClient(m, session);
                     try {
                         f.accept(client);
                     } finally {
diff --git a/src/main/java/sh/libre/scim/storage/ScimStorageProviderFactory.java b/src/main/java/sh/libre/scim/storage/ScimStorageProviderFactory.java
index 57cfc2d..1a0d953 100644
--- a/src/main/java/sh/libre/scim/storage/ScimStorageProviderFactory.java
+++ b/src/main/java/sh/libre/scim/storage/ScimStorageProviderFactory.java
@@ -32,6 +32,20 @@ public class ScimStorageProviderFactory implements UserStorageProviderFactory<Sc
                 .options(MediaType.APPLICATION_JSON.toString(), ScimService.MEDIA_TYPE_SCIM_TYPE.toString())
                 .defaultValue(ScimService.MEDIA_TYPE_SCIM_TYPE.toString())
                 .add()
+                .property()
+                .name("auth-mode")
+                .type(ProviderConfigProperty.LIST_TYPE)
+                .label("Auth mode")
+                .helpText("Select the authorization mode")
+                .options("NONE", "BEARER")
+                .defaultValue("NONE")
+                .add()
+                .property()
+                .name("auth-bearer-token")
+                .type(ProviderConfigProperty.PASSWORD)
+                .label("Bearer token")
+                .helpText("Add a bearer token in the authorization header")
+                .add()
                 .build();
     }
 
-- 
GitLab