You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by dj...@apache.org on 2016/10/05 07:41:22 UTC

svn commit: r1763355 - in /jackrabbit/oak/trunk/oak-auth-external/src: main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/ main/java/org/apache/jackra...

Author: dj
Date: Wed Oct  5 07:41:22 2016
New Revision: 1763355

URL: http://svn.apache.org/viewvc?rev=1763355&view=rev
Log:
OAK-4825 : Support disabling of users instead of removal in DefaultSyncHandler

Modified:
    jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/SyncResult.java
    jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/DefaultSyncConfig.java
    jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/DefaultSyncContext.java
    jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/package-info.java
    jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncConfigImpl.java
    jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/Delegatee.java
    jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/package-info.java
    jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/AbstractExternalAuthTest.java
    jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java
    jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/DefaultSyncContextTest.java

Modified: jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/SyncResult.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/SyncResult.java?rev=1763355&r1=1763354&r2=1763355&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/SyncResult.java (original)
+++ jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/SyncResult.java Wed Oct  5 07:41:22 2016
@@ -64,6 +64,16 @@ public interface SyncResult {
         DELETE,
 
         /**
+         * authorizable enabled
+         */
+        ENABLE,
+
+        /**
+         * authorizable disabled
+         */
+        DISABLE,
+
+        /**
          * nothing changed. no such authorizable found.
          */
         NO_SUCH_AUTHORIZABLE,

Modified: jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/DefaultSyncConfig.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/DefaultSyncConfig.java?rev=1763355&r1=1763354&r2=1763355&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/DefaultSyncConfig.java (original)
+++ jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/DefaultSyncConfig.java Wed Oct  5 07:41:22 2016
@@ -229,6 +229,8 @@ public class DefaultSyncConfig {
 
         private boolean dynamicMembership;
 
+        private boolean disableMissing;
+
         /**
          * Returns the duration in milliseconds until the group membership of a user is expired. If the
          * membership information is expired it is re-synced according to the maximum nesting depth.
@@ -310,6 +312,22 @@ public class DefaultSyncConfig {
             return this;
         }
 
+        /**
+         * Controls the behavior for users that no longer exist on the external provider. The default is to delete the repository users
+         * if they no longer exist on the external provider. If set to true, they will be disabled instead, and re-enabled once they appear
+         * again.
+         */
+        public boolean getDisableMissing() {
+            return disableMissing;
+        }
+
+        /**
+         * @see #getDisableMissing()
+         */
+        public User setDisableMissing(boolean disableMissing) {
+            this.disableMissing = disableMissing;
+            return this;
+        }
     }
 
     /**

Modified: jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/DefaultSyncContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/DefaultSyncContext.java?rev=1763355&r1=1763354&r2=1763355&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/DefaultSyncContext.java (original)
+++ jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/DefaultSyncContext.java Wed Oct  5 07:41:22 2016
@@ -326,10 +326,16 @@ public class DefaultSyncContext implemen
             log.info("won't remove local group with members: {}", id);
             status = SyncResult.Status.NOP;
         } else if (!keepMissing) {
-            authorizable.remove();
-            log.debug("removing authorizable '{}' that no longer exists on IDP {}", id, idp.getName());
+            if (config.user().getDisableMissing() && !authorizable.isGroup()) {
+                ((User) authorizable).disable("No longer exists on external identity provider '" + idp.getName() + "'");
+                log.debug("disabling user '{}' that no longer exists on IDP {}", id, idp.getName());
+                status = SyncResult.Status.DISABLE;
+            } else {
+                authorizable.remove();
+                log.debug("removing authorizable '{}' that no longer exists on IDP {}", id, idp.getName());
+                status = SyncResult.Status.DELETE;
+            }
             timer.mark("remove");
-            status = SyncResult.Status.DELETE;
         } else {
             status = SyncResult.Status.MISSING;
             log.info("external identity missing for {}, but purge == false.", id);
@@ -432,9 +438,14 @@ public class DefaultSyncContext implemen
                 // synchronize external memberships
                 syncMembership(external, user, config.user().getMembershipNestingDepth());
             }
+            if (this.config.user().getDisableMissing() && user.isDisabled()) {
+                status = SyncResult.Status.ENABLE;
+                user.disable(null);
+            } else {
+                status = SyncResult.Status.UPDATE;
+            }
             // finally "touch" the sync property
             user.setProperty(REP_LAST_SYNCED, nowValue);
-            status = SyncResult.Status.UPDATE;
         }
         return new DefaultSyncResultImpl(createSyncedIdentity(user), status);
     }

Modified: jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/package-info.java?rev=1763355&r1=1763354&r2=1763355&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/package-info.java Wed Oct  5 07:41:22 2016
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("1.2.0")
+@Version("1.3.0")
 @Export
 package org.apache.jackrabbit.oak.spi.security.authentication.external.basic;
 

Modified: jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncConfigImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncConfigImpl.java?rev=1763355&r1=1763354&r2=1763355&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncConfigImpl.java (original)
+++ jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncConfigImpl.java Wed Oct  5 07:41:22 2016
@@ -178,6 +178,22 @@ public class DefaultSyncConfigImpl exten
     public static final String PARAM_USER_DYNAMIC_MEMBERSHIP = "user.dynamicMembership";
 
     /**
+     * @see User#getDisableMissing()
+     */
+    public static final boolean PARAM_DISABLE_MISSING_USERS_DEFAULT = false;
+
+    /**
+     * @see User#getDisableMissing()
+     */
+    @Property(
+        label = "Disable missing users",
+        description = "If true, users that no longer exist on the external provider will be locally disabled, " +
+            "and re-enabled if they become valid again. If false (default) they will be removed.",
+        boolValue = false
+    )
+    public static final String PARAM_DISABLE_MISSING_USERS = "user.disableMissing";
+
+    /**
      * @see DefaultSyncConfig.Group#getExpirationTime()
      */
     public static final String PARAM_GROUP_EXPIRATION_TIME_DEFAULT = "1d";
@@ -268,6 +284,7 @@ public class DefaultSyncConfigImpl exten
                 .setName(params.getConfigValue(PARAM_NAME, PARAM_NAME_DEFAULT));
 
         cfg.user()
+                .setDisableMissing(params.getConfigValue(PARAM_DISABLE_MISSING_USERS, PARAM_DISABLE_MISSING_USERS_DEFAULT))
                 .setMembershipExpirationTime(getMilliSeconds(params, PARAM_USER_MEMBERSHIP_EXPIRATION_TIME, PARAM_USER_MEMBERSHIP_EXPIRATION_TIME_DEFAULT, ONE_HOUR))
                 .setMembershipNestingDepth(params.getConfigValue(PARAM_USER_MEMBERSHIP_NESTING_DEPTH, PARAM_USER_MEMBERSHIP_NESTING_DEPTH_DEFAULT))
                 .setDynamicMembership(params.getConfigValue(PARAM_USER_DYNAMIC_MEMBERSHIP, PARAM_USER_DYNAMIC_MEMBERSHIP_DEFAULT))

Modified: jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/Delegatee.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/Delegatee.java?rev=1763355&r1=1763354&r2=1763355&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/Delegatee.java (original)
+++ jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/Delegatee.java Wed Oct  5 07:41:22 2016
@@ -391,6 +391,8 @@ final class Delegatee {
                     case ADD:
                     case DELETE:
                     case UPDATE:
+                    case ENABLE:
+                    case DISABLE:
                         append(list, result.getIdentity(), e);
                         break;
                     default:
@@ -415,6 +417,12 @@ final class Delegatee {
             case DELETE:
                 op = "del";
                 break;
+            case ENABLE:
+                op = "ena";
+                break;
+            case DISABLE:
+                op = "dis";
+                break;
             case NO_SUCH_AUTHORIZABLE:
                 op = "nsa";
                 break;

Modified: jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/package-info.java?rev=1763355&r1=1763354&r2=1763355&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/package-info.java Wed Oct  5 07:41:22 2016
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("2.0.0")
+@Version("2.1.0")
 @Export
 package org.apache.jackrabbit.oak.spi.security.authentication.external;
 

Modified: jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/AbstractExternalAuthTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/AbstractExternalAuthTest.java?rev=1763355&r1=1763354&r2=1763355&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/AbstractExternalAuthTest.java (original)
+++ jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/AbstractExternalAuthTest.java Wed Oct  5 07:41:22 2016
@@ -144,6 +144,10 @@ public abstract class AbstractExternalAu
         // nothing to do
     }
 
+    protected void addIDPUser(String id) {
+        ((TestIdentityProvider) idp).addUser(new TestIdentityProvider.TestUser(id, idp.getName()));
+    }
+
     protected DefaultSyncConfig createSyncConfig() {
         DefaultSyncConfig syncConfig = new DefaultSyncConfig();
         Map<String, String> mapping = new HashMap<String, String>();

Modified: jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java?rev=1763355&r1=1763354&r2=1763355&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java (original)
+++ jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/TestIdentityProvider.java Wed Oct  5 07:41:22 2016
@@ -81,12 +81,12 @@ public class TestIdentityProvider implem
                 .withGroups("_gr_u_", "g%r%"));
     }
 
-    private void addUser(TestIdentity user) {
-        externalUsers.put(user.getId().toLowerCase(), (TestUser) user);
+    public void addUser(TestIdentity user) {
+        externalUsers.put(user.getId().toLowerCase(), (ExternalUser) user);
     }
 
     private void addGroup(TestIdentity group) {
-        externalGroups.put(group.getId().toLowerCase(), (TestGroup) group);
+        externalGroups.put(group.getId().toLowerCase(), (ExternalGroup) group);
     }
 
     @Nonnull

Modified: jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/DefaultSyncContextTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/DefaultSyncContextTest.java?rev=1763355&r1=1763354&r2=1763355&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/DefaultSyncContextTest.java (original)
+++ jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/basic/DefaultSyncContextTest.java Wed Oct  5 07:41:22 2016
@@ -386,6 +386,71 @@ public class DefaultSyncContextTest exte
     }
 
     @Test
+    public void testSyncDisabledUserById() throws Exception {
+        // configure to disable missing users
+        syncConfig.user().setDisableMissing(true);
+
+        // mark a regular repo user as external user from the test IDP
+        User u = userManager.createUser("test" + UUID.randomUUID(), null);
+        String userId = u.getID();
+        setExternalID(u, idp.getName());
+
+        // test sync with 'keepmissing' = true
+        syncCtx.setKeepMissing(true);
+        SyncResult result = syncCtx.sync(userId);
+        assertEquals(SyncResult.Status.MISSING, result.getStatus());
+        assertNotNull(userManager.getAuthorizable(userId));
+
+        // test sync with 'keepmissing' = false
+        syncCtx.setKeepMissing(false);
+        result = syncCtx.sync(userId);
+        assertEquals(SyncResult.Status.DISABLE, result.getStatus());
+
+        Authorizable authorizable = userManager.getAuthorizable(userId);
+        assertNotNull(authorizable);
+        assertTrue(((User)authorizable).isDisabled());
+
+        // add external user back
+        addIDPUser(userId);
+
+        result = syncCtx.sync(userId);
+        assertEquals(SyncResult.Status.ENABLE, result.getStatus());
+        assertNotNull(userManager.getAuthorizable(userId));
+        assertFalse(((User)authorizable).isDisabled());
+    }
+
+    @Test
+    public void testSyncDoesNotEnableUsers() throws Exception {
+        // configure to remove missing users, check that sync does not mess with disabled status
+        syncConfig.user().setDisableMissing(false);
+        // test sync with 'keepmissing' = false
+        syncCtx.setKeepMissing(false);
+
+        ExternalUser user = idp.listUsers().next();
+        assertNotNull(user);
+
+        SyncResult result = syncCtx.sync(user);
+        assertEquals(SyncResult.Status.ADD, result.getStatus());
+
+        Authorizable authorizable = userManager.getAuthorizable(user.getId());
+        assertTrue(authorizable instanceof User);
+        User u = (User) authorizable;
+
+        // disable user
+        u.disable("disabled locally");
+        root.commit();
+
+        // sync
+        syncCtx.setForceUserSync(true);
+        result = syncCtx.sync(user.getId());
+        assertEquals(SyncResult.Status.UPDATE, result.getStatus());
+        authorizable = userManager.getAuthorizable(user.getId());
+        assertNotNull(authorizable);
+        assertTrue(authorizable instanceof User);
+        assertTrue(((User)authorizable).isDisabled());
+    }
+
+    @Test
     public void testSyncGroupById() throws Exception {
         ExternalIdentity externalId = idp.listGroups().next();