Index: oak-core/src/main/java/org/apache/jackrabbit/oak/security/SecurityProviderImpl.java =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/security/SecurityProviderImpl.java (revision 1701740) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/security/SecurityProviderImpl.java (working copy) @@ -36,6 +36,7 @@ import org.apache.jackrabbit.oak.security.authorization.AuthorizationConfigurationImpl; import org.apache.jackrabbit.oak.security.principal.PrincipalConfigurationImpl; import org.apache.jackrabbit.oak.security.privilege.PrivilegeConfigurationImpl; +import org.apache.jackrabbit.oak.security.user.RandomAuthorizableNodeName; import org.apache.jackrabbit.oak.security.user.UserConfigurationImpl; import org.apache.jackrabbit.oak.spi.security.ConfigurationBase; import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters; @@ -46,11 +47,15 @@ import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenConfiguration; import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration; import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants; +import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider; import org.apache.jackrabbit.oak.spi.security.principal.CompositePrincipalConfiguration; import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration; import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConfiguration; +import org.apache.jackrabbit.oak.spi.security.user.AuthorizableNodeName; +import org.apache.jackrabbit.oak.spi.security.user.UserAuthenticationFactory; 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.whiteboard.Whiteboard; import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardAuthorizableActionProvider; import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardAuthorizableNodeName; @@ -66,38 +71,35 @@ public class SecurityProviderImpl implements SecurityProvider, WhiteboardAware { @Reference - private volatile AuthorizationConfiguration authorizationConfiguration; + private AuthorizationConfiguration authorizationConfiguration; @Reference - private volatile AuthenticationConfiguration authenticationConfiguration; + private AuthenticationConfiguration authenticationConfiguration; @Reference - private volatile PrivilegeConfiguration privilegeConfiguration; + private PrivilegeConfiguration privilegeConfiguration; @Reference - private volatile UserConfiguration userConfiguration; + private UserConfiguration userConfiguration; - @Reference(referenceInterface = PrincipalConfiguration.class, - name = "principalConfiguration", - bind = "bindPrincipalConfiguration", - unbind = "unbindPrincipalConfiguration", - policy = ReferencePolicy.DYNAMIC, - cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE) - private final CompositePrincipalConfiguration principalConfiguration = new CompositePrincipalConfiguration(this); + @Reference + private PrincipalConfiguration principalConfiguration; - @Reference(referenceInterface = TokenConfiguration.class, - name = "tokenConfiguration", - bind = "bindTokenConfiguration", - unbind = "unbindTokenConfiguration", - policy = ReferencePolicy.DYNAMIC, - cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE) - private final CompositeTokenConfiguration tokenConfiguration = new CompositeTokenConfiguration(this); + @Reference + private TokenConfiguration tokenConfiguration; - private final WhiteboardAuthorizableNodeName authorizableNodeName = new WhiteboardAuthorizableNodeName(); - private final WhiteboardAuthorizableActionProvider authorizableActionProvider = new WhiteboardAuthorizableActionProvider(); - private final WhiteboardRestrictionProvider restrictionProvider = new WhiteboardRestrictionProvider(); - private final WhiteboardUserAuthenticationFactory userAuthenticationFactory = new WhiteboardUserAuthenticationFactory(UserConfigurationImpl.getDefaultAuthenticationFactory()); + @Reference + private AuthorizableNodeName authorizableNodeName; + @Reference + private AuthorizableActionProvider authorizableActionProvider; + + @Reference + private RestrictionProvider restrictionProvider; + + @Reference + private UserAuthenticationFactory userAuthenticationFactory; + private ConfigurationParameters configuration; private Whiteboard whiteboard; @@ -119,13 +121,45 @@ checkNotNull(configuration); this.configuration = configuration; - authenticationConfiguration = new AuthenticationConfigurationImpl(this); - authorizationConfiguration = new AuthorizationConfigurationImpl(this); - userConfiguration = new UserConfigurationImpl(this); - privilegeConfiguration = new PrivilegeConfigurationImpl(); + if (principalConfiguration == null) { + principalConfiguration = new PrincipalConfigurationImpl(this); + } - principalConfiguration.setDefaultConfig(new PrincipalConfigurationImpl(this)); - tokenConfiguration.setDefaultConfig(new TokenConfigurationImpl(this)); + if (tokenConfiguration == null) { + tokenConfiguration = new TokenConfigurationImpl(this); + } + + if (authorizableNodeName == null) { + authorizableNodeName = AuthorizableNodeName.DEFAULT; + } + + if (authorizableActionProvider == null) { + authorizableActionProvider = AuthorizableActionProvider.EMPTY; + } + + if (restrictionProvider == null) { + restrictionProvider = RestrictionProvider.EMPTY; + } + + if (userAuthenticationFactory == null) { + userAuthenticationFactory = UserConfigurationImpl.getDefaultAuthenticationFactory(); + } + + if (authenticationConfiguration == null) { + authenticationConfiguration = new AuthenticationConfigurationImpl(this); + } + + if (authorizationConfiguration == null) { + authorizationConfiguration = new AuthorizationConfigurationImpl(this); + } + + if (userConfiguration == null) { + userConfiguration = new UserConfigurationImpl(this); + } + + if (privilegeConfiguration == null) { + privilegeConfiguration = new PrivilegeConfigurationImpl(); + } } @Override @@ -191,43 +225,10 @@ @Activate protected void activate(BundleContext context) { whiteboard = new OsgiWhiteboard(context); - authorizableActionProvider.start(whiteboard); - authorizableNodeName.start(whiteboard); - restrictionProvider.start(whiteboard); - userAuthenticationFactory.start(whiteboard); - initializeConfigurations(); } - @Deactivate - protected void deactivate() { - authorizableActionProvider.stop(); - authorizableNodeName.stop(); - restrictionProvider.stop(); - userAuthenticationFactory.stop(); - } - @SuppressWarnings("UnusedDeclaration") - protected void bindPrincipalConfiguration(@Nonnull PrincipalConfiguration reference) { - principalConfiguration.addConfiguration(initConfiguration(reference)); - } - - @SuppressWarnings("UnusedDeclaration") - protected void unbindPrincipalConfiguration(@Nonnull PrincipalConfiguration reference) { - principalConfiguration.removeConfiguration(reference); - } - - @SuppressWarnings("UnusedDeclaration") - protected void bindTokenConfiguration(@Nonnull TokenConfiguration reference) { - tokenConfiguration.addConfiguration(initConfiguration(reference)); - } - - @SuppressWarnings("UnusedDeclaration") - protected void unbindTokenConfiguration(@Nonnull TokenConfiguration reference) { - tokenConfiguration.removeConfiguration(reference); - } - - @SuppressWarnings("UnusedDeclaration") protected void bindAuthorizationConfiguration(@Nonnull AuthorizationConfiguration reference) { authorizationConfiguration = initConfiguration(reference); // TODO (OAK-1268): authorizationConfiguration.addConfiguration(initConfiguration(reference)); @@ -252,7 +253,11 @@ initConfiguration(userConfiguration, ConfigurationParameters.of(userMap)); initConfiguration(authenticationConfiguration); + initConfiguration(authorizationConfiguration); + initConfiguration(userConfiguration); + initConfiguration(principalConfiguration); initConfiguration(privilegeConfiguration); + initConfiguration(tokenConfiguration); } private T initConfiguration(@Nonnull T config) { Index: oak-core/src/main/java/org/apache/jackrabbit/oak/security/package-info.java =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/security/package-info.java (revision 1701740) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/security/package-info.java (working copy) @@ -20,7 +20,7 @@ * * See README.md for more details. */ -@Version("1.0.1") +@Version("2.0.0") @Export(optional = "provide:=true") package org.apache.jackrabbit.oak.security; Index: oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/RandomAuthorizableNodeName.java =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/RandomAuthorizableNodeName.java (revision 1701740) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/RandomAuthorizableNodeName.java (working copy) @@ -33,7 +33,7 @@ * Implementation of the {@code AuthorizableNodeName} that generates a random * node name that doesn't reveal the ID of the authorizable. */ -@Component(metatype = true, label = "Apache Jackrabbit Oak Random Authorizable Node Name", description = "Generates a random name for the authorizable node.", policy = ConfigurationPolicy.REQUIRE) +@Component(metatype = true, label = "Apache Jackrabbit Oak Random Authorizable Node Name", description = "Generates a random name for the authorizable node.") @Service(AuthorizableNodeName.class) public class RandomAuthorizableNodeName implements AuthorizableNodeName { Index: oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AuthorizableActionProvider.java =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AuthorizableActionProvider.java (revision 1701740) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/AuthorizableActionProvider.java (working copy) @@ -16,14 +16,16 @@ */ package org.apache.jackrabbit.oak.spi.security.user.action; +import org.apache.jackrabbit.oak.spi.security.SecurityProvider; + +import javax.annotation.Nonnull; import java.util.List; -import javax.annotation.Nonnull; -import org.apache.jackrabbit.oak.spi.security.SecurityProvider; +import static java.util.Collections.emptyList; /** - * {@code AuthorizableActionProvider} is used to provide {@code AuthorizableAction}s - * for each instance of {@code UserManager}. + * {@code AuthorizableActionProvider} is used to provide {@code + * AuthorizableAction}s for each instance of {@code UserManager}. * * @since OAK 1.0 */ @@ -31,4 +33,19 @@ @Nonnull List getAuthorizableActions(@Nonnull SecurityProvider securityProvider); + + /** + * An implementation of {@code AuthorizableActionProvider} that returns an + * empty list of {@code AuthorizableAction}. + */ + AuthorizableActionProvider EMPTY = new AuthorizableActionProvider() { + + @Nonnull + @Override + public List getAuthorizableActions(@Nonnull SecurityProvider securityProvider) { + return emptyList(); + } + + }; + } \ No newline at end of file Index: oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/DefaultAuthorizableActionProvider.java =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/DefaultAuthorizableActionProvider.java (revision 1701740) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/DefaultAuthorizableActionProvider.java (working copy) @@ -16,6 +16,7 @@ */ package org.apache.jackrabbit.oak.spi.security.user.action; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -34,56 +35,39 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static com.google.common.collect.Lists.newArrayList; +import static java.util.Collections.unmodifiableList; + /** * Default implementation of the {@link AuthorizableActionProvider} interface * that allows to config all actions provided by the OAK. */ -@Component(metatype = true, label = "Apache Jackrabbit Oak AuthorizableActionProvider") -@Service(AuthorizableActionProvider.class) -@Properties({ - @Property(name = DefaultAuthorizableActionProvider.ENABLED_ACTIONS, - label = "Authorizable Actions", - description = "The set of actions that is supported by this provider implementation.", - cardinality = 4, - 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") - }), - @Property(name = AccessControlAction.USER_PRIVILEGE_NAMES, - label = "Configure AccessControlAction: User Privileges", - description = "The name of the privileges that should be granted to a given user on it's home.", - cardinality = Integer.MAX_VALUE), - @Property(name = AccessControlAction.GROUP_PRIVILEGE_NAMES, - label = "Configure AccessControlAction: Group Privileges", - description = "The name of the privileges that should be granted to a given group on it's home.", - cardinality = Integer.MAX_VALUE), - @Property(name = PasswordValidationAction.CONSTRAINT, - label = "Configure PasswordValidationAction: Password Constraint", - description = "A regular expression specifying the pattern that must be matched by a user's password.") -}) public class DefaultAuthorizableActionProvider implements AuthorizableActionProvider { private static final Logger log = LoggerFactory.getLogger(DefaultAuthorizableActionProvider.class); - static final String ENABLED_ACTIONS = "enabledActions"; + private final List enabledActions; - private String[] enabledActions = new String[] {AccessControlAction.class.getName()}; + private final ConfigurationParameters config; - private ConfigurationParameters config = ConfigurationParameters.EMPTY; + public DefaultAuthorizableActionProvider() { + this(ConfigurationParameters.EMPTY, newArrayList(AccessControlAction.class.getName())); + } - public DefaultAuthorizableActionProvider() {} + public DefaultAuthorizableActionProvider(ConfigurationParameters parameters) { + this(parameters, newArrayList(AccessControlAction.class.getName())); + } - public DefaultAuthorizableActionProvider(ConfigurationParameters config) { + public DefaultAuthorizableActionProvider(ConfigurationParameters config, List enabledActions) { this.config = config; + this.enabledActions = enabledActions; } //-----------------------------------------< AuthorizableActionProvider >--- @Nonnull @Override public List getAuthorizableActions(@Nonnull SecurityProvider securityProvider) { - List actions = Lists.newArrayList(); + List actions = newArrayList(); for (String className : enabledActions) { try { Object o = Class.forName(className).newInstance(); @@ -102,11 +86,4 @@ return actions; } - //----------------------------------------------------< SCR Integration >--- - @SuppressWarnings("UnusedDeclaration") - @Activate - private void activate(Map properties) { - config = ConfigurationParameters.of(properties); - enabledActions = PropertiesUtil.toStringArray(properties.get(ENABLED_ACTIONS), new String[0]); - } } \ No newline at end of file Index: oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/DefaultAuthorizableActionProviderRegistration.java =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/DefaultAuthorizableActionProviderRegistration.java (revision 0) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/DefaultAuthorizableActionProviderRegistration.java (working copy) @@ -0,0 +1,92 @@ +package org.apache.jackrabbit.oak.spi.security.user.action; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Properties; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.PropertyOption; +import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +import java.util.List; +import java.util.Map; + +import static com.google.common.collect.Lists.newArrayList; +import static org.apache.jackrabbit.oak.commons.PropertiesUtil.toBoolean; +import static org.apache.jackrabbit.oak.commons.PropertiesUtil.toStringArray; + +@Component( + immediate = true, + metatype = true, + label = "Apache Jackrabbit Oak AuthorizableActionProvider", + configurationPid = "org.apache.jackrabbit.oak.spi.security.user.action.DefaultAuthorizableActionProvider" +) +@Properties({ + @Property( + name = "enabledActions", + label = "Authorizable Actions", + description = "The set of actions that is supported by this provider implementation.", + cardinality = 4, + 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") + } + ), + @Property( + name = AccessControlAction.USER_PRIVILEGE_NAMES, + label = "Configure AccessControlAction: User Privileges", + description = "The name of the privileges that should be granted to a given user on it's home.", + cardinality = Integer.MAX_VALUE + ), + @Property( + name = AccessControlAction.GROUP_PRIVILEGE_NAMES, + label = "Configure AccessControlAction: Group Privileges", + description = "The name of the privileges that should be granted to a given group on it's home.", + cardinality = Integer.MAX_VALUE + ), + @Property( + name = PasswordValidationAction.CONSTRAINT, + label = "Configure PasswordValidationAction: Password Constraint", + description = "A regular expression specifying the pattern that must be matched by a user's password." + ), + @Property( + name = "enabled", + label = "Enabled", + description = "If checked, enable the registration of this component", + boolValue = true + ) +}) +public class DefaultAuthorizableActionProviderRegistration { + + private ServiceRegistration registration; + + @Activate + public void activate(BundleContext context, Map properties) { + boolean enabled = toBoolean(properties.get("enabled"), false); + + if (enabled) { + registration = context.registerService(AuthorizableActionProvider.class.getName(), createAuthorizableActionProvider(properties), null); + } + } + + @Deactivate + public void deactivate() { + if (registration != null) { + registration.unregister(); + registration = null; + } + } + + private DefaultAuthorizableActionProvider createAuthorizableActionProvider(Map properties) { + return new DefaultAuthorizableActionProvider(ConfigurationParameters.of(properties), getEnabledActions(properties)); + } + + private List getEnabledActions(Map properties) { + return newArrayList(toStringArray(properties.get("enabledActions"), new String[]{})); + } + +} Property changes on: oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/DefaultAuthorizableActionProviderRegistration.java ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/package-info.java =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/package-info.java (revision 1701740) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/action/package-info.java (working copy) @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -@Version("1.0.2") +@Version("1.1.0") @Export(optional = "provide:=true") package org.apache.jackrabbit.oak.spi.security.user.action; Index: oak-pojosr/src/test/resources/config-common/org.apache.jackrabbit.oak.spi.security.user.action.DefaultAuthorizableActionProvider.config =================================================================== --- oak-pojosr/src/test/resources/config-common/org.apache.jackrabbit.oak.spi.security.user.action.DefaultAuthorizableActionProvider.config (revision 1701740) +++ oak-pojosr/src/test/resources/config-common/org.apache.jackrabbit.oak.spi.security.user.action.DefaultAuthorizableActionProvider.config (working copy) @@ -1,3 +1,4 @@ enabledActions=["org.apache.jackrabbit.oak.spi.security.user.action.AccessControlAction"] userPrivilegeNames=["jcr:all"] -groupPrivilegeNames=["jcr:read"] \ No newline at end of file +groupPrivilegeNames=["jcr:read"] +enabled="false" \ No newline at end of file