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 an...@apache.org on 2013/09/11 17:03:47 UTC

svn commit: r1521892 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/ oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/ oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/ ...

Author: angela
Date: Wed Sep 11 15:03:47 2013
New Revision: 1521892

URL: http://svn.apache.org/r1521892
Log:
OAK-521 : Configurable AuthorizableAction(s)
- simplify actions
- add composite action provider
- make default impl a service
- fix configuration of access control action
- remove implementation specific action api from generic user configuration and make it a parameter of the user configuration parameters

OAK-522 : Pluggable User Management (wip)
- make configuration impl a service

OAK-754 : Pluggable Security Setup (wip)
- rename ConfigurationParameters#getNullableConfigValue and allow to specify a target class and fix usages
- ConfigurationParameters: improve convertion
- ConfigurationParameters: add more utility methods to create config params

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiAuthorizableActionProvider.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/CompositeActionProvider.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionValidatorProvider.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserConfigurationImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserInitializer.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserManagerImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProvider.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/ConfigurationParameters.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModule.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserConfiguration.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AbstractAuthorizableAction.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AccessControlAction.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AuthorizableAction.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AuthorizableActionProvider.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/ClearMembershipAction.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/DefaultAuthorizableActionProvider.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/PasswordChangeAction.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/PasswordValidationAction.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/ConfigurationParametersTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/user/action/AccessControlActionTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/user/action/PasswordValidationActionTest.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/UserImportWithActionsTest.java

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiAuthorizableActionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiAuthorizableActionProvider.java?rev=1521892&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiAuthorizableActionProvider.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiAuthorizableActionProvider.java Wed Sep 11 15:03:47 2013
@@ -0,0 +1,41 @@
+/*
+ * 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.osgi;
+
+import java.util.List;
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import org.apache.jackrabbit.oak.spi.security.user.action.AuthorizableAction;
+import org.apache.jackrabbit.oak.spi.security.user.action.AuthorizableActionProvider;
+import org.apache.jackrabbit.oak.spi.security.user.action.CompositeActionProvider;
+
+/**
+ * OsgiAuthorizableActionProvider... TODO
+ */
+public class OsgiAuthorizableActionProvider extends AbstractServiceTracker<AuthorizableActionProvider> implements AuthorizableActionProvider {
+
+    public OsgiAuthorizableActionProvider() {
+        super(AuthorizableActionProvider.class);
+    }
+
+    @Override
+    public List<? extends AuthorizableAction> getAuthorizableActions(@Nonnull SecurityProvider securityProvider) {
+        AuthorizableActionProvider actionProvider = new CompositeActionProvider(getServices());
+        return actionProvider.getAuthorizableActions(securityProvider);
+    }
+}
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionValidatorProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionValidatorProvider.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionValidatorProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionValidatorProvider.java Wed Sep 11 15:03:47 2013
@@ -54,7 +54,7 @@ public class PermissionValidatorProvider
         this.acConfig = securityProvider.getConfiguration(AuthorizationConfiguration.class);
 
         ConfigurationParameters params = acConfig.getParameters();
-        String compatValue = params.getNullableConfigValue(PermissionConstants.PARAM_PERMISSIONS_JR2, null);
+        String compatValue = params.getConfigValue(PermissionConstants.PARAM_PERMISSIONS_JR2, null, String.class);
         jr2Permissions = Permissions.getPermissions(compatValue);
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserConfigurationImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserConfigurationImpl.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserConfigurationImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserConfigurationImpl.java Wed Sep 11 15:03:47 2013
@@ -20,6 +20,8 @@ import java.util.Collections;
 import java.util.List;
 import javax.annotation.Nonnull;
 
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
 import org.apache.jackrabbit.api.security.user.UserManager;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
@@ -27,17 +29,21 @@ import org.apache.jackrabbit.oak.spi.com
 import org.apache.jackrabbit.oak.spi.lifecycle.WorkspaceInitializer;
 import org.apache.jackrabbit.oak.spi.security.ConfigurationBase;
 import org.apache.jackrabbit.oak.spi.security.Context;
+import org.apache.jackrabbit.oak.spi.security.SecurityConfiguration;
 import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
 import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
-import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
-import org.apache.jackrabbit.oak.spi.security.user.action.AuthorizableActionProvider;
-import org.apache.jackrabbit.oak.spi.security.user.action.DefaultAuthorizableActionProvider;
 import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
 
 /**
  * Default implementation of the {@link UserConfiguration}.
  */
-public class UserConfigurationImpl extends ConfigurationBase implements UserConfiguration {
+@Component()
+@Service({UserConfiguration.class, SecurityConfiguration.class})
+public class UserConfigurationImpl extends ConfigurationBase implements UserConfiguration, SecurityConfiguration {
+
+    public UserConfigurationImpl() {
+        super();
+    }
 
     public UserConfigurationImpl(SecurityProvider securityProvider) {
         super(securityProvider);
@@ -80,12 +86,4 @@ public class UserConfigurationImpl exten
     public UserManager getUserManager(Root root, NamePathMapper namePathMapper) {
         return new UserManagerImpl(root, namePathMapper, getSecurityProvider());
     }
-
-    @Nonnull
-    @Override
-    public AuthorizableActionProvider getAuthorizableActionProvider() {
-        // TODO OAK-521: add proper implementation
-        AuthorizableActionProvider defProvider = new DefaultAuthorizableActionProvider(getSecurityProvider(), getParameters());
-        return getParameters().getConfigValue(UserConstants.PARAM_AUTHORIZABLE_ACTION_PROVIDER, defProvider);
-    }
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserInitializer.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserInitializer.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserInitializer.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserInitializer.java Wed Sep 11 15:03:47 2013
@@ -126,7 +126,7 @@ class UserInitializer implements Workspa
                 boolean omitPw = params.getConfigValue(PARAM_OMIT_ADMIN_PW, false);
                 userManager.createUser(adminId, (omitPw) ? null : adminId);
             }
-            String anonymousId = Strings.emptyToNull(params.getNullableConfigValue(PARAM_ANONYMOUS_ID, DEFAULT_ANONYMOUS_ID));
+            String anonymousId = Strings.emptyToNull(params.getConfigValue(PARAM_ANONYMOUS_ID, DEFAULT_ANONYMOUS_ID, String.class));
             if (anonymousId != null && userManager.getAuthorizable(anonymousId) == null) {
                 userManager.createUser(anonymousId, null);
             }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserManagerImpl.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserManagerImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserManagerImpl.java Wed Sep 11 15:03:47 2013
@@ -20,7 +20,6 @@ import java.io.UnsupportedEncodingExcept
 import java.security.NoSuchAlgorithmException;
 import java.security.Principal;
 import java.util.Iterator;
-import java.util.List;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -48,6 +47,8 @@ import org.apache.jackrabbit.oak.spi.sec
 import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
 import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
 import org.apache.jackrabbit.oak.spi.security.user.action.AuthorizableAction;
+import org.apache.jackrabbit.oak.spi.security.user.action.AuthorizableActionProvider;
+import org.apache.jackrabbit.oak.spi.security.user.action.DefaultAuthorizableActionProvider;
 import org.apache.jackrabbit.oak.spi.security.user.util.PasswordUtil;
 import org.apache.jackrabbit.oak.spi.security.user.util.UserUtil;
 import org.slf4j.Logger;
@@ -69,7 +70,7 @@ public class UserManagerImpl implements 
     private final UserProvider userProvider;
     private final MembershipProvider membershipProvider;
     private final ConfigurationParameters config;
-    private final List<AuthorizableAction> authorizableActions;
+    private final AuthorizableActionProvider actionProvider;
 
     private UserQueryManager queryManager;
     private ReadOnlyNodeTypeManager ntMgr;
@@ -83,7 +84,16 @@ public class UserManagerImpl implements 
         this.config = uc.getParameters();
         this.userProvider = new UserProvider(root, config);
         this.membershipProvider = new MembershipProvider(root, config);
-        this.authorizableActions = uc.getAuthorizableActionProvider().getAuthorizableActions();
+        this.actionProvider = getActionProvider(config);
+    }
+
+    @Nonnull
+    private static AuthorizableActionProvider getActionProvider(ConfigurationParameters config) {
+        AuthorizableActionProvider actionProvider = config.getConfigValue(UserConstants.PARAM_AUTHORIZABLE_ACTION_PROVIDER, null, AuthorizableActionProvider.class);
+        if (actionProvider == null) {
+            actionProvider = new DefaultAuthorizableActionProvider(config);
+        }
+        return actionProvider;
     }
 
     //--------------------------------------------------------< UserManager >---
@@ -224,7 +234,7 @@ public class UserManagerImpl implements 
      * @throws RepositoryException If an exception occurs.
      */
     void onCreate(User user, String password) throws RepositoryException {
-        for (AuthorizableAction action : authorizableActions) {
+        for (AuthorizableAction action : actionProvider.getAuthorizableActions(securityProvider)) {
             action.onCreate(user, password, root, namePathMapper);
         }
     }
@@ -238,7 +248,7 @@ public class UserManagerImpl implements 
      * @throws RepositoryException If an exception occurs.
      */
     void onCreate(Group group) throws RepositoryException {
-        for (AuthorizableAction action : authorizableActions) {
+        for (AuthorizableAction action : actionProvider.getAuthorizableActions(securityProvider)) {
             action.onCreate(group, root, namePathMapper);
         }
     }
@@ -252,7 +262,7 @@ public class UserManagerImpl implements 
      * @throws RepositoryException If an exception occurs.
      */
     void onRemove(Authorizable authorizable) throws RepositoryException {
-        for (AuthorizableAction action : authorizableActions) {
+        for (AuthorizableAction action : actionProvider.getAuthorizableActions(securityProvider)) {
             action.onRemove(authorizable, root, namePathMapper);
         }
     }
@@ -267,7 +277,7 @@ public class UserManagerImpl implements 
      * @throws RepositoryException If an exception occurs.
      */
     void onPasswordChange(User user, String password) throws RepositoryException {
-        for (AuthorizableAction action : authorizableActions) {
+        for (AuthorizableAction action : actionProvider.getAuthorizableActions(securityProvider)) {
             action.onPasswordChange(user, password, root, namePathMapper);
         }
     }
@@ -305,11 +315,6 @@ public class UserManagerImpl implements 
     }
 
     @Nonnull
-    SecurityProvider getSecurityProvider() {
-        return securityProvider;
-    }
-
-    @Nonnull
     ConfigurationParameters getConfig() {
         return config;
     }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProvider.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserProvider.java Wed Sep 11 15:03:47 2013
@@ -338,7 +338,7 @@ class UserProvider extends AuthorizableB
     }
 
     private String getNodeName(String authorizableId) {
-        AuthorizableNodeName generator = config.getConfigValue(PARAM_AUTHORIZABLE_NODE_NAME, AuthorizableNodeName.DEFAULT);
+        AuthorizableNodeName generator = checkNotNull(config.getConfigValue(PARAM_AUTHORIZABLE_NODE_NAME, AuthorizableNodeName.DEFAULT, AuthorizableNodeName.class));
         return generator.generateNodeName(authorizableId);
     }
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/ConfigurationParameters.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/ConfigurationParameters.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/ConfigurationParameters.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/ConfigurationParameters.java Wed Sep 11 15:03:47 2013
@@ -26,6 +26,8 @@ import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -48,7 +50,15 @@ public class ConfigurationParameters {
         this.options = (options == null) ? Collections.<String, Object>emptyMap() : Collections.unmodifiableMap(options);
     }
 
-    public static ConfigurationParameters newInstance(Properties properties) {
+    public static ConfigurationParameters newInstance(@Nonnull ConfigurationParameters... params) {
+        Map<String, Object> m = Maps.newHashMap();
+        for (ConfigurationParameters cp : params) {
+            m.putAll(cp.options);
+        }
+        return new ConfigurationParameters(ImmutableMap.copyOf(m));
+    }
+
+    public static ConfigurationParameters newInstance(@Nonnull Properties properties) {
         if (properties.isEmpty()) {
             return EMPTY;
         }
@@ -60,7 +70,7 @@ public class ConfigurationParameters {
         return new ConfigurationParameters(options);
     }
 
-    public static ConfigurationParameters newInstance(Dictionary<String, Object> properties) {
+    public static ConfigurationParameters newInstance(@Nonnull Dictionary<String, Object> properties) {
         if (properties.isEmpty()) {
             return EMPTY;
         }
@@ -101,15 +111,18 @@ public class ConfigurationParameters {
      *     match the type of the default value.</li>
      * </ul>
      *
+     *
      * @param key The name of the configuration option.
      * @param defaultValue The default value to return if no such entry exists
      * or to use for conversion.
+     * @param targetClass The target class
      * @return The original or converted configuration value or {@code null}.
      */
     @CheckForNull
-    public <T> T getNullableConfigValue(@Nonnull String key, @Nullable T defaultValue) {
-        if (options != null && options.containsKey(key)) {
-            return convert(options.get(key), defaultValue);
+    public <T> T getConfigValue(@Nonnull String key, @Nullable T defaultValue,
+                                @Nullable Class<T> targetClass) {
+        if (options.containsKey(key)) {
+            return convert(options.get(key), defaultValue, targetClass);
         } else {
             return defaultValue;
         }
@@ -117,8 +130,8 @@ public class ConfigurationParameters {
 
     @Nonnull
     public <T> T getConfigValue(@Nonnull String key, @Nonnull T defaultValue) {
-        if (options != null && options.containsKey(key)) {
-            T value = convert(options.get(key), defaultValue);
+        if (options.containsKey(key)) {
+            T value = convert(options.get(key), defaultValue, null);
             return (value == null) ? defaultValue : value;
         } else {
             return defaultValue;
@@ -128,16 +141,21 @@ public class ConfigurationParameters {
     //--------------------------------------------------------< private >---
     @SuppressWarnings("unchecked")
     @Nullable
-    private static <T> T convert(@Nullable Object configProperty, @Nullable T defaultValue) {
+    private static <T> T convert(@Nullable Object configProperty, @Nullable T defaultValue, @Nullable Class<T> trgtClass) {
         if (configProperty == null) {
             return null;
         }
 
         T value;
         String str = configProperty.toString();
-        Class targetClass = (defaultValue == null) ? configProperty.getClass() : defaultValue.getClass();
+        Class targetClass;
+        if (trgtClass != null) {
+            targetClass = trgtClass;
+        } else {
+            targetClass = (defaultValue == null) ? configProperty.getClass() : defaultValue.getClass();
+        }
         try {
-            if (targetClass == configProperty.getClass()) {
+            if (targetClass.equals(configProperty.getClass()) || targetClass.isAssignableFrom(configProperty.getClass())) {
                 value = (T) configProperty;
             } else if (targetClass == String.class) {
                 value = (T) str;
@@ -156,7 +174,7 @@ public class ConfigurationParameters {
             }
         } catch (NumberFormatException e) {
             log.warn("Invalid value {}; cannot be parsed into {}", str, targetClass.getName());
-            value = defaultValue;
+            throw new IllegalArgumentException("Cannot convert config entry " + str + " to " + targetClass.getName());
         }
         return value;
     }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModule.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModule.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModule.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/external/ExternalLoginModule.java Wed Sep 11 15:03:47 2013
@@ -65,7 +65,7 @@ public abstract class ExternalLoginModul
      * @throws SyncException
      */
     protected SyncHandler getSyncHandler() throws SyncException {
-        Object syncHandler = options.getNullableConfigValue(PARAM_SYNC_HANDLER, null);
+        Object syncHandler = options.getConfigValue(PARAM_SYNC_HANDLER, null, null);
         if (syncHandler == null) {
             return new DefaultSyncHandler();
         } else if (syncHandler instanceof SyncHandler) {
@@ -117,7 +117,7 @@ public abstract class ExternalLoginModul
         try {
             SyncHandler handler = getSyncHandler();
             Root root = getRoot();
-            Object smValue = options.getNullableConfigValue(PARAM_SYNC_MODE, null);
+            Object smValue = options.getConfigValue(PARAM_SYNC_MODE, null, null);
             SyncMode syncMode;
             if (smValue == null) {
                 syncMode = DEFAULT_SYNC_MODE;

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserConfiguration.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserConfiguration.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserConfiguration.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/UserConfiguration.java Wed Sep 11 15:03:47 2013
@@ -22,7 +22,6 @@ import org.apache.jackrabbit.api.securit
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.spi.security.SecurityConfiguration;
-import org.apache.jackrabbit.oak.spi.security.user.action.AuthorizableActionProvider;
 
 /**
  * Configuration interface for user management.
@@ -33,7 +32,4 @@ public interface UserConfiguration exten
 
     @Nonnull
     UserManager getUserManager(Root root, NamePathMapper namePathMapper);
-
-    @Nonnull
-    AuthorizableActionProvider getAuthorizableActionProvider();
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AbstractAuthorizableAction.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AbstractAuthorizableAction.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AbstractAuthorizableAction.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AbstractAuthorizableAction.java Wed Sep 11 15:03:47 2013
@@ -35,14 +35,17 @@ import org.apache.jackrabbit.oak.spi.sec
  */
 public abstract class AbstractAuthorizableAction implements AuthorizableAction {
 
-    // TODO OAK-521:: review again
-    protected abstract void init(SecurityProvider securityProvider, ConfigurationParameters config);
-
     //-------------------------------------------------< AuthorizableAction >---
     /**
      * Doesn't perform any action.
-     *
-     * @see AuthorizableAction#onCreate(org.apache.jackrabbit.api.security.user.Group, org.apache.jackrabbit.oak.api.Root, org.apache.jackrabbit.oak.namepath.NamePathMapper)
+     */
+    @Override
+    public void init(SecurityProvider securityProvider, ConfigurationParameters config) {
+        // nothing to do
+    }
+
+    /**
+     * Doesn't perform any action.
      */
     @Override
     public void onCreate(@Nonnull Group group, @Nonnull Root root, @Nonnull NamePathMapper namePathMapper) throws RepositoryException {
@@ -51,8 +54,6 @@ public abstract class AbstractAuthorizab
 
     /**
      * Doesn't perform any action.
-     *
-     * @see AuthorizableAction#onCreate(org.apache.jackrabbit.api.security.user.User, String, org.apache.jackrabbit.oak.api.Root, org.apache.jackrabbit.oak.namepath.NamePathMapper)
      */
     @Override
     public void onCreate(@Nonnull User user, @Nullable String password, @Nonnull Root root, @Nonnull NamePathMapper namePathMapper) throws RepositoryException {
@@ -61,8 +62,6 @@ public abstract class AbstractAuthorizab
 
     /**
      * Doesn't perform any action.
-     *
-     * @see AuthorizableAction#onRemove(org.apache.jackrabbit.api.security.user.Authorizable, org.apache.jackrabbit.oak.api.Root, org.apache.jackrabbit.oak.namepath.NamePathMapper)
      */
     @Override
     public void onRemove(@Nonnull Authorizable authorizable, @Nonnull Root root, @Nonnull NamePathMapper namePathMapper) throws RepositoryException {
@@ -71,8 +70,6 @@ public abstract class AbstractAuthorizab
 
     /**
      * Doesn't perform any action.
-     *
-     * @see AuthorizableAction#onPasswordChange(org.apache.jackrabbit.api.security.user.User, String, org.apache.jackrabbit.oak.api.Root, org.apache.jackrabbit.oak.namepath.NamePathMapper)
      */
     @Override
     public void onPasswordChange(@Nonnull User user, @Nullable String newPassword, @Nonnull Root root, @Nonnull NamePathMapper namePathMapper) throws RepositoryException {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AccessControlAction.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AccessControlAction.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AccessControlAction.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AccessControlAction.java Wed Sep 11 15:03:47 2013
@@ -17,8 +17,6 @@
 package org.apache.jackrabbit.oak.spi.security.user.action;
 
 import java.security.Principal;
-import java.util.ArrayList;
-import java.util.List;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import javax.jcr.RepositoryException;
@@ -38,7 +36,6 @@ import org.apache.jackrabbit.oak.spi.sec
 import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
 import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
 import org.apache.jackrabbit.oak.spi.security.user.util.UserUtil;
-import org.apache.jackrabbit.util.Text;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -60,8 +57,8 @@ import org.slf4j.LoggerFactory;
  * </p>
  * <p>Example configuration:
  * <pre>
- *    groupPrivilegeNames : "jcr:read"
- *    userPrivilegeNames  : "jcr:read, rep:write"
+ *    groupPrivilegeNames : ["jcr:read"]
+ *    userPrivilegeNames  : ["jcr:read,rep:write"]
  * </pre>
  * </p>
  * <p>This configuration could for example lead to the following content
@@ -109,15 +106,14 @@ public class AccessControlAction extends
     private String[] groupPrivilegeNames = new String[0];
     private String[] userPrivilegeNames = new String[0];
 
-    //-----------------------------------------< AbstractAuthorizableAction >---
+    //-------------------------------------------------< AuthorizableAction >---
     @Override
-    protected void init(SecurityProvider securityProvider, ConfigurationParameters config) {
-        setSecurityProvider(securityProvider);
-        setUserPrivilegeNames(config.getNullableConfigValue(USER_PRIVILEGE_NAMES, (String) null));
-        setGroupPrivilegeNames(config.getNullableConfigValue(GROUP_PRIVILEGE_NAMES, (String) null));
+    public void init(SecurityProvider securityProvider, ConfigurationParameters config) {
+        this.securityProvider = securityProvider;
+        userPrivilegeNames = privilegeNames(config, USER_PRIVILEGE_NAMES);
+        groupPrivilegeNames = privilegeNames(config, GROUP_PRIVILEGE_NAMES);
     }
 
-    //-------------------------------------------------< AuthorizableAction >---
     @Override
     public void onCreate(Group group, Root root, NamePathMapper namePathMapper) throws RepositoryException {
         setAC(group, root, namePathMapper);
@@ -128,36 +124,23 @@ public class AccessControlAction extends
         setAC(user, root, namePathMapper);
     }
 
-    //------------------------------------------------------< Configuration >---
-    public void setSecurityProvider(@Nonnull SecurityProvider securityProvider) {
-        this.securityProvider = securityProvider;
-    }
-
-    /**
-     * Sets the privileges a new group will be granted on the group's home directory.
-     *
-     * @param privilegeNames A comma separated list of privilege names.
-     */
-    public void setGroupPrivilegeNames(@Nullable String privilegeNames) {
-        if (privilegeNames != null && privilegeNames.length() > 0) {
-            groupPrivilegeNames = split(privilegeNames);
-        }
-
-    }
-
+    //------------------------------------------------------------< private >---
     /**
-     * Sets the privileges a new user will be granted on the user's home directory.
+     * Gets the privilege names that be granted on the group's home directory.
      *
-     * @param privilegeNames  A comma separated list of privilege names.
+     * @param config the configuration parameters.
+     * @param paramName the name of the configuration option
+     * @return a valid string array containing the privilege names.
      */
-    public void setUserPrivilegeNames(@Nullable String privilegeNames) {
-        if (privilegeNames != null && privilegeNames.length() > 0) {
-            userPrivilegeNames = split(privilegeNames);
+    private static String[] privilegeNames(ConfigurationParameters config, String paramName) {
+        String[] privilegeNames = config.getConfigValue(paramName, null, String[].class);
+        if (privilegeNames != null && privilegeNames.length > 0) {
+            return privilegeNames;
+        } else {
+            return new String[0];
         }
     }
 
-    //------------------------------------------------------------< private >---
-
     private void setAC(@Nonnull Authorizable authorizable, @Nonnull Root root,
                        @Nonnull NamePathMapper namePathMapper) throws RepositoryException {
         if (securityProvider == null) {
@@ -236,22 +219,4 @@ public class AccessControlAction extends
         }
         return privileges;
     }
-
-    /**
-     * Split the specified configuration parameter into privilege names.
-     *
-     * @param configParam The configuration parameter defining a comma separated
-     * list of privilege names.
-     * @return An array of privilege names.
-     */
-    private static String[] split(@Nonnull String configParam) {
-        List<String> nameList = new ArrayList<String>();
-        for (String pn : Text.explode(configParam, ',', false)) {
-            String privName = pn.trim();
-            if (privName.length()  > 0) {
-                nameList.add(privName);
-            }
-        }
-        return nameList.toArray(new String[nameList.size()]);
-    }
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AuthorizableAction.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AuthorizableAction.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AuthorizableAction.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AuthorizableAction.java Wed Sep 11 15:03:47 2013
@@ -23,6 +23,8 @@ import org.apache.jackrabbit.api.securit
 import org.apache.jackrabbit.api.security.user.User;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
 
 /**
  * The {@code AuthorizableAction} interface provide an implementation
@@ -45,6 +47,14 @@ import org.apache.jackrabbit.oak.namepat
 public interface AuthorizableAction {
 
     /**
+     * Initialize this action with the specified security provider and configuration.
+     *
+     * @param securityProvider
+     * @param config
+     */
+    void init(SecurityProvider securityProvider, ConfigurationParameters config);
+
+    /**
      * Allows to add application specific modifications or validation associated
      * with the creation of a new group. Note, that this method is called
      * <strong>before</strong> any {@code Root#commit()} call.

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AuthorizableActionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AuthorizableActionProvider.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AuthorizableActionProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AuthorizableActionProvider.java Wed Sep 11 15:03:47 2013
@@ -17,6 +17,9 @@
 package org.apache.jackrabbit.oak.spi.security.user.action;
 
 import java.util.List;
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
 
 /**
  * {@code AuthorizableActionProvider} is used to provide {@code AuthorizableAction}s
@@ -26,5 +29,5 @@ import java.util.List;
  */
 public interface AuthorizableActionProvider {
 
-    List<AuthorizableAction> getAuthorizableActions();
+    List<? extends AuthorizableAction> getAuthorizableActions(@Nonnull SecurityProvider securityProvider);
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/ClearMembershipAction.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/ClearMembershipAction.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/ClearMembershipAction.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/ClearMembershipAction.java Wed Sep 11 15:03:47 2013
@@ -23,8 +23,6 @@ import org.apache.jackrabbit.api.securit
 import org.apache.jackrabbit.api.security.user.Group;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
-import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
-import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
 
 /**
  * Authorizable action attempting to clear all group membership before removing
@@ -34,12 +32,6 @@ import org.apache.jackrabbit.oak.spi.sec
  */
 public class ClearMembershipAction extends AbstractAuthorizableAction {
 
-    //-----------------------------------------< AbstractAuthorizableAction >---
-    @Override
-    protected void init(SecurityProvider securityProvider, ConfigurationParameters config) {
-        // nothing to do
-    }
-
     //-------------------------------------------------< AuthorizableAction >---
     @Override
     public void onRemove(Authorizable authorizable, Root root, NamePathMapper namePathMapper) throws RepositoryException {

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/CompositeActionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/CompositeActionProvider.java?rev=1521892&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/CompositeActionProvider.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/CompositeActionProvider.java Wed Sep 11 15:03:47 2013
@@ -0,0 +1,50 @@
+/*
+ * 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.user.action;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import com.google.common.collect.Lists;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+
+/**
+ * Aggregates a collection of {@link AuthorizableActionProvider}s into a single
+ * provider.
+ */
+public class CompositeActionProvider implements AuthorizableActionProvider {
+
+    private final Collection<? extends AuthorizableActionProvider> providers;
+
+    public CompositeActionProvider(Collection<? extends AuthorizableActionProvider> providers) {
+        this.providers = providers;
+    }
+
+    public CompositeActionProvider(AuthorizableActionProvider... providers) {
+        this.providers = Arrays.asList(providers);
+    }
+
+    @Override
+    public List<? extends AuthorizableAction> getAuthorizableActions(SecurityProvider securityProvider) {
+        List<AuthorizableAction> actions = Lists.newArrayList();
+        for (AuthorizableActionProvider p : providers) {
+            actions.addAll(p.getAuthorizableActions(securityProvider));
+        }
+        return actions;
+    }
+}
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/DefaultAuthorizableActionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/DefaultAuthorizableActionProvider.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/DefaultAuthorizableActionProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/DefaultAuthorizableActionProvider.java Wed Sep 11 15:03:47 2013
@@ -16,31 +16,74 @@
  */
 package org.apache.jackrabbit.oak.spi.security.user.action;
 
-import java.util.Collections;
 import java.util.List;
 
+import com.google.common.collect.Lists;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.PropertyOption;
+import org.apache.felix.scr.annotations.Service;
 import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
 import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
- * DefaultAuthorizableActionProvider... TODO
+ * Default implementation of the {@link AuthorizableActionProvider} interface
+ * that allows to config all actions provided by the OAK.
  */
+@Component()
+@Service(AuthorizableActionProvider.class)
 public class DefaultAuthorizableActionProvider implements AuthorizableActionProvider {
 
-    private final SecurityProvider securityProvider;
-    private final ConfigurationParameters config;
+    private static final Logger log = LoggerFactory.getLogger(DefaultAuthorizableActionProvider.class);
 
-    public DefaultAuthorizableActionProvider(SecurityProvider securityProvider,
-                                             ConfigurationParameters config) {
-        this.securityProvider = securityProvider;
+    private static final String ENABLED_ACTIONS = "enabledActions";
+
+    @Property(name = ENABLED_ACTIONS,
+            options = {
+                    @PropertyOption(name = "org.apache.jackrabbit.oak.spi.security.user.action.AccessControlAction", value = "AccessControlAction"),
+                    @PropertyOption(name = "org.apache.jackrabbit.oak.spi.security.user.action.PasswordValidationAction", value = "PasswordValidationAction"),
+                    @PropertyOption(name = "org.apache.jackrabbit.oak.spi.security.user.action.PasswordChangeAction", value = "PasswordChangeAction"),
+                    @PropertyOption(name = "org.apache.jackrabbit.oak.spi.security.user.action.ClearMembershipAction", value = "ClearMembershipAction")
+            })
+    private String[] enabledActions = new String[] {AccessControlAction.class.getName()};
+
+    private ConfigurationParameters config = ConfigurationParameters.EMPTY;
+
+    public DefaultAuthorizableActionProvider() {}
+
+    public DefaultAuthorizableActionProvider(ConfigurationParameters config) {
         this.config = config;
     }
 
+    //-----------------------------------------< AuthorizableActionProvider >---
     @Override
-    public List<AuthorizableAction> getAuthorizableActions() {
-        // TODO OAK-521: create and initialize actions from configuration
-        AccessControlAction action = new AccessControlAction();
-        action.init(securityProvider, config);
-        return Collections.<AuthorizableAction>singletonList(action);
+    public List<? extends AuthorizableAction> getAuthorizableActions(SecurityProvider securityProvider) {
+        List<AuthorizableAction> actions = Lists.newArrayList();
+        for (String className : enabledActions) {
+            try {
+                Object o = Class.forName(className).newInstance();
+                if (o instanceof AuthorizableAction) {
+                    actions.add((AuthorizableAction) o);
+                }
+            } catch (Exception e) {
+                log.debug("Unable to create authorizable action", e);
+            }
+        }
+
+        // merge configurations that may contain action configuration information
+        for (AuthorizableAction action : actions) {
+            action.init(securityProvider, config);
+        }
+        return actions;
+    }
+
+    //----------------------------------------------------< SCR Integration >---
+    @Activate
+    protected void activate(ComponentContext context) {
+        config = ConfigurationParameters.newInstance(context.getProperties());
     }
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/PasswordChangeAction.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/PasswordChangeAction.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/PasswordChangeAction.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/PasswordChangeAction.java Wed Sep 11 15:03:47 2013
@@ -24,8 +24,6 @@ import javax.jcr.nodetype.ConstraintViol
 import org.apache.jackrabbit.api.security.user.User;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
-import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
-import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
 import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
 import org.apache.jackrabbit.oak.spi.security.user.util.PasswordUtil;
 import org.apache.jackrabbit.oak.util.TreeUtil;
@@ -43,11 +41,6 @@ import org.apache.jackrabbit.oak.util.Tr
  */
 public class PasswordChangeAction extends AbstractAuthorizableAction {
 
-    @Override
-    protected void init(SecurityProvider securityProvider, ConfigurationParameters config) {
-        // nothing to do
-    }
-
     //-------------------------------------------------< AuthorizableAction >---
     @Override
     public void onPasswordChange(User user, String newPassword, Root root, NamePathMapper namePathMapper) throws RepositoryException {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/PasswordValidationAction.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/PasswordValidationAction.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/PasswordValidationAction.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/PasswordValidationAction.java Wed Sep 11 15:03:47 2013
@@ -57,16 +57,15 @@ public class PasswordValidationAction ex
 
     private Pattern pattern;
 
-    //-----------------------------------------< AbstractAuthorizableAction >---
+    //-------------------------------------------------< AuthorizableAction >---
     @Override
-    protected void init(SecurityProvider securityProvider, ConfigurationParameters config) {
-        String constraint = config.getNullableConfigValue(CONSTRAINT, (String) null);
+    public void init(SecurityProvider securityProvider, ConfigurationParameters config) {
+        String constraint = config.getConfigValue(CONSTRAINT, null, String.class);
         if (constraint != null) {
             setConstraint(constraint);
         }
     }
 
-    //-------------------------------------------------< AuthorizableAction >---
     @Override
     public void onCreate(User user, String password, Root root, NamePathMapper namePathMapper) throws RepositoryException {
         validatePassword(password, false);
@@ -77,13 +76,13 @@ public class PasswordValidationAction ex
         validatePassword(newPassword, true);
     }
 
-    //------------------------------------------------------< Configuration >---
+    //------------------------------------------------------------< private >---
     /**
      * Set the password constraint.
      *
      * @param constraint A regular expression that can be used to validate a new password.
      */
-    public void setConstraint(@Nonnull String constraint) {
+    private void setConstraint(@Nonnull String constraint) {
         try {
             pattern = Pattern.compile(constraint);
         } catch (PatternSyntaxException e) {
@@ -91,7 +90,6 @@ public class PasswordValidationAction ex
         }
     }
 
-    //------------------------------------------------------------< private >---
     /**
      * Validate the specified password.
      *

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/ConfigurationParametersTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/ConfigurationParametersTest.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/ConfigurationParametersTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/ConfigurationParametersTest.java Wed Sep 11 15:03:47 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.oak.security;
 
+import java.util.Calendar;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -30,6 +31,7 @@ import static junit.framework.Assert.ass
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
 import static org.junit.Assert.assertArrayEquals;
 
 public class ConfigurationParametersTest {
@@ -72,10 +74,17 @@ public class ConfigurationParametersTest
         map.put("o1", "v");
         ConfigurationParameters options = new ConfigurationParameters(map);
 
-        assertEquals("v", options.getNullableConfigValue("o1", null));
-        assertEquals("v", options.getNullableConfigValue("o1", "v2"));
-        assertEquals("v2", options.getNullableConfigValue("missing", "v2"));
-        assertEquals(null, options.getNullableConfigValue("missing", null));
+        assertEquals("v", options.getConfigValue("o1", null, null));
+        assertEquals("v", options.getConfigValue("o1", null, String.class));
+
+        assertEquals("v", options.getConfigValue("o1", "v2", null));
+        assertEquals("v", options.getConfigValue("o1", "v2", String.class));
+
+        assertEquals("v2", options.getConfigValue("missing", "v2", null));
+        assertEquals("v2", options.getConfigValue("missing", "v2", String.class));
+
+        assertNull(options.getConfigValue("missing", null, null));
+        assertNull(options.getConfigValue("missing", null, TestObject.class));
 
     }
 
@@ -89,9 +98,11 @@ public class ConfigurationParametersTest
         assertEquals(obj, options.getConfigValue("missing", obj));
         assertEquals(int1000, options.getConfigValue("missing", int1000));
 
-        assertNull(options.getNullableConfigValue("missing", null));
-        assertEquals(obj, options.getNullableConfigValue("missing", obj));
-        assertEquals(int1000, options.getNullableConfigValue("missing", int1000));
+        assertNull(options.getConfigValue("missing", null, null));
+        assertNull(options.getConfigValue("missing", null, String.class));
+        assertEquals(obj, options.getConfigValue("missing", obj, null));
+        assertEquals(obj, options.getConfigValue("missing", obj, TestObject.class));
+        assertEquals(int1000, options.getConfigValue("missing", int1000, Integer.class));
     }
 
     @Test
@@ -111,14 +122,17 @@ public class ConfigurationParametersTest
     public void testArrayDefaultValue2() {
         TestObject[] testArray = new TestObject[] {new TestObject("t")};
 
-        TestObject[] result = ConfigurationParameters.EMPTY.getNullableConfigValue("test", new TestObject[0]);
+        TestObject[] result = ConfigurationParameters.EMPTY.getConfigValue("test", new TestObject[0], null);
         assertNotNull(result);
         assertEquals(0, result.length);
-        assertArrayEquals(testArray, ConfigurationParameters.EMPTY.getNullableConfigValue("test", testArray));
+        assertArrayEquals(testArray, ConfigurationParameters.EMPTY.getConfigValue("test", testArray, null));
+        assertArrayEquals(testArray, ConfigurationParameters.EMPTY.getConfigValue("test", testArray, TestObject[].class));
 
         ConfigurationParameters options = new ConfigurationParameters(Collections.singletonMap("test", testArray));
-        assertArrayEquals(testArray, (TestObject[]) options.getNullableConfigValue("test", null));
-        assertArrayEquals(testArray, options.getNullableConfigValue("test", new TestObject[] {new TestObject("s")}));
+        assertArrayEquals(testArray, (TestObject[]) options.getConfigValue("test", null, null));
+        assertArrayEquals(testArray, options.getConfigValue("test", null, TestObject[].class));
+        assertArrayEquals(testArray, options.getConfigValue("test", new TestObject[]{new TestObject("s")}, null));
+        assertArrayEquals(testArray, options.getConfigValue("test", new TestObject[]{new TestObject("s")}, TestObject[].class));
     }
 
     @Test
@@ -159,24 +173,63 @@ public class ConfigurationParametersTest
         m.put("Int3", 1000);
         ConfigurationParameters options = new ConfigurationParameters(m);
 
-        assertNotNull(options.getNullableConfigValue("TEST", null));
-        assertEquals(testObject, options.getNullableConfigValue("TEST", null));
+        assertNotNull(options.getConfigValue("TEST", null, null));
+        assertNotNull(options.getConfigValue("TEST", null, TestObject.class));
+
+        assertEquals(testObject, options.getConfigValue("TEST", null, null));
+        assertEquals(testObject, options.getConfigValue("TEST", null, TestObject.class));
+
+        assertEquals(testObject, options.getConfigValue("TEST", testObject, null));
+        assertEquals(testObject, options.getConfigValue("TEST", testObject, TestObject.class));
+
+        assertEquals("t", options.getConfigValue("TEST", "defaultString", null));
+        assertEquals("t", options.getConfigValue("TEST", "defaultString", String.class));
+
+        assertEquals("1000", options.getConfigValue("String", null, null));
+        assertEquals("1000", options.getConfigValue("String", null, String.class));
+
+        assertEquals(int1000, options.getConfigValue("String", new Integer(10), null));
+        assertEquals(int1000, options.getConfigValue("String", new Integer(10), Integer.class));
+
+        assertEquals(new Long(1000), options.getConfigValue("String", new Long(10), null));
+        assertEquals(new Long(1000), options.getConfigValue("String", new Long(10), Long.class));
 
-        assertEquals(testObject, options.getNullableConfigValue("TEST", testObject));
-        assertEquals("t", options.getNullableConfigValue("TEST", "defaultString"));
+        assertEquals("1000", options.getConfigValue("String", "10", null));
+        assertEquals("1000", options.getConfigValue("String", "10", String.class));
 
-        assertEquals("1000", options.getNullableConfigValue("String", null));
-        assertEquals(int1000, options.getNullableConfigValue("String", new Integer(10)));
-        assertEquals(new Long(1000), options.getNullableConfigValue("String", new Long(10)));
-        assertEquals("1000", options.getNullableConfigValue("String", "10"));
-
-        assertEquals(int1000, options.getNullableConfigValue("Int2", null));
-        assertEquals(int1000, options.getNullableConfigValue("Int2", new Integer(10)));
-        assertEquals("1000", options.getNullableConfigValue("Int2", "1000"));
-
-        assertEquals(1000, options.getNullableConfigValue("Int3", null));
-        assertEquals(int1000, options.getNullableConfigValue("Int3", new Integer(10)));
-        assertEquals("1000", options.getNullableConfigValue("Int3", "1000"));
+        assertEquals(int1000, options.getConfigValue("Int2", null, null));
+        assertEquals(int1000, options.getConfigValue("Int2", new Integer(10), null));
+        assertEquals("1000", options.getConfigValue("Int2", "1000", null));
+
+        assertEquals(1000, options.getConfigValue("Int3", null, null));
+        assertEquals(int1000, options.getConfigValue("Int3", new Integer(10), null));
+        assertEquals("1000", options.getConfigValue("Int3", "1000", null));
+    }
+
+    @Test
+    public void testImpossibleConversion() {
+        Map<String, Object> map = new HashMap<String, Object>();
+        map.put("string", "v");
+        map.put("obj", new TestObject("test"));
+        map.put("int", new Integer(10));
+        ConfigurationParameters options = new ConfigurationParameters(map);
+
+        Map<String, Class> impossible = new HashMap();
+        impossible.put("string", TestObject.class);
+        impossible.put("string", Integer.class);
+        impossible.put("string", Calendar.class);
+        impossible.put("obj", Integer.class);
+        impossible.put("int", TestObject.class);
+        impossible.put("int", Calendar.class);
+
+        for (String key : impossible.keySet()) {
+            try {
+                options.getConfigValue(key, null, impossible.get(key));
+                fail("Impossible conversion for " + key + " to " + impossible.get(key));
+            } catch (IllegalArgumentException e) {
+                // success
+            }
+        }
     }
 
     @Test
@@ -194,11 +247,12 @@ public class ConfigurationParametersTest
     public void testNullValue2() {
         ConfigurationParameters options = new ConfigurationParameters(Collections.singletonMap("test", null));
 
-        assertNull(options.getNullableConfigValue("test", null));
-        assertNull(options.getNullableConfigValue("test", "value"));
-        assertNull(options.getNullableConfigValue("test", "value"));
-        assertNull(options.getNullableConfigValue("test", new TestObject("t")));
-        assertNull(options.getNullableConfigValue("test", false));
+        assertNull(options.getConfigValue("test", null, null));
+        assertNull(options.getConfigValue("test", null, TestObject.class));
+        assertNull(options.getConfigValue("test", "value", null));
+        assertNull(options.getConfigValue("test", "value", null));
+        assertNull(options.getConfigValue("test", new TestObject("t"), null));
+        assertNull(options.getConfigValue("test", false, null));
     }
 
     private class TestObject {

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/user/action/AccessControlActionTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/user/action/AccessControlActionTest.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/user/action/AccessControlActionTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/user/action/AccessControlActionTest.java Wed Sep 11 15:03:47 2013
@@ -45,9 +45,9 @@ public class AccessControlActionTest ext
 
     @Override
     protected ConfigurationParameters getSecurityConfigParameters() {
-        Map<String, String> map = new HashMap<String, String>();
-        map.put(AccessControlAction.GROUP_PRIVILEGE_NAMES, PrivilegeConstants.JCR_READ);
-        map.put(AccessControlAction.USER_PRIVILEGE_NAMES, PrivilegeConstants.JCR_ALL);
+        Map<String, String[]> map = new HashMap<String, String[]>();
+        map.put(AccessControlAction.GROUP_PRIVILEGE_NAMES, new String[] {PrivilegeConstants.JCR_READ});
+        map.put(AccessControlAction.USER_PRIVILEGE_NAMES, new String[] {PrivilegeConstants.JCR_ALL});
 
         ConfigurationParameters userConfig = new ConfigurationParameters(map);
         return new ConfigurationParameters(ImmutableMap.of(UserConfiguration.NAME, userConfig));

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/user/action/PasswordValidationActionTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/user/action/PasswordValidationActionTest.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/user/action/PasswordValidationActionTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/user/action/PasswordValidationActionTest.java Wed Sep 11 15:03:47 2013
@@ -17,12 +17,14 @@
 package org.apache.jackrabbit.oak.spi.security.user.action;
 
 import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import javax.annotation.Nonnull;
 import javax.jcr.RepositoryException;
 import javax.jcr.nodetype.ConstraintViolationException;
 
+import com.google.common.collect.ImmutableList;
 import org.apache.jackrabbit.api.security.user.User;
 import org.apache.jackrabbit.oak.AbstractSecurityTest;
 import org.apache.jackrabbit.oak.api.Root;
@@ -59,7 +61,8 @@ public class PasswordValidationActionTes
         user = (User) getUserManager(root).getAuthorizable(adminSession.getAuthInfo().getUserID());
 
         testAction.reset();
-        pwAction.setConstraint("^.*(?=.{8,})(?=.*[a-z])(?=.*[A-Z]).*");
+        pwAction.init(getSecurityProvider(), new ConfigurationParameters(
+                Collections.singletonMap(PasswordValidationAction.CONSTRAINT, "^.*(?=.{8,})(?=.*[a-z])(?=.*[A-Z]).*")));
 
     }
 
@@ -140,7 +143,7 @@ public class PasswordValidationActionTes
         testUser = getUserManager(root).createUser("testuser", "testPw123456");
         root.commit();
         try {
-            pwAction.setConstraint("abc");
+            pwAction.init(getSecurityProvider(), new ConfigurationParameters(Collections.singletonMap(PasswordValidationAction.CONSTRAINT, "abc")));
 
             String hashed = PasswordUtil.buildPasswordHash("abc");
             testUser.changePassword(hashed);
@@ -164,11 +167,6 @@ public class PasswordValidationActionTes
         }
 
         @Override
-        protected void init(SecurityProvider securityProvider, ConfigurationParameters config) {
-            // nothing to do
-        }
-
-        @Override
         public void onCreate(User user, String password, Root root, NamePathMapper namePathMapper) throws RepositoryException {
             onCreateCalled++;
         }
@@ -181,10 +179,15 @@ public class PasswordValidationActionTes
 
     private class TestSecurityProvider extends SecurityProviderImpl {
 
-        private final AuthorizableAction[] actions;
+        private final AuthorizableActionProvider actionProvider;
 
         private TestSecurityProvider() {
-            this.actions = new AuthorizableAction[]{pwAction, testAction};
+            actionProvider = new AuthorizableActionProvider() {
+                @Override
+                public List<? extends AuthorizableAction> getAuthorizableActions(@Nonnull SecurityProvider securityProvider) {
+                    return ImmutableList.of(pwAction, testAction);
+                }
+            };
         }
 
         public <T> T getConfiguration(Class<T> configClass) {
@@ -192,13 +195,9 @@ public class PasswordValidationActionTes
                 return (T) new UserConfigurationImpl(this) {
                     @Nonnull
                     @Override
-                    public AuthorizableActionProvider getAuthorizableActionProvider() {
-                        return new AuthorizableActionProvider() {
-                            @Override
-                            public List<AuthorizableAction> getAuthorizableActions() {
-                                return Arrays.asList(actions);
-                            }
-                        };
+                    public ConfigurationParameters getParameters() {
+                        Map<String, AuthorizableActionProvider> m = Collections.singletonMap(UserConstants.PARAM_AUTHORIZABLE_ACTION_PROVIDER, actionProvider);
+                        return ConfigurationParameters.newInstance(super.getParameters(), new ConfigurationParameters(m));
                     }
                 };
             } else {

Modified: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/UserImportWithActionsTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/UserImportWithActionsTest.java?rev=1521892&r1=1521891&r2=1521892&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/UserImportWithActionsTest.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/UserImportWithActionsTest.java Wed Sep 11 15:03:47 2013
@@ -25,7 +25,6 @@ import javax.jcr.security.AccessControlE
 import javax.jcr.security.AccessControlList;
 import javax.jcr.security.AccessControlManager;
 import javax.jcr.security.AccessControlPolicy;
-import javax.jcr.security.Privilege;
 
 import org.apache.jackrabbit.api.JackrabbitSession;
 import org.apache.jackrabbit.api.security.user.Authorizable;
@@ -33,6 +32,8 @@ import org.apache.jackrabbit.api.securit
 import org.apache.jackrabbit.api.security.user.User;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
 import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
 import org.apache.jackrabbit.oak.spi.security.user.action.AccessControlAction;
 import org.apache.jackrabbit.oak.spi.security.user.action.AuthorizableAction;
@@ -116,7 +117,7 @@ public class UserImportWithActionsTest e
 
     public void testAccessControlActionExecutionForUser() throws Exception {
         AccessControlAction a1 = new AccessControlAction();
-        a1.setUserPrivilegeNames(Privilege.JCR_ALL);
+        //a1.setUserPrivilegeNames(Privilege.JCR_ALL);
 
         setAuthorizableActions(a1);
 
@@ -152,7 +153,7 @@ public class UserImportWithActionsTest e
 
     public void testAccessControlActionExecutionForUser2() throws Exception {
         AccessControlAction a1 = new AccessControlAction();
-        a1.setUserPrivilegeNames(Privilege.JCR_ALL);
+        //a1.setUserPrivilegeNames(Privilege.JCR_ALL);
 
         setAuthorizableActions(a1);
 
@@ -188,7 +189,7 @@ public class UserImportWithActionsTest e
 
     public void testAccessControlActionExecutionForGroup() throws Exception {
         AccessControlAction a1 = new AccessControlAction();
-        a1.setGroupPrivilegeNames(Privilege.JCR_READ);
+        //a1.setGroupPrivilegeNames(Privilege.JCR_READ);
 
         setAuthorizableActions(a1);
 
@@ -236,6 +237,10 @@ public class UserImportWithActionsTest e
         private String pw;
 
         @Override
+        public void init(SecurityProvider securityProvider, ConfigurationParameters config) {
+        }
+
+        @Override
         public void onCreate(Group group, Root root, NamePathMapper namePathMapper) throws RepositoryException {
             id = group.getID();
         }