Index: oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugSecurityProvider.java =================================================================== --- oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugSecurityProvider.java (revision 1704287) +++ oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugSecurityProvider.java (working copy) @@ -33,8 +33,12 @@ composite.setDefaultConfig(authorizationConfiguration); composite.addConfiguration(new CugConfiguration(this)); composite.addConfiguration(authorizationConfiguration); - setAuthorizationConfiguration(composite); + ((CugSecurityProvider) this).bindAuthorizationConfiguration(composite); } } + @Override + protected void bindAuthorizationConfiguration(@Nonnull AuthorizationConfiguration reference) { + super.bindAuthorizationConfiguration(reference); + } } \ No newline at end of file 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 1704287) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/security/SecurityProviderImpl.java (working copy) @@ -16,96 +16,118 @@ */ package org.apache.jackrabbit.oak.security; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.google.common.collect.ImmutableMap; +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.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.ReferencePolicy; +import org.apache.felix.scr.annotations.Service; +import org.apache.jackrabbit.oak.osgi.OsgiWhiteboard; import org.apache.jackrabbit.oak.security.authentication.AuthenticationConfigurationImpl; import org.apache.jackrabbit.oak.security.authentication.token.TokenConfigurationImpl; 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.UserConfigurationImpl; +import org.apache.jackrabbit.oak.spi.security.ConfigurationBase; import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters; import org.apache.jackrabbit.oak.spi.security.SecurityConfiguration; import org.apache.jackrabbit.oak.spi.security.SecurityProvider; import org.apache.jackrabbit.oak.spi.security.authentication.AuthenticationConfiguration; +import org.apache.jackrabbit.oak.spi.security.authentication.token.CompositeTokenConfiguration; 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.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.UserConfiguration; +import org.apache.jackrabbit.oak.spi.security.user.UserConstants; import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard; +import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardAuthorizableActionProvider; +import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardAuthorizableNodeName; import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardAware; +import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardRestrictionProvider; +import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardUserAuthenticationFactory; +import org.osgi.framework.BundleContext; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.Sets.newHashSet; +@Component +@Service(value = {SecurityProvider.class}) public class SecurityProviderImpl implements SecurityProvider, WhiteboardAware { - private AuthenticationConfiguration authenticationConfiguration; + @Reference + private volatile AuthorizationConfiguration authorizationConfiguration; - private AuthorizationConfiguration authorizationConfiguration; + @Reference + private volatile AuthenticationConfiguration authenticationConfiguration; - private UserConfiguration userConfiguration; + @Reference + private volatile PrivilegeConfiguration privilegeConfiguration; - private PrincipalConfiguration principalConfiguration; + @Reference + private volatile UserConfiguration userConfiguration; - private PrivilegeConfiguration privilegeConfiguration; + @Reference(referenceInterface = PrincipalConfiguration.class, + name = "principalConfiguration", + bind = "bindPrincipalConfiguration", + unbind = "unbindPrincipalConfiguration", + policy = ReferencePolicy.DYNAMIC, + cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE) + private final CompositePrincipalConfiguration principalConfiguration = new CompositePrincipalConfiguration(this); - private TokenConfiguration tokenConfiguration; + @Reference(referenceInterface = TokenConfiguration.class, + name = "tokenConfiguration", + bind = "bindTokenConfiguration", + unbind = "unbindTokenConfiguration", + policy = ReferencePolicy.DYNAMIC, + cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE) + private final CompositeTokenConfiguration tokenConfiguration = new CompositeTokenConfiguration(this); + 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()); + private ConfigurationParameters configuration; private Whiteboard whiteboard; /** - * Default constructor using an empty configuration and default - * implementations for the security configurations. + * Default constructor used in OSGi environments. */ public SecurityProviderImpl() { this(ConfigurationParameters.EMPTY); } /** - * Create a new {@code SecurityProvider} instance with the given - * configuration parameters. + * Create a new {@code SecurityProvider} instance with the given configuration + * parameters. * * @param configuration security configuration */ public SecurityProviderImpl(@Nonnull ConfigurationParameters configuration) { - this.configuration = checkNotNull(configuration); - this.authenticationConfiguration = new AuthenticationConfigurationImpl(this); - this.authorizationConfiguration = new AuthorizationConfigurationImpl(this); - this.userConfiguration = new UserConfigurationImpl(this); - this.principalConfiguration = new PrincipalConfigurationImpl(this); - this.privilegeConfiguration = new PrivilegeConfigurationImpl(); - this.tokenConfiguration = new TokenConfigurationImpl(this); - } + checkNotNull(configuration); + this.configuration = configuration; - public void setAuthenticationConfiguration(AuthenticationConfiguration authenticationConfiguration) { - this.authenticationConfiguration = checkNotNull(authenticationConfiguration); - } + authenticationConfiguration = new AuthenticationConfigurationImpl(this); + authorizationConfiguration = new AuthorizationConfigurationImpl(this); + userConfiguration = new UserConfigurationImpl(this); + privilegeConfiguration = new PrivilegeConfigurationImpl(); - public void setAuthorizationConfiguration(AuthorizationConfiguration authorizationConfiguration) { - this.authorizationConfiguration = authorizationConfiguration; + principalConfiguration.setDefaultConfig(new PrincipalConfigurationImpl(this)); + tokenConfiguration.setDefaultConfig(new TokenConfigurationImpl(this)); } - public void setUserConfiguration(UserConfiguration userConfiguration) { - this.userConfiguration = userConfiguration; - } - - public void setPrincipalConfiguration(PrincipalConfiguration principalConfiguration) { - this.principalConfiguration = principalConfiguration; - } - - public void setPrivilegeConfiguration(PrivilegeConfiguration privilegeConfiguration) { - this.privilegeConfiguration = privilegeConfiguration; - } - - public void setTokenConfiguration(TokenConfiguration tokenConfiguration) { - this.tokenConfiguration = tokenConfiguration; - } - @Override public void setWhiteboard(@Nonnull Whiteboard whiteboard) { this.whiteboard = whiteboard; @@ -122,9 +144,7 @@ if (name == null) { return configuration; } - ConfigurationParameters params = configuration.getConfigValue(name, ConfigurationParameters.EMPTY); - for (SecurityConfiguration sc : getConfigurations()) { if (sc != null && sc.getName().equals(name)) { return ConfigurationParameters.of(params, sc.getParameters()); @@ -136,14 +156,14 @@ @Nonnull @Override public Iterable getConfigurations() { - return newHashSet( - authenticationConfiguration, - authorizationConfiguration, - userConfiguration, - principalConfiguration, - privilegeConfiguration, - tokenConfiguration - ); + Set scs = new HashSet(); + scs.add(authenticationConfiguration); + scs.add(authorizationConfiguration); + scs.add(userConfiguration); + scs.add(principalConfiguration); + scs.add(privilegeConfiguration); + scs.add(tokenConfiguration); + return scs; } @SuppressWarnings("unchecked") @@ -167,4 +187,89 @@ } } + //----------------------------------------------------------------< SCR >--- + @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)); + } + + @SuppressWarnings("UnusedDeclaration") + protected void unbindAuthorizationConfiguration(@Nonnull AuthorizationConfiguration reference) { + authorizationConfiguration = new AuthorizationConfigurationImpl(this); + // TODO (OAK-1268): authorizationConfiguration.removeConfiguration(reference); + } + + //------------------------------------------------------------< private >--- + private void initializeConfigurations() { + initConfiguration(authorizationConfiguration, ConfigurationParameters.of( + AccessControlConstants.PARAM_RESTRICTION_PROVIDER, restrictionProvider) + ); + + Map userMap = ImmutableMap.of( + UserConstants.PARAM_AUTHORIZABLE_ACTION_PROVIDER, authorizableActionProvider, + UserConstants.PARAM_AUTHORIZABLE_NODE_NAME, authorizableNodeName, + UserConstants.PARAM_USER_AUTHENTICATION_FACTORY, userAuthenticationFactory); + initConfiguration(userConfiguration, ConfigurationParameters.of(userMap)); + + initConfiguration(authenticationConfiguration); + initConfiguration(privilegeConfiguration); + } + + private T initConfiguration(@Nonnull T config) { + if (config instanceof ConfigurationBase) { + ConfigurationBase cfg = (ConfigurationBase) config; + cfg.setSecurityProvider(this); + cfg.setParameters(ConfigurationParameters.of(ConfigurationParameters.EMPTY, cfg.getParameters())); + } + return config; + } + + private T initConfiguration(@Nonnull T config, @Nonnull ConfigurationParameters params) { + if (config instanceof ConfigurationBase) { + ConfigurationBase cfg = (ConfigurationBase) config; + cfg.setSecurityProvider(this); + cfg.setParameters(ConfigurationParameters.of(params, cfg.getParameters())); + } + return config; + } } Index: oak-core/src/main/java/org/apache/jackrabbit/oak/security/internal/InternalSecurityProvider.java =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/security/internal/InternalSecurityProvider.java (revision 0) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/security/internal/InternalSecurityProvider.java (working copy) @@ -0,0 +1,170 @@ +/* + * 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.security.internal; + +import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters; +import org.apache.jackrabbit.oak.spi.security.SecurityConfiguration; +import org.apache.jackrabbit.oak.spi.security.SecurityProvider; +import org.apache.jackrabbit.oak.spi.security.authentication.AuthenticationConfiguration; +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.principal.PrincipalConfiguration; +import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConfiguration; +import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration; +import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard; +import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardAware; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import static com.google.common.collect.Sets.newHashSet; + +class InternalSecurityProvider implements SecurityProvider, WhiteboardAware { + + private AuthenticationConfiguration authenticationConfiguration; + + private AuthorizationConfiguration authorizationConfiguration; + + private UserConfiguration userConfiguration; + + private PrivilegeConfiguration privilegeConfiguration; + + private PrincipalConfiguration principalConfiguration; + + private TokenConfiguration tokenConfiguration; + + private Whiteboard whiteboard; + + @Nonnull + @Override + public ConfigurationParameters getParameters(@Nullable String name) { + SecurityConfiguration securityConfiguration = getSecurityConfigurationByName(name); + + if (securityConfiguration == null) { + return ConfigurationParameters.EMPTY; + } + + return securityConfiguration.getParameters(); + } + + private SecurityConfiguration getSecurityConfigurationByName(String name) { + if (AuthenticationConfiguration.NAME.equals(name)) { + return authenticationConfiguration; + } + + if (AuthorizationConfiguration.NAME.equals(name)) { + return authorizationConfiguration; + } + + if (UserConfiguration.NAME.equals(name)) { + return userConfiguration; + } + + if (PrivilegeConfiguration.NAME.equals(name)) { + return privilegeConfiguration; + } + + if (PrincipalConfiguration.NAME.equals(name)) { + return principalConfiguration; + } + + if (TokenConfiguration.NAME.equals(name)) { + return tokenConfiguration; + } + + return null; + } + + @Nonnull + @Override + public Iterable getConfigurations() { + return newHashSet( + authenticationConfiguration, + authorizationConfiguration, + userConfiguration, + privilegeConfiguration, + principalConfiguration, + tokenConfiguration + ); + } + + @Nonnull + @Override + @SuppressWarnings("unchecked") + public T getConfiguration(@Nonnull Class configurationClass) { + if (configurationClass == AuthenticationConfiguration.class) { + return (T) authenticationConfiguration; + } + + if (configurationClass == AuthorizationConfiguration.class) { + return (T) authorizationConfiguration; + } + + if (configurationClass == UserConfiguration.class) { + return (T) userConfiguration; + } + + if (configurationClass == PrivilegeConfiguration.class) { + return (T) privilegeConfiguration; + } + + if (configurationClass == PrincipalConfiguration.class) { + return (T) principalConfiguration; + } + + if (configurationClass == TokenConfiguration.class) { + return (T) tokenConfiguration; + } + + throw new IllegalArgumentException("Unsupported security configuration class " + configurationClass); + } + + @Override + public void setWhiteboard(@Nonnull Whiteboard whiteboard) { + this.whiteboard = whiteboard; + } + + @Override + public Whiteboard getWhiteboard() { + return whiteboard; + } + + public void setAuthenticationConfiguration(AuthenticationConfiguration authenticationConfiguration) { + this.authenticationConfiguration = authenticationConfiguration; + } + + public void setAuthorizationConfiguration(AuthorizationConfiguration authorizationConfiguration) { + this.authorizationConfiguration = authorizationConfiguration; + } + + public void setUserConfiguration(UserConfiguration userConfiguration) { + this.userConfiguration = userConfiguration; + } + + public void setPrivilegeConfiguration(PrivilegeConfiguration privilegeConfiguration) { + this.privilegeConfiguration = privilegeConfiguration; + } + + public void setPrincipalConfiguration(PrincipalConfiguration principalConfiguration) { + this.principalConfiguration = principalConfiguration; + } + + public void setTokenConfiguration(TokenConfiguration tokenConfiguration) { + this.tokenConfiguration = tokenConfiguration; + } + +} Property changes on: oak-core/src/main/java/org/apache/jackrabbit/oak/security/internal/InternalSecurityProvider.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/security/internal/SecurityProviderRegistration.java =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistration.java (revision 1704287) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/security/internal/SecurityProviderRegistration.java (working copy) @@ -29,7 +29,6 @@ import org.apache.felix.scr.annotations.References; import org.apache.jackrabbit.oak.commons.PropertiesUtil; import org.apache.jackrabbit.oak.osgi.OsgiWhiteboard; -import org.apache.jackrabbit.oak.security.SecurityProviderImpl; import org.apache.jackrabbit.oak.security.user.UserConfigurationImpl; import org.apache.jackrabbit.oak.spi.security.ConfigurationBase; import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters; @@ -60,6 +59,8 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; +import java.util.Dictionary; +import java.util.Hashtable; import java.util.List; import java.util.Map; @@ -417,10 +418,15 @@ // Register the SecurityProvider. + + Dictionary properties = new Hashtable(); + + properties.put("type", "default"); + ServiceRegistration registration = context.registerService( SecurityProvider.class.getName(), createSecurityProvider(context), - null + properties ); synchronized (this) { @@ -465,7 +471,7 @@ } private SecurityProvider createSecurityProvider(BundleContext context) { - SecurityProviderImpl securityProvider = new SecurityProviderImpl(); + InternalSecurityProvider securityProvider = new InternalSecurityProvider(); // Static, mandatory references 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 1704287) +++ 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("2.0.0") +@Version("1.0.1") @Export(optional = "provide:=true") package org.apache.jackrabbit.oak.security; Index: oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/osgi/RepositoryManager.java =================================================================== --- oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/osgi/RepositoryManager.java (revision 1704287) +++ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/osgi/RepositoryManager.java (working copy) @@ -85,7 +85,7 @@ private boolean fastQueryResultSize; - @Reference + @Reference(target = "(type=default)") private SecurityProvider securityProvider; @Reference Index: oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/SecurityProviderRegistrationTest.groovy =================================================================== --- oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/SecurityProviderRegistrationTest.groovy (revision 1704287) +++ oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/SecurityProviderRegistrationTest.groovy (working copy) @@ -160,7 +160,7 @@ } private ServiceReference[] getSecurityProviderServiceReferences() { - return registry.getServiceReferences(SecurityProvider.class.name, null) + return registry.getServiceReferences(SecurityProvider.class.name, "(type=default)") } private void setRequiredServicePids(String... pids) {