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 ch...@apache.org on 2015/07/28 07:30:51 UTC

svn commit: r1692998 - in /jackrabbit/oak/trunk/oak-auth-external: ./ src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/

Author: chetanm
Date: Tue Jul 28 05:30:51 2015
New Revision: 1692998

URL: http://svn.apache.org/r1692998
Log:
OAK-3146 - ExternalLoginModuleFactory should inject SyncManager and ExternalIdentityProviderManager

Added:
    jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleFactoryTest.java   (with props)
Modified:
    jackrabbit/oak/trunk/oak-auth-external/pom.xml
    jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModule.java
    jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModuleFactory.java

Modified: jackrabbit/oak/trunk/oak-auth-external/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/pom.xml?rev=1692998&r1=1692997&r2=1692998&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-auth-external/pom.xml Tue Jul 28 05:30:51 2015
@@ -185,5 +185,10 @@
             <version>2.4</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.osgi-mock</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>

Modified: jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModule.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/ExternalLoginModule.java?rev=1692998&r1=1692997&r2=1692998&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModule.java (original)
+++ jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModule.java Tue Jul 28 05:30:51 2015
@@ -76,6 +76,10 @@ public class ExternalLoginModule extends
      */
     public static final String PARAM_SYNC_HANDLER_NAME = "sync.handlerName";
 
+    private ExternalIdentityProviderManager idpManager;
+
+    private SyncManager syncManager;
+
     /**
      * internal configuration when invoked from a factory rather than jaas
      */
@@ -136,11 +140,13 @@ public class ExternalLoginModule extends
         if (idpName.isEmpty()) {
             log.error("External login module needs IPD name. Will not be used for login.");
         } else {
-            ExternalIdentityProviderManager idpMgr = WhiteboardUtils.getService(whiteboard, ExternalIdentityProviderManager.class);
-            if (idpMgr == null) {
+            if (idpManager == null) {
+                idpManager = WhiteboardUtils.getService(whiteboard, ExternalIdentityProviderManager.class);
+            }
+            if (idpManager == null) {
                 log.error("External login module needs IDPManager. Will not be used for login.");
             } else {
-                idp = idpMgr.getProvider(idpName);
+                idp = idpManager.getProvider(idpName);
                 if (idp == null) {
                     log.error("No IDP found with name {}. Will not be used for login.", idpName);
                 }
@@ -151,11 +157,13 @@ public class ExternalLoginModule extends
         if (syncHandlerName.isEmpty()) {
             log.error("External login module needs SyncHandler name. Will not be used for login.");
         } else {
-            SyncManager syncMgr = WhiteboardUtils.getService(whiteboard, SyncManager.class);
-            if (syncMgr == null) {
+            if (syncManager == null) {
+                syncManager = WhiteboardUtils.getService(whiteboard, SyncManager.class);
+            }
+            if (syncManager == null) {
                 log.error("External login module needs SyncManager. Will not be used for login.");
             } else {
-                syncHandler = syncMgr.getSyncHandler(syncHandlerName);
+                syncHandler = syncManager.getSyncHandler(syncHandlerName);
                 if (syncHandler == null) {
                     log.error("No SyncHandler found with name {}. Will not be used for login.", syncHandlerName);
                 }
@@ -405,4 +413,13 @@ public class ExternalLoginModule extends
         Class scClass = SimpleCredentials.class;
         return Collections.singleton(scClass);
     }
+
+
+    public void setSyncManager(SyncManager syncManager) {
+        this.syncManager = syncManager;
+    }
+
+    public void setIdpManager(ExternalIdentityProviderManager idpManager) {
+        this.idpManager = idpManager;
+    }
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModuleFactory.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/ExternalLoginModuleFactory.java?rev=1692998&r1=1692997&r2=1692998&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModuleFactory.java (original)
+++ jackrabbit/oak/trunk/oak-auth-external/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/ExternalLoginModuleFactory.java Tue Jul 28 05:30:51 2015
@@ -165,7 +165,9 @@ public class ExternalLoginModuleFactory
      */
     @Override
     public LoginModule createLoginModule() {
-        return new ExternalLoginModule(osgiConfig);
+        ExternalLoginModule lm = new ExternalLoginModule(osgiConfig);
+        lm.setIdpManager(idpManager);
+        lm.setSyncManager(syncManager);
+        return lm;
     }
-
 }
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleFactoryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleFactoryTest.java?rev=1692998&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleFactoryTest.java (added)
+++ jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleFactoryTest.java Tue Jul 28 05:30:51 2015
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.spi.security.authentication.external;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.Repository;
+import javax.jcr.SimpleCredentials;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.spi.LoginModule;
+
+import org.apache.felix.jaas.LoginModuleFactory;
+import org.apache.felix.jaas.boot.ProxyLoginModule;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.Oak;
+import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.basic.DefaultSyncConfig;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.impl.DefaultSyncHandler;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalIDPManagerImpl;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalLoginModule;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalLoginModuleFactory;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.impl.SyncManagerImpl;
+import org.apache.jackrabbit.oak.spi.whiteboard.Registration;
+import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
+import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class ExternalLoginModuleFactoryTest extends AbstractSecurityTest {
+    private final static String TEST_CONSTANT_PROPERTY_NAME = "profile/constantProperty";
+
+    private final static String TEST_CONSTANT_PROPERTY_VALUE = "constant-value";
+
+    @Rule
+    public final OsgiContext context = new OsgiContext();
+
+    private final HashMap<String, Object> options = new HashMap<String, Object>();
+
+    private final String userId = "testUser";
+
+    private ExternalIdentityProvider idp;
+
+    private DefaultSyncConfig syncConfig;
+
+    private Registration testIdpReg;
+
+    private Registration syncHandlerReg;
+
+    private Whiteboard whiteboard;
+
+    @Override
+    protected Oak withEditors(Oak oak) {
+        super.withEditors(oak);
+        //Just grab the whiteboard but do not register any manager here
+        //This would ensure that LoginModule would only work if the required managers
+        //are preset
+        whiteboard = oak.getWhiteboard();
+        return oak;
+    }
+
+    @Before
+    public void before() throws Exception {
+        super.before();
+
+        idp = new TestIdentityProvider();
+        testIdpReg = whiteboard.register(ExternalIdentityProvider.class, idp, Collections.<String, Object>emptyMap());
+
+        options.put(ExternalLoginModule.PARAM_SYNC_HANDLER_NAME, "default");
+        options.put(ExternalLoginModule.PARAM_IDP_NAME, idp.getName());
+
+        // set default sync config
+        syncConfig = new DefaultSyncConfig();
+        Map<String, String> mapping = new HashMap<String, String>();
+        mapping.put("name", "name");
+        mapping.put("email", "email");
+        mapping.put("profile/name", "profile/name");
+        mapping.put("profile/age", "profile/age");
+        mapping.put(TEST_CONSTANT_PROPERTY_NAME, "\"constant-value\"");
+        syncConfig.user().setPropertyMapping(mapping);
+        syncConfig.user().setMembershipNestingDepth(1);
+        syncHandlerReg = whiteboard.register(SyncHandler.class, new DefaultSyncHandler(syncConfig), Collections.<String, Object>emptyMap());
+    }
+
+    @After
+    public void after() throws Exception {
+        testIdpReg.unregister();
+        syncHandlerReg.unregister();
+
+        try {
+            UserManager userManager = getUserManager(root);
+            Authorizable a = userManager.getAuthorizable(userId);
+            if (a != null) {
+                a.remove();
+            }
+            root.commit();
+        } finally {
+            root.refresh();
+            super.after();
+        }
+    }
+
+    protected Configuration getConfiguration() {
+        return new Configuration() {
+            @Override
+            public AppConfigurationEntry[] getAppConfigurationEntry(String s) {
+                AppConfigurationEntry entry = new AppConfigurationEntry(
+                        //Use ProxyLoginModule so that factory mode can be used
+                        ProxyLoginModule.class.getName(),
+                        AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
+                        options);
+                return new AppConfigurationEntry[]{entry};
+            }
+        };
+    }
+
+    //~-------------------------------------------< tests >
+
+    /**
+     * Prepares the OSGi part with required services injected and configures
+     * the factory in JAAS options which then delegates to ExternalLoginModuleFactory
+     */
+    public void setUpJaasFactoryWithInjection() throws Exception{
+        context.registerService(Repository.class, EasyMock.createMock(Repository.class));
+        context.registerService(SyncManager.class, new SyncManagerImpl(whiteboard));
+        context.registerService(ExternalIdentityProviderManager.class, new ExternalIDPManagerImpl(whiteboard));
+
+        final LoginModuleFactory lmf = context.registerInjectActivateService(new ExternalLoginModuleFactory());
+        options.put(ProxyLoginModule.PROP_LOGIN_MODULE_FACTORY, new ProxyLoginModule.BootLoginModuleFactory() {
+            @Override
+            public LoginModule createLoginModule() {
+                return lmf.createLoginModule();
+            }
+        });
+    }
+
+    @Test
+    public void testSyncCreateUser() throws Exception {
+        setUpJaasFactoryWithInjection();
+        UserManager userManager = getUserManager(root);
+        ContentSession cs = null;
+        try {
+            assertNull(userManager.getAuthorizable(userId));
+
+            cs = login(new SimpleCredentials(userId, new char[0]));
+
+            root.refresh();
+
+            Authorizable a = userManager.getAuthorizable(userId);
+            assertNotNull(a);
+            ExternalUser user = idp.getUser(userId);
+            for (String prop : user.getProperties().keySet()) {
+                assertTrue(a.hasProperty(prop));
+            }
+            assertEquals(TEST_CONSTANT_PROPERTY_VALUE, a.getProperty(TEST_CONSTANT_PROPERTY_NAME)[0].getString());
+        } finally {
+            if (cs != null) {
+                cs.close();
+            }
+            options.clear();
+        }
+    }
+
+}

Propchange: jackrabbit/oak/trunk/oak-auth-external/src/test/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModuleFactoryTest.java
------------------------------------------------------------------------------
    svn:eol-style = native