From 5ab3d960a843a1a1bb075ae8b2d6cfa5753e76b4 Mon Sep 17 00:00:00 2001
From: Hugo Renard <hugo.renard@protonmail.com>
Date: Thu, 19 May 2022 14:13:14 +0200
Subject: [PATCH] tolerate provider failure

---
 .../sh/libre/scim/core/ScimDispatcher.java    | 30 +++++++++++--------
 .../storage/ScimStorageProviderFactory.java   | 12 +++-----
 2 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/src/main/java/sh/libre/scim/core/ScimDispatcher.java b/src/main/java/sh/libre/scim/core/ScimDispatcher.java
index c8beede..ee4d1f2 100644
--- a/src/main/java/sh/libre/scim/core/ScimDispatcher.java
+++ b/src/main/java/sh/libre/scim/core/ScimDispatcher.java
@@ -2,13 +2,14 @@ package sh.libre.scim.core;
 
 import java.util.function.Consumer;
 import org.jboss.logging.Logger;
+import org.keycloak.component.ComponentModel;
 import org.keycloak.models.KeycloakSession;
 
 import sh.libre.scim.storage.ScimStorageProviderFactory;
 
 public class ScimDispatcher {
-    public static final String SCOPE_USER = "user"; 
-    public static final String SCOPE_GROUP = "group"; 
+    public static final String SCOPE_USER = "user";
+    public static final String SCOPE_GROUP = "group";
 
     final private KeycloakSession session;
     final private Logger LOGGER = Logger.getLogger(ScimDispatcher.class);
@@ -20,16 +21,21 @@ public class ScimDispatcher {
     public void run(String scope, Consumer<ScimClient> f) {
         session.getContext().getRealm().getComponentsStream()
                 .filter((m) -> {
-                    return ScimStorageProviderFactory.ID.equals(m.getProviderId()) && m.get("enabled").equals("true") &&  m.get("propagation-"+scope).equals("true");
+                    return ScimStorageProviderFactory.ID.equals(m.getProviderId()) && m.get("enabled").equals("true")
+                            && m.get("propagation-" + scope).equals("true");
                 })
-                .forEach(m -> {
-                    LOGGER.infof("%s %s %s %s", m.getId(), m.getName(), m.getProviderId(), m.getProviderType());
-                    var client = new ScimClient(m, session);
-                    try {
-                        f.accept(client);
-                    } finally {
-                        client.close();
-                    }
-                });
+                .forEach(m -> runOne(m, f));
+    }
+
+    public void runOne(ComponentModel m, Consumer<ScimClient> f) {
+        LOGGER.infof("%s %s %s %s", m.getId(), m.getName(), m.getProviderId(), m.getProviderType());
+        var client = new ScimClient(m, session);
+        try {
+            f.accept(client);
+        } catch (Exception e) {
+            LOGGER.error(e);
+        } finally {
+            client.close();
+        }
     }
 }
diff --git a/src/main/java/sh/libre/scim/storage/ScimStorageProviderFactory.java b/src/main/java/sh/libre/scim/storage/ScimStorageProviderFactory.java
index 505d884..a3cf574 100644
--- a/src/main/java/sh/libre/scim/storage/ScimStorageProviderFactory.java
+++ b/src/main/java/sh/libre/scim/storage/ScimStorageProviderFactory.java
@@ -12,7 +12,6 @@ import org.keycloak.component.ComponentModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
 import org.keycloak.models.KeycloakSessionTask;
-import org.keycloak.models.RealmModel;
 import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.provider.ProviderConfigProperty;
 import org.keycloak.provider.ProviderConfigurationBuilder;
@@ -22,7 +21,7 @@ import org.keycloak.storage.user.ImportSynchronization;
 import org.keycloak.storage.user.SynchronizationResult;
 
 import sh.libre.scim.core.GroupAdapter;
-import sh.libre.scim.core.ScimClient;
+import sh.libre.scim.core.ScimDispatcher;
 import sh.libre.scim.core.UserAdapter;
 
 public class ScimStorageProviderFactory
@@ -125,16 +124,13 @@ public class ScimStorageProviderFactory
 
             @Override
             public void run(KeycloakSession session) {
-                RealmModel realm = session.realms().getRealm(realmId);
-                session.getContext().setRealm(realm);
-                var client = new ScimClient(model, session);
+                var dispatcher = new ScimDispatcher(session);
                 if (model.get("propagation-user").equals("true")) {
-                    client.sync(UserAdapter.class, result);
+                    dispatcher.runOne(model, (client) -> client.sync(UserAdapter.class, result));
                 }
                 if (model.get("propagation-group").equals("true")) {
-                    client.sync(GroupAdapter.class, result);
+                    dispatcher.runOne(model, (client) -> client.sync(GroupAdapter.class, result));
                 }
-                client.close();
             }
 
         });
-- 
GitLab