You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2009/10/22 19:26:39 UTC
svn commit: r828791 [1/8] - in /jackrabbit/trunk:
jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/user/
jackrabbit-core/src/main/java/org/apache/jackrabbit/core/
jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/ jackrabbi...
Author: angela
Date: Thu Oct 22 17:26:37 2009
New Revision: 828791
URL: http://svn.apache.org/viewvc?rev=828791&view=rev
Log:
JCR-2313 - Improvements to user management (2) [work in progress]
-> see issue for details
JCR-2333 - ItemImpl#validateTransientItems: Incomplete validation of mandatory child item
-> patch2
JCR-2195 - Provide possibility to import protected items using Session/Workspace import functionality
-> deal with reference properties
-> make import handlers configurable
-> add userimporter
JCR-171 - Make the extraction of Session UserIDs from Subjects configurable
-> extend SecurityManagerConfig and retrieve uid from principal name if configured
class is present in the subject
JCR-2351 - Make Authorizable.setProperty more noisy in case of failure
JCR-2331 - Configurable DefaultPolicy replacing Initialization within the ACProvider
-> initial steps. remove code that relies on the default-init
-> add TODOs
JCR-2291 - Issues with compiled permissions of ACL provider
-> remove code searching for DENY-read entries in case of default initialization of ac entries
and here and there minor improvement, usage of generics etc....
Added:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/UserPerWorkspaceSecurityManager.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/ImportConfig.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/UserManagerConfig.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImporter.java (contents, props changed)
- copied, changed from r818472, jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/AccessControlImporter.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserPerWorkspaceUserManager.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/UserPerWorkspaceSecurityManagerTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/NodeCreationTest.java
- copied, changed from r818472, jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/IdResolverTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImporterTest.java
Removed:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlEntryIterator.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/IdResolverTest.java
Modified:
jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/user/UserManager.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/DefaultSecurityManager.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SystemSession.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/SecurityManagerConfig.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/WorkspaceConfig.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/JackrabbitSecurityManager.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/WorkspaceAccessManager.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplate.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/combined/CombinedProvider.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/DefaultPrincipalProvider.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/ProviderRegistryImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleSecurityManager.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleWorkspaceAccessManager.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/AuthorizableImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/GroupImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/ImpersonationImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserConstants.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/ReferenceChangeTracker.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/AccessControlImporter.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/DefaultProtectedNodeImporter.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/DefaultProtectedPropertyImporter.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/ProtectedNodeImporter.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/ProtectedPropertyImporter.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/SessionImporter.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java
jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.cnd
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/AbstractUserTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/AuthorizableTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/GroupTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/ImpersonationTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/NestedGroupTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/UserManagerCreateGroupTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/UserManagerCreateUserTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/UserManagerTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/user/UserTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/NodeImplTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestAll.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/config/SecurityConfigTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/config/WorkspaceConfigTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractEvaluationTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractVersionManagementTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractWriteTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/WriteTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/combined/WriteTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/principalbased/WriteTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/principal/DefaultPrincipalProviderTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/AdministratorTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/AuthorizableImplTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/GroupAdministratorTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/ImpersonationImplTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/IndexNodeResolverTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/NodeResolverTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/NotUserAdministratorTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/TestAll.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/TraversingNodeResolverTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserAdministratorTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImplTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserManagerImplTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/xml/AccessControlImporterTest.java
Modified: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/user/UserManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/user/UserManager.java?rev=828791&r1=828790&r2=828791&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/user/UserManager.java (original)
+++ jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/user/UserManager.java Thu Oct 22 17:26:37 2009
@@ -17,6 +17,7 @@
package org.apache.jackrabbit.api.security.user;
import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
import java.security.Principal;
import java.util.Iterator;
@@ -49,9 +50,9 @@
/**
* Get the Authorizable by its id.
*
- * @param id
+ * @param id The user or group id.
* @return Authorizable or <code>null</code>, if not present.
- * @throws RepositoryException
+ * @throws RepositoryException If an error occurs.
* @see Authorizable#getID()
*/
Authorizable getAuthorizable(String id) throws RepositoryException;
@@ -61,7 +62,7 @@
*
* @param principal
* @return Authorizable or <code>null</code>, if not present.
- * @throws RepositoryException
+ * @throws RepositoryException If an error occurs.
*/
Authorizable getAuthorizable(Principal principal) throws RepositoryException;
@@ -74,10 +75,10 @@
* @param value
* @return All <code>Authorizable</code>s that have a property with the given
* name exactly matching the given value.
- * @throws RepositoryException
+ * @throws RepositoryException If an error occurs.
* @see Authorizable#getProperty(String)
*/
- Iterator findAuthorizables(String propertyName, String value) throws RepositoryException;
+ Iterator<Authorizable> findAuthorizables(String propertyName, String value) throws RepositoryException;
/**
* Returns all <code>Authorizable</code>s that have
@@ -94,10 +95,10 @@
* <li>{@link #SEARCH_TYPE_GROUP}</li>
* <li>{@link #SEARCH_TYPE_USER}</li>
* </ul>
- * @return
- * @throws RepositoryException
+ * @return An iterator of <code>Authorizable</code>.
+ * @throws RepositoryException If an error occurs.
*/
- Iterator findAuthorizables(String propertyName, String value, int searchType) throws RepositoryException;
+ Iterator<Authorizable> findAuthorizables(String propertyName, String value, int searchType) throws RepositoryException;
/**
* Creates an User for the given userID / password pair; neither of the
@@ -106,7 +107,7 @@
* the specified userID is equal to the principal name and the intermediate
* path is <code>null</code>.
*
- * @param userID
+ * @param userID The id of the new user.
* @param password The initial password of this user.
* @return The new <code>User</code>.
* @throws AuthorizableExistsException in case the given userID is already
@@ -163,4 +164,35 @@
* @throws RepositoryException If another error occurs.
*/
Group createGroup(Principal principal, String intermediatePath) throws AuthorizableExistsException, RepositoryException;
+
+ /**
+ * If any write operations executed through the User API are automatically
+ * persisted this method returns <code>true</code>. In this case there are
+ * no pending transient changes left and there is no need to explicitely call
+ * {@link javax.jcr.Session#save()}. If this method returns <code>false</code>
+ * any changes must be completed by an extra save call on the
+ * <code>Session</code> associated with this <code>UserManager</code>.
+ *
+ * @return <code>true</code> if changes are automatically persisted;
+ * <code>false</code> if changes made through this API (including method
+ * calls on {@link Authorizable} and subclasses are only transient and
+ * must be persisted using {@link javax.jcr.Session#save()}.
+ * @see #autoSave(boolean)
+ */
+ boolean isAutoSave();
+
+ /**
+ * Changes the auto save behavior of this <code>UserManager</code>.
+ * <p/>
+ * Note, that this shouldn't be allowed in cases where the associated session
+ * is different from the original session accessing the user manager.
+ *
+ * @param enable If <code>true</code> changes made through this API will
+ * be automatically saved; otherwise an explict call to
+ * {@link javax.jcr.Session#save()} is required in order to persist changes.
+ * @throws UnsupportedRepositoryOperationException If the implementation
+ * does not allow to change the auto save behavior.
+ * @throws RepositoryException If some other error occurs.
+ */
+ void autoSave(boolean enable) throws UnsupportedRepositoryOperationException, RepositoryException;
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/DefaultSecurityManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/DefaultSecurityManager.java?rev=828791&r1=828790&r2=828791&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/DefaultSecurityManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/DefaultSecurityManager.java Thu Oct 22 17:26:37 2009
@@ -37,13 +37,14 @@
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.core.config.AccessManagerConfig;
-import org.apache.jackrabbit.core.config.BeanConfig;
import org.apache.jackrabbit.core.config.LoginModuleConfig;
import org.apache.jackrabbit.core.config.SecurityConfig;
import org.apache.jackrabbit.core.config.SecurityManagerConfig;
import org.apache.jackrabbit.core.config.WorkspaceConfig;
import org.apache.jackrabbit.core.config.WorkspaceSecurityConfig;
+import org.apache.jackrabbit.core.config.UserManagerConfig;
import org.apache.jackrabbit.core.security.AMContext;
import org.apache.jackrabbit.core.security.AccessManager;
import org.apache.jackrabbit.core.security.DefaultAccessManager;
@@ -94,9 +95,9 @@
private RepositoryImpl repository;
/**
- * session on the system workspace.
+ * System session.
*/
- private SystemSession securitySession;
+ private SystemSession systemSession;
/**
* System user manager. Implementation needed here for the DefaultPrincipalProvider.
@@ -104,11 +105,6 @@
private UserManager systemUserManager;
/**
- * System Sessions PrincipalMangager used for internal access to Principals
- */
- private PrincipalManager systemPrincipalManager;
-
- /**
* The user id of the administrator. The value is retrieved from
* configuration. If the config entry is missing a default id is used (see
* {@link SecurityConstants#ADMIN_ID}).
@@ -120,7 +116,7 @@
* configuration. If the config entry is missing a default id is used (see
* {@link SecurityConstants#ANONYMOUS_ID}).
*/
- private String anonymousId;
+ protected String anonymousId;
/**
* Contains the access control providers per workspace.
@@ -164,7 +160,7 @@
throw new RepositoryException("SystemSession expected");
}
- securitySession = (SystemSession) systemSession;
+ this.systemSession = (SystemSession) systemSession;
this.repository = (RepositoryImpl) repository;
SecurityConfig config = this.repository.getConfig().getSecurityConfig();
@@ -204,12 +200,12 @@
}
// create the system userManager and make sure the system-users exist.
- systemUserManager = createUserManager(securitySession);
- createSystemUsers(systemUserManager, adminId, anonymousId);
+ systemUserManager = createUserManager(this.systemSession);
+ createSystemUsers(systemUserManager, this.systemSession, adminId, anonymousId);
// init default ac-provider-factory
acProviderFactory = new AccessControlProviderFactoryImpl();
- acProviderFactory.init(securitySession);
+ acProviderFactory.init(this.systemSession);
// create the workspace access manager
SecurityManagerConfig smc = config.getSecurityManagerConfig();
@@ -218,14 +214,13 @@
} else {
// fallback -> the default implementation
log.debug("No WorkspaceAccessManager configured; using default.");
- workspaceAccessManager = new WorkspaceAccessManagerImpl();
+ workspaceAccessManager = createDefaultWorkspaceAccessManager();
}
- workspaceAccessManager.init(securitySession);
+ workspaceAccessManager.init(this.systemSession);
// initialize principal-provider registry
// 1) create default
- PrincipalProvider defaultPP = new DefaultPrincipalProvider(securitySession, (UserManagerImpl) systemUserManager);
- defaultPP.init(new Properties());
+ PrincipalProvider defaultPP = createDefaultPrincipalProvider();
// 2) create registry instance
principalProviderRegistry = new ProviderRegistryImpl(defaultPP);
// 3) register all configured principal providers.
@@ -233,35 +228,10 @@
principalProviderRegistry.registerProvider(props);
}
- // create the principal manager for the security workspace
- systemPrincipalManager = new PrincipalManagerImpl(securitySession, principalProviderRegistry.getProviders());
-
initialized = true;
}
/**
- * Creates a {@link UserManagerImpl} for the given session. May be overridden
- * to return a custom implementation.
- *
- * @param session session
- * @return user manager
- * @throws RepositoryException if an error occurs
- */
- protected UserManagerImpl createUserManager(SessionImpl session) throws RepositoryException {
- BeanConfig umc = repository.getConfig().getSecurityConfig().getSecurityManagerConfig().getUserManagerConfig();
- Properties config = null;
- if (umc != null) {
- // TODO: deal with other user manager implementations.
- String clName = umc.getClassName();
- if (clName != null && !(UserManagerImpl.class.getName().equals(clName) || clName.length() == 0)) {
- log.warn("Unsupported custom UserManager implementation: '" + clName + "' -> Ignored.");
- }
- config = umc.getParameters();
- }
- return new UserManagerImpl(session, adminId, config);
- }
-
- /**
* @see JackrabbitSecurityManager#dispose(String)
*/
public void dispose(String workspaceName) {
@@ -323,11 +293,9 @@
*/
public PrincipalManager getPrincipalManager(Session session) throws RepositoryException {
checkInitialized();
- if (session == securitySession) {
- return systemPrincipalManager;
- } else if (session instanceof SessionImpl) {
+ if (session instanceof SessionImpl) {
SessionImpl sImpl = (SessionImpl) session;
- return new PrincipalManagerImpl(sImpl, principalProviderRegistry.getProviders());
+ return createPrincipalManager(sImpl);
} else {
throw new RepositoryException("Internal error: SessionImpl expected.");
}
@@ -338,10 +306,10 @@
*/
public UserManager getUserManager(Session session) throws RepositoryException {
checkInitialized();
- if (session == securitySession) {
+ if (session == systemSession) {
return systemUserManager;
} else if (session instanceof SessionImpl) {
- String workspaceName = securitySession.getWorkspace().getName();
+ String workspaceName = systemSession.getWorkspace().getName();
try {
SessionImpl sImpl = (SessionImpl) session;
UserManagerImpl uMgr;
@@ -362,63 +330,212 @@
}
/**
- * @see JackrabbitSecurityManager#getUserID(Subject)
+ * @see JackrabbitSecurityManager#getUserID(javax.security.auth.Subject, String)
*/
- public String getUserID(Subject subject) throws RepositoryException {
+ public String getUserID(Subject subject, String workspaceName) throws RepositoryException {
checkInitialized();
+
/* shortcut if the subject contains the AdminPrincipal in which case
the userID is already known. */
if (!subject.getPrincipals(AdminPrincipal.class).isEmpty()) {
return adminId;
}
+ /* if there is a configure principal class that should be used to
+ determine the UserID -> try this one. */
+ Class cl = getConfig().getUserIdClass();
+ if (cl != null) {
+ Set<Principal> s = subject.getPrincipals(cl);
+ if (!s.isEmpty()) {
+ for (Principal p : s) {
+ if (!(p instanceof java.security.acl.Group)) {
+ return p.getName();
+ }
+ }
+ // all principals found with the given p-Class were Group principals
+ log.debug("Only Group principals found with class '" + cl.getName() + "' -> Not used for UserID.");
+ } else {
+ log.debug("No principal found with class '" + cl.getName() + "'.");
+ }
+ }
+
/*
- Retrieve userID from the subject.
+ Fallback szenario to retrieve userID from the subject:
Since the subject may contain multiple principals and the principal
- name must not be equals to the UserID by definition, the userID
- may either be obtained from the login-credentials or from the
- user manager. in the latter case the set of principals present with
- the specified subject is used to search for the user.
+ name may not be equals to the UserID, the id is retrieved by
+ searching for the corresponding authorizable and if this doesn't
+ succeed an attempt is made to obtained it from the login-credentials.
*/
String uid = null;
- // try simple access to userID over SimpleCredentials first.
- Iterator<SimpleCredentials> creds = subject.getPublicCredentials(
- SimpleCredentials.class).iterator();
- if (creds.hasNext()) {
- SimpleCredentials sc = creds.next();
- uid = sc.getUserID();
- } else {
- // no SimpleCredentials: retrieve authorizables corresponding to
- // a non-group principal. the first one present is used to determine
- // the userID.
+
+ // first try to retrieve an authorizable corresponding to
+ // a non-group principal. the first one present is used
+ // to determine the userID.
+ try {
+ UserManager umgr = getSystemUserManager(workspaceName);
for (Principal p : subject.getPrincipals()) {
if (!(p instanceof Group)) {
- Authorizable authorz = systemUserManager.getAuthorizable(p);
+ Authorizable authorz = umgr.getAuthorizable(p);
if (authorz != null && !authorz.isGroup()) {
uid = authorz.getID();
break;
}
}
}
+ } catch (RepositoryException e) {
+ // failed to access userid via user manager -> use fallback 2.
+ log.error("Unexpected error while retrieving UserID.", e);
+ }
+
+ // 2. if no matching user is found try simple access to userID over
+ // SimpleCredentials.
+ if (uid == null) {
+ Iterator<SimpleCredentials> creds = subject.getPublicCredentials(
+ SimpleCredentials.class).iterator();
+ if (creds.hasNext()) {
+ SimpleCredentials sc = creds.next();
+ uid = sc.getUserID();
+ }
}
+
return uid;
}
/**
* Creates an AuthContext for the given {@link Credentials} and
- * {@link Subject}.<br>
+ * {@link Subject}. The workspace name is ignored and users are
+ * stored and retrieved from a specific (separate) workspace.<br>
* This includes selection of application specific LoginModules and
* initialization with credentials and Session to System-Workspace
*
* @return an {@link AuthContext} for the given Credentials, Subject
* @throws RepositoryException in other exceptional repository states
*/
- public AuthContext getAuthContext(Credentials creds, Subject subject)
+ public AuthContext getAuthContext(Credentials creds, Subject subject, String workspaceName)
throws RepositoryException {
checkInitialized();
- return authContextProvider.getAuthContext(creds, subject, securitySession,
- principalProviderRegistry, adminId, anonymousId);
+ return getAuthContextProvider().getAuthContext(creds, subject, systemSession,
+ getPrincipalProviderRegistry(), adminId, anonymousId);
+ }
+
+ //----------------------------------------------------------< protected >---
+ /**
+ * @return The <code>SecurityManagerConfig</code> configured for the
+ * repository this manager has been created for.
+ */
+ protected SecurityManagerConfig getConfig() {
+ return repository.getConfig().getSecurityConfig().getSecurityManagerConfig();
+ }
+
+ /**
+ * @param workspaceName
+ * @return The system user manager. Since this implementation stores users
+ * in a dedicated workspace the system user manager is the same for all
+ * sessions irrespective of the workspace.
+ */
+ protected UserManager getSystemUserManager(String workspaceName) throws RepositoryException {
+ return systemUserManager;
}
+ /**
+ * Creates a {@link UserManagerImpl} for the given session. May be overridden
+ * to return a custom implementation.
+ *
+ * @param session session
+ * @return user manager
+ * @throws RepositoryException if an error occurs
+ */
+ protected UserManagerImpl createUserManager(SessionImpl session) throws RepositoryException {
+ UserManagerConfig umc = getConfig().getUserManagerConfig();
+ Properties params = (umc == null) ? null : umc.getParameters();
+
+ // since users are stored in and retrieved from a dedicated workspace
+ // only the system session assigned with that workspace will get the
+ // system user manager (special implementation that asserts the existance
+ // of the admin user).
+ if (session == systemSession) {
+ return new SystemUserManager(systemSession, params);
+ } else {
+ UserManagerImpl um;
+ if (umc != null) {
+ Class<?>[] paramTypes = new Class[] { SessionImpl.class, String.class, Properties.class };
+ um = (UserManagerImpl) umc.getUserManager(UserManagerImpl.class, paramTypes, (SessionImpl) session, adminId, params);
+ // TODO: should we make sure the implementation doesn't allow
+ // TODO: to change the autosave behavior? since the user manager
+ // TODO: writes to a separate workspace this would cause troubles.
+ } else {
+ um = new UserManagerImpl(session, adminId, params);
+ }
+ return um;
+ }
+ }
+
+ /**
+ * @param session The session used to create the principal manager.
+ * @return A new instance of PrincipalManagerImpl
+ * @throws javax.jcr.RepositoryException If an error occurs.
+ */
+ protected PrincipalManager createPrincipalManager(SessionImpl session) throws RepositoryException {
+ return new PrincipalManagerImpl(session, getPrincipalProviderRegistry().getProviders());
+ }
+
+ /**
+ * @return A nwe instance of WorkspaceAccessManagerImpl to be used as
+ * default workspace access manager if the configuration doesn't specify one.
+ */
+ protected WorkspaceAccessManager createDefaultWorkspaceAccessManager() {
+ return new WorkspaceAccessManagerImpl();
+ }
+
+ /**
+ * Creates the default principal provider used to create the
+ * {@link PrincipalProviderRegistry}.
+ *
+ * @return An new instance of <code>DefaultPrincipalProvider</code>.
+ * @throws RepositoryException If an error occurs.
+ */
+ protected PrincipalProvider createDefaultPrincipalProvider() throws RepositoryException {
+ PrincipalProvider defaultPP = new DefaultPrincipalProvider(this.systemSession, (UserManagerImpl) systemUserManager);
+ defaultPP.init(new Properties());
+ return defaultPP;
+ }
+
+ /**
+ * @return The PrincipalProviderRegistry created during initialization.
+ */
+ protected PrincipalProviderRegistry getPrincipalProviderRegistry() {
+ return principalProviderRegistry;
+ }
+
+ /**
+ * @return The AuthContextProvider created during initialization.
+ */
+ protected AuthContextProvider getAuthContextProvider() {
+ return authContextProvider;
+ }
+
+ /**
+ * Throws <code>IllegalStateException</code> if this manager hasn't been
+ * initialized.
+ */
+ protected void checkInitialized() {
+ if (!initialized) {
+ throw new IllegalStateException("Not initialized");
+ }
+ }
+
+ /**
+ * @return The system session used to initialize this SecurityManager.
+ */
+ protected Session getSystemSession() {
+ return systemSession;
+ }
+
+ /**
+ * @return The repository used to initialize this SecurityManager.
+ */
+ protected Repository getRepository() {
+ return repository;
+ }
//--------------------------------------------------------------------------
/**
* Returns the access control provider for the specified
@@ -455,59 +572,77 @@
* configured (or default) adminID is member of this user-group.
*
* @param userManager Manager to create users/groups.
+ * @param session
* @param adminId UserID of the administrator.
* @param anonymousId UserID of the anonymous user.
* @throws RepositoryException If an error occurs.
*/
- private static void createSystemUsers(UserManager userManager,
- String adminId,
- String anonymousId) throws RepositoryException {
- Principal pr = new PrincipalImpl(SecurityConstants.ADMINISTRATORS_NAME);
- Group admins = (Group) userManager.getAuthorizable(pr);
- if (admins == null) {
- admins = userManager.createGroup(new PrincipalImpl(SecurityConstants.ADMINISTRATORS_NAME));
- log.debug("...created administrators group with name '"+SecurityConstants.ADMINISTRATORS_NAME+"'");
- }
+ static void createSystemUsers(UserManager userManager,
+ SystemSession session,
+ String adminId,
+ String anonymousId) throws RepositoryException {
+ Authorizable admin = null;
if (adminId != null) {
- Authorizable admin = userManager.getAuthorizable(adminId);
+ admin = userManager.getAuthorizable(adminId);
if (admin == null) {
admin = userManager.createUser(adminId, adminId);
- log.info("...created admin-user with id \'" + adminId + "\' ...");
- admins.addMember(admin);
- log.info("...added admin \'" + adminId + "\' as member of the administrators group.");
+ if (!userManager.isAutoSave()) {
+ session.save();
+ }
+ log.info("... created admin-user with id \'" + adminId + "\' ...");
+ }
+ }
+
+ // assume administrators groupID and principalName are the same.
+ // and avoid retrieving group by principal.
+ Group admins = (Group) userManager.getAuthorizable(SecurityConstants.ADMINISTRATORS_NAME);
+ if (admins == null) {
+ admins = userManager.createGroup(new PrincipalImpl(SecurityConstants.ADMINISTRATORS_NAME));
+ if (!userManager.isAutoSave()) {
+ session.save();
+ }
+ log.info("... created administrators group with name '"+SecurityConstants.ADMINISTRATORS_NAME+"'");
+ }
+
+ try {
+ if (admins != null && admins.addMember(admin)) {
+ if (!userManager.isAutoSave()) {
+ session.save();
+ }
+ log.info("... added admin '" + adminId + "' as member of the administrators group.");
}
+ } catch (RepositoryException e) {
+ // administrator has full permissions anyway. just log a
+ // warning and ignore the error.
+ log.warn("Unexpected error while adding admin to the administrators group", e);
}
if (anonymousId != null) {
Authorizable anonymous = userManager.getAuthorizable(anonymousId);
if (anonymous == null) {
userManager.createUser(anonymousId, "");
- log.info("...created anonymous-user with id \'" + anonymousId + "\' ...");
+ if (!userManager.isAutoSave()) {
+ session.save();
+ }
+ log.info("... created anonymous-user with id \'" + anonymousId + "\' ...");
}
}
}
- private void checkInitialized() {
- if (!initialized) {
- throw new IllegalStateException("Not initialized");
- }
- }
-
//------------------------------------------------------< inner classes >---
/**
* <code>WorkspaceAccessManager</code> that upon {@link #grants(Set principals, String)}
* evaluates if access to the root node of a workspace with the specified
* name is granted.
*/
- private class WorkspaceAccessManagerImpl implements SecurityConstants, WorkspaceAccessManager {
+ private final class WorkspaceAccessManagerImpl implements SecurityConstants, WorkspaceAccessManager {
//-----------------------------------------< WorkspaceAccessManager >---
/**
* {@inheritDoc}
- * @param securitySession
*/
- public void init(Session securitySession) throws RepositoryException {
+ public void init(Session systemSession) throws RepositoryException {
// nothing to do here.
}
@@ -526,4 +661,39 @@
return prov.canAccessRoot(principals);
}
}
+
+ /**
+ * System user manager that (re) creates the admin user in case it doesn't
+ * exist yet (upon initial startup) or has been deleted.
+ */
+ protected final class SystemUserManager extends UserManagerImpl {
+
+ private final SystemSession session;
+ private String adminPw;
+
+ protected SystemUserManager(SystemSession session, Properties config) throws RepositoryException {
+ super(session, adminId, config);
+ this.session = session;
+ adminPw = adminId; // The default value as defined upon #createSystemUsers
+ }
+
+ @Override
+ public Authorizable getAuthorizable(String id) throws RepositoryException {
+ Authorizable a = super.getAuthorizable(id);
+ if (a == null && adminId.equals(id)) {
+ log.info("Admin user does not exist.");
+ a = createAdmin(adminId, adminPw);
+ }
+ return a;
+ }
+
+ private User createAdmin(String adminId, String pw) throws RepositoryException {
+ User admin = createUser(adminId, pw);
+ if (!isAutoSave()) {
+ session.save();
+ }
+ log.info("... created admin user with id \'" + adminId + "\' and default pw.");
+ return admin;
+ }
+ }
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemImpl.java?rev=828791&r1=828790&r2=828791&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemImpl.java Thu Oct 22 17:26:37 2009
@@ -47,6 +47,7 @@
import org.apache.jackrabbit.core.id.ItemId;
import org.apache.jackrabbit.core.id.NodeId;
+import org.apache.jackrabbit.core.id.PropertyId;
import org.apache.jackrabbit.core.nodetype.EffectiveNodeType;
import org.apache.jackrabbit.core.nodetype.NodeTypeConflictException;
import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
@@ -425,11 +426,10 @@
if (nodeState.getStatus() == ItemState.STATUS_NEW
|| !nodeState.getNodeTypeName().equals(
((NodeState) nodeState.getOverlayedState()).getNodeTypeName())) {
- NodeType[] nta = nodeDef.getRequiredPrimaryTypes();
- for (int i = 0; i < nta.length; i++) {
- NodeTypeImpl ntReq = (NodeTypeImpl) nta[i];
- if (!(pnt.getQName().equals(ntReq.getQName())
- || pnt.isDerivedFrom(ntReq.getQName()))) {
+ for (NodeType ntReq : nodeDef.getRequiredPrimaryTypes()) {
+ Name ntName = ((NodeTypeImpl) ntReq).getQName();
+ if (!(pnt.getQName().equals(ntName)
+ || pnt.isDerivedFrom(ntName))) {
/**
* the transient node's primary node type does not
* satisfy the 'required primary types' constraint
@@ -443,9 +443,7 @@
}
// mandatory child properties
- QPropertyDefinition[] pda = ent.getMandatoryPropDefs();
- for (int i = 0; i < pda.length; i++) {
- QPropertyDefinition pd = pda[i];
+ for (QPropertyDefinition pd : ent.getMandatoryPropDefs()) {
if (pd.getDeclaringNodeType().equals(NameConstants.MIX_VERSIONABLE)
|| pd.getDeclaringNodeType().equals(NameConstants.MIX_SIMPLE_VERSIONABLE)) {
/**
@@ -455,24 +453,52 @@
*/
continue;
}
- if (!nodeState.hasPropertyName(pd.getName())) {
- String msg = itemMgr.safeGetJCRPath(id)
+ String msg = itemMgr.safeGetJCRPath(id)
+ ": mandatory property " + pd.getName()
+ " does not exist";
+ if (!nodeState.hasPropertyName(pd.getName())) {
log.debug(msg);
throw new ConstraintViolationException(msg);
+ } else {
+ /*
+ there exists a property with the mandatory-name.
+ make sure the property really has the expected mandatory
+ property definition (and not another non-mandatory def,
+ such as e.g. multivalued residual instead of single-value
+ mandatory, named def).
+ */
+ PropertyId pi = new PropertyId(nodeState.getNodeId(), pd.getName());
+ ItemData childData = itemMgr.getItemData(pi, null, false);
+ if (!childData.getDefinition().isMandatory()) {
+ throw new ConstraintViolationException(msg);
+ }
}
}
// mandatory child nodes
- QItemDefinition[] cnda = ent.getMandatoryNodeDefs();
- for (int i = 0; i < cnda.length; i++) {
- QItemDefinition cnd = cnda[i];
- if (!nodeState.hasChildNodeEntry(cnd.getName())) {
- String msg = itemMgr.safeGetJCRPath(id)
+ for (QItemDefinition cnd : ent.getMandatoryNodeDefs()) {
+ String msg = itemMgr.safeGetJCRPath(id)
+ ": mandatory child node " + cnd.getName()
+ " does not exist";
+ if (!nodeState.hasChildNodeEntry(cnd.getName())) {
log.debug(msg);
throw new ConstraintViolationException(msg);
+ } else {
+ /*
+ there exists a child node with the mandatory-name.
+ make sure the node really has the expected mandatory
+ node definition.
+ */
+ boolean hasMandatoryChild = false;
+ for (ChildNodeEntry cne : nodeState.getChildNodeEntries(cnd.getName())) {
+ ItemData childData = itemMgr.getItemData(cne.getId(), null, false);
+ if (childData.getDefinition().isMandatory()) {
+ hasMandatoryChild = true;
+ break;
+ }
+ }
+ if (!hasMandatoryChild) {
+ throw new ConstraintViolationException(msg);
+ }
}
}
} else {
@@ -509,11 +535,11 @@
if (constraints.length > 0
&& (propDef.getRequiredType() == PropertyType.REFERENCE
|| propDef.getRequiredType() == PropertyType.WEAKREFERENCE)) {
- for (int i = 0; i < values.length; i++) {
+ for (InternalValue internalV : values) {
boolean satisfied = false;
String constraintViolationMsg = null;
try {
- NodeId targetId = values[i].getNodeId();
+ NodeId targetId = internalV.getNodeId();
if (propDef.getRequiredType() == PropertyType.WEAKREFERENCE
&& !itemMgr.itemExists(targetId)) {
// target of weakref doesn;t exist, skip
@@ -524,14 +550,13 @@
* constraints are OR-ed, i.e. at least one
* has to be satisfied
*/
- for (int j = 0; j < constraints.length; j++) {
+ for (String constrNtName : constraints) {
/**
* a [WEAK]REFERENCE value constraint specifies
* the name of the required node type of
* the target node
*/
- String ntName = constraints[j];
- if (targetNode.isNodeType(ntName)) {
+ if (targetNode.isNodeType(constrNtName)) {
satisfied = true;
break;
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java?rev=828791&r1=828790&r2=828791&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java Thu Oct 22 17:26:37 2009
@@ -356,7 +356,7 @@
* read the said item
* @throws RepositoryException if another error occurs
*/
- private ItemData getItemData(ItemId itemId, Path path, boolean permissionCheck)
+ ItemData getItemData(ItemId itemId, Path path, boolean permissionCheck)
throws ItemNotFoundException, AccessDeniedException,
RepositoryException {
ItemData data = retrieveItem(itemId);
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java?rev=828791&r1=828790&r2=828791&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java Thu Oct 22 17:26:37 2009
@@ -520,16 +520,14 @@
thisState.addChildNodeEntry(name, nodeState.getNodeId());
// add 'auto-create' properties defined in node type
- PropertyDefinition[] pda = nodeType.getAutoCreatedPropertyDefinitions();
- for (int i = 0; i < pda.length; i++) {
- PropertyDefinitionImpl pd = (PropertyDefinitionImpl) pda[i];
+ for (PropertyDefinition aPda : nodeType.getAutoCreatedPropertyDefinitions()) {
+ PropertyDefinitionImpl pd = (PropertyDefinitionImpl) aPda;
node.createChildProperty(pd.unwrap().getName(), pd.getRequiredType(), pd);
}
// recursively add 'auto-create' child nodes defined in node type
- NodeDefinition[] nda = nodeType.getAutoCreatedNodeDefinitions();
- for (int i = 0; i < nda.length; i++) {
- NodeDefinitionImpl nd = (NodeDefinitionImpl) nda[i];
+ for (NodeDefinition aNda : nodeType.getAutoCreatedNodeDefinitions()) {
+ NodeDefinitionImpl nd = (NodeDefinitionImpl) aNda;
node.createChildNode(nd.unwrap().getName(), (NodeTypeImpl) nd.getDefaultPrimaryType(), null);
}
@@ -918,9 +916,8 @@
setMixinTypesProperty(mixins);
// add 'auto-create' properties defined in mixin type
- PropertyDefinition[] pda = mixin.getAutoCreatedPropertyDefinitions();
- for (int i = 0; i < pda.length; i++) {
- PropertyDefinitionImpl pd = (PropertyDefinitionImpl) pda[i];
+ for (PropertyDefinition aPda : mixin.getAutoCreatedPropertyDefinitions()) {
+ PropertyDefinitionImpl pd = (PropertyDefinitionImpl) aPda;
// make sure that the property is not already defined by primary type
// or existing mixin's
NodeTypeImpl declaringNT = (NodeTypeImpl) pd.getDeclaringNodeType();
@@ -930,9 +927,8 @@
}
// recursively add 'auto-create' child nodes defined in mixin type
- NodeDefinition[] nda = mixin.getAutoCreatedNodeDefinitions();
- for (int i = 0; i < nda.length; i++) {
- NodeDefinitionImpl nd = (NodeDefinitionImpl) nda[i];
+ for (NodeDefinition aNda : mixin.getAutoCreatedNodeDefinitions()) {
+ NodeDefinitionImpl nd = (NodeDefinitionImpl) aNda;
// make sure that the child node is not already defined by primary type
// or existing mixin's
NodeTypeImpl declaringNT = (NodeTypeImpl) nd.getDeclaringNodeType();
@@ -1786,8 +1782,8 @@
// create new child node
NodeImpl node = addNode(nodeName, nodeTypeName, id);
if (mixinNames != null) {
- for (int i = 0; i < mixinNames.length; i++) {
- node.addMixin(mixinNames[i]);
+ for (Name mixinName : mixinNames) {
+ node.addMixin(mixinName);
}
}
@@ -3409,7 +3405,7 @@
if (!isNodeType(NameConstants.MIX_REFERENCEABLE)) {
return PropertyIteratorAdapter.EMPTY;
}
-
+
try {
StringBuilder stmt = new StringBuilder();
stmt.append("//*[@").append(ISO9075.encode(name));
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java?rev=828791&r1=828790&r2=828791&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java Thu Oct 22 17:26:37 2009
@@ -19,7 +19,6 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringReader;
@@ -33,7 +32,6 @@
import java.util.Map;
import java.util.Properties;
import java.util.Set;
-import java.util.Iterator;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
@@ -1065,7 +1063,7 @@
} else {
log.debug("Found preauthenticated Subject, try to extend authentication");
// login either using JAAS or custom LoginModule
- AuthContext authCtx = getSecurityManager().getAuthContext(null, subject);
+ AuthContext authCtx = getSecurityManager().getAuthContext(null, subject, workspaceName);
try {
authCtx.login();
s = createSession(authCtx, workspaceName);
@@ -1320,8 +1318,8 @@
// now set customized repository descriptor values (if any exist)
Properties props = getCustomRepositoryDescriptors();
if (props != null) {
- for (Iterator it = props.keySet().iterator(); it.hasNext();) {
- String key = (String) it.next();
+ for (Object o : props.keySet()) {
+ String key = (String) o;
setDescriptor(key, props.getProperty(key));
}
}
@@ -1462,16 +1460,15 @@
}
}
// not preauthenticated -> try login with credentials
- AuthContext authCtx = getSecurityManager().getAuthContext(credentials, new Subject());
+ AuthContext authCtx = getSecurityManager().getAuthContext(credentials, new Subject(), workspaceName);
authCtx.login();
// create session, and add SimpleCredentials attributes (JCR-1932)
SessionImpl session = createSession(authCtx, workspaceName);
if (credentials instanceof SimpleCredentials) {
SimpleCredentials sc = (SimpleCredentials) credentials;
- String[] names = sc.getAttributeNames();
- for (int i = 0; i < names.length; i++) {
- session.setAttribute(names[i], sc.getAttribute(names[i]));
+ for (String name : sc.getAttributeNames()) {
+ session.setAttribute(name, sc.getAttribute(name));
}
}
return session;
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java?rev=828791&r1=828790&r2=828791&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java Thu Oct 22 17:26:37 2009
@@ -50,8 +50,6 @@
import org.apache.jackrabbit.core.version.InternalVersionManagerImpl;
import org.apache.jackrabbit.core.xml.ImportHandler;
import org.apache.jackrabbit.core.xml.SessionImporter;
-import org.apache.jackrabbit.core.xml.AccessControlImporter;
-import org.apache.jackrabbit.core.xml.ProtectedNodeImporter;
import org.apache.jackrabbit.spi.Name;
import org.apache.jackrabbit.spi.Path;
import org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver;
@@ -86,7 +84,6 @@
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.ValueFactory;
import javax.jcr.Workspace;
-import javax.jcr.ImportUUIDBehavior;
import javax.jcr.lock.Lock;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.ConstraintViolationException;
@@ -280,7 +277,7 @@
this.rep = rep;
this.subject = subject;
- userId = retrieveUserId(subject);
+ userId = retrieveUserId(subject, wspConfig.getName());
namePathResolver = new DefaultNamePathResolver(this, this, true);
ntMgr = new NodeTypeManagerImpl(rep.getNodeTypeRegistry(), this, rep.getDataStore());
@@ -300,8 +297,8 @@
*
* @return the userID.
*/
- protected String retrieveUserId(Subject subject) throws RepositoryException {
- return rep.getSecurityManager().getUserID(subject);
+ protected String retrieveUserId(Subject subject, String workspaceName) throws RepositoryException {
+ return rep.getSecurityManager().getUserID(subject, workspaceName);
}
/**
@@ -1166,9 +1163,7 @@
ItemValidator.CHECK_CONSTRAINTS | ItemValidator.CHECK_HOLD | ItemValidator.CHECK_RETENTION;
getValidator().checkModify(parent, options, Permission.NONE);
- // TODO: make configurable
- ProtectedNodeImporter pi = new AccessControlImporter(this, this, false, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
- SessionImporter importer = new SessionImporter(parent, this, uuidBehavior, pi, null);
+ SessionImporter importer = new SessionImporter(parent, this, uuidBehavior, wsp.getConfig().getImportConfig());
return new ImportHandler(importer, this);
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SystemSession.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SystemSession.java?rev=828791&r1=828790&r2=828791&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SystemSession.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SystemSession.java Thu Oct 22 17:26:37 2009
@@ -81,7 +81,7 @@
*
* @return the name of <code>SystemPrincipal</code>.
*/
- protected String retrieveUserId(Subject subject) throws RepositoryException {
+ protected String retrieveUserId(Subject subject, String workspaceName) throws RepositoryException {
return new SystemPrincipal().getName();
}
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/UserPerWorkspaceSecurityManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/UserPerWorkspaceSecurityManager.java?rev=828791&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/UserPerWorkspaceSecurityManager.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/UserPerWorkspaceSecurityManager.java Thu Oct 22 17:26:37 2009
@@ -0,0 +1,321 @@
+/*
+ * 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.core;
+
+import org.apache.jackrabbit.api.security.principal.PrincipalManager;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.core.config.UserManagerConfig;
+import org.apache.jackrabbit.core.security.authentication.AuthContext;
+import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager;
+import org.apache.jackrabbit.core.security.principal.DefaultPrincipalProvider;
+import org.apache.jackrabbit.core.security.principal.PrincipalManagerImpl;
+import org.apache.jackrabbit.core.security.principal.PrincipalProvider;
+import org.apache.jackrabbit.core.security.principal.PrincipalProviderRegistry;
+import org.apache.jackrabbit.core.security.simple.SimpleWorkspaceAccessManager;
+import org.apache.jackrabbit.core.security.user.UserPerWorkspaceUserManager;
+import org.apache.jackrabbit.core.security.user.UserManagerImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.Credentials;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.security.auth.Subject;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+/**
+ * Derived security manager implementation that expects that users information
+ * is present in each workspace instead of having a single, dedicated
+ * "security-workspace" that provides user information. Consequently, the
+ * UserManager used to retrieve and manipulate user content is always
+ * bound to the <code>Session</code> passed to {@link #getUserManager(Session)}.
+ * <p/> In addition the default (user-based) principal provider created by
+ * {@link org.apache.jackrabbit.core.DefaultSecurityManager}
+ * cannot be used to retrieve principals. Instead this implementation keeps
+ * a distinct pp-registry for each workspace.
+ * </p>
+ * NOTE: While this security manager asserts that a minimal set of system
+ * users (admin, administrators group and anonymous) is present in each workspace
+ * it doesn't make any attempt to set or define the access permissions on the
+ * tree containing user related information.
+ */
+public class UserPerWorkspaceSecurityManager extends DefaultSecurityManager {
+
+ /**
+ * the default logger
+ */
+ private static final Logger log = LoggerFactory.getLogger(UserPerWorkspaceSecurityManager.class);
+
+ private final Map<String, PrincipalProviderRegistry> ppRegistries = new HashMap();
+
+ /**
+ * List of workspace names for which {@link #createSystemUsers} has already
+ * been called.
+ */
+ private final List<String> systemUsersInitialized = new ArrayList();
+
+ private PrincipalProviderRegistry getPrincipalProviderRegistry(SessionImpl s) throws RepositoryException {
+ String wspName = s.getWorkspace().getName();
+ PrincipalProviderRegistry p = ppRegistries.get(wspName);
+ if (p == null) {
+ SystemSession systemSession;
+ if (s instanceof SystemSession) {
+ systemSession = (SystemSession) s;
+ } else {
+ RepositoryImpl repo = (RepositoryImpl) getRepository();
+ systemSession = repo.getSystemSession(wspName);
+ // TODO: review again... this workaround is used in several places.
+ repo.onSessionCreated(systemSession);
+ }
+
+ PrincipalProvider defaultPP = new DefaultPrincipalProvider(systemSession, (UserManagerImpl) getUserManager(systemSession));
+ defaultPP.init(new Properties());
+
+ p = new WorkspaceBasedPrincipalProviderRegistry(defaultPP);
+ ppRegistries.put(wspName, p);
+ }
+ return p;
+ }
+
+ //------------------------------------------< JackrabbitSecurityManager >---
+ /**
+ * @see org.apache.jackrabbit.core.security.JackrabbitSecurityManager#init(Repository, Session)
+ */
+ @Override
+ public void init(Repository repository, Session systemSession) throws RepositoryException {
+ super.init(repository, systemSession);
+
+ systemUsersInitialized.add(systemSession.getWorkspace().getName());
+ }
+
+ /**
+ * @see org.apache.jackrabbit.core.security.JackrabbitSecurityManager#dispose(String)
+ */
+ @Override
+ public void dispose(String workspaceName) {
+ super.dispose(workspaceName);
+ synchronized (ppRegistries) {
+ PrincipalProviderRegistry reg = ppRegistries.remove(workspaceName);
+ if (reg != null) {
+ reg.getDefault().close();
+ }
+ }
+ }
+
+ /**
+ * @see org.apache.jackrabbit.core.security.JackrabbitSecurityManager#close()
+ */
+ @Override
+ public void close() {
+ super.close();
+ synchronized (ppRegistries) {
+ for (PrincipalProviderRegistry registry : ppRegistries.values()) {
+ registry.getDefault().close();
+ }
+ ppRegistries.clear();
+ }
+ }
+
+ /**
+ * As this implementation expectes that users information in present in
+ * every workspace, the UserManager is always created with the given
+ * session.
+ *
+ * @see org.apache.jackrabbit.core.security.JackrabbitSecurityManager#getUserManager(javax.jcr.Session)
+ */
+ @Override
+ public UserManager getUserManager(Session session) throws RepositoryException {
+ checkInitialized();
+ if (session == getSystemSession()) {
+ return super.getUserManager(session);
+ } else if (session instanceof SessionImpl) {
+ UserManager uMgr = createUserManager((SessionImpl) session);
+ // Since users are not stored in a dedicated security workspace:
+ // make sure the system users are present. this is always the case
+ // for the configured security-workspace (or if missing the default
+ // workspace) but not for other workspaces.
+ // However, the check is only executed if the given session is a
+ // SystemSession (see also #getPrincipalProviderRegistry(Session)
+ // that initializes a SystemSession based UserManager for each workspace).
+ String wspName = session.getWorkspace().getName();
+ if (session instanceof SystemSession && !systemUsersInitialized.contains(wspName)) {
+ createSystemUsers(uMgr, (SystemSession) session, adminId, anonymousId);
+ systemUsersInitialized.add(wspName);
+ }
+ return uMgr;
+ } else {
+ throw new RepositoryException("Internal error: SessionImpl expected.");
+ }
+ }
+
+ /**
+ * Creates an AuthContext for the given {@link javax.jcr.Credentials} and
+ * {@link javax.security.auth.Subject}.<br>
+ * This includes selection of application specific LoginModules and
+ * initialization with credentials and Session to System-Workspace
+ *
+ * @return an {@link org.apache.jackrabbit.core.security.authentication.AuthContext} for the given Credentials, Subject
+ * @throws javax.jcr.RepositoryException in other exceptional repository states
+ */
+ @Override
+ public AuthContext getAuthContext(Credentials creds, Subject subject, String workspaceName)
+ throws RepositoryException {
+ checkInitialized();
+ SystemSession systemSession = ((RepositoryImpl) getRepository()).getSystemSession(workspaceName);
+ return getAuthContextProvider().getAuthContext(creds, subject, systemSession,
+ getPrincipalProviderRegistry(systemSession), adminId, anonymousId);
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ * Always returns <code>null</code>. The default principal provider is
+ * workspace depending as users are expected to exist in every workspace.
+ *
+ * @return <code>null</code>
+ * @throws RepositoryException
+ */
+ @Override
+ protected PrincipalProvider createDefaultPrincipalProvider() throws RepositoryException {
+ return null;
+ }
+
+ @Override
+ protected UserManager getSystemUserManager(String workspaceName) throws RepositoryException {
+ if (workspaceName.equals(getSystemSession().getWorkspace().getName())) {
+ return super.getSystemUserManager(workspaceName);
+ } else {
+ return ((RepositoryImpl) getRepository()).getWorkspaceInfo(workspaceName).getSystemSession().getUserManager();
+ }
+ }
+
+ /**
+ * Creates a new instanceof <code>TransientChangeUserManagerImpl</code>.
+ *
+ * @param session session
+ * @return an instanceof <code>TransientChangeUserManagerImpl</code>
+ * @throws RepositoryException
+ */
+ @Override
+ protected UserManagerImpl createUserManager(SessionImpl session) throws RepositoryException {
+ UserManagerConfig umc = getConfig().getUserManagerConfig();
+ Properties params = (umc == null) ? null : umc.getParameters();
+
+ // in contrast to the DefaultSecurityManager users are not retrieved
+ // from a dedicated workspace: the system session of each workspace must
+ // get a system user manager that asserts the existance of the admin user.
+ if (session instanceof SystemSession) {
+ return new SystemUserManager((SystemSession) session, params);
+ } else {
+ if (umc != null) {
+ Class<?>[] paramTypes = new Class[] { SessionImpl.class, String.class, Properties.class };
+ return (UserPerWorkspaceUserManager) umc.getUserManager(UserPerWorkspaceUserManager.class, paramTypes, (SessionImpl) session, adminId, params);
+ } else {
+ return new UserPerWorkspaceUserManager(session, adminId, params);
+ }
+ }
+ }
+
+ /**
+ * @param session Session for the principal manager must be created.
+ * @return A new instance of PrincipalManagerImpl. Note that this implementation
+ * uses a workspace specific principal provider registry, that retrieves
+ * the configured providers from the registry obtained throug
+ * {@link #getPrincipalProviderRegistry()} but has a workspace specific
+ * default provider.
+ * @throws RepositoryException
+ */
+ @Override
+ protected PrincipalManager createPrincipalManager(SessionImpl session) throws RepositoryException {
+ return new PrincipalManagerImpl(session, getPrincipalProviderRegistry(session).getProviders());
+ }
+
+ /**
+ * Returns a new instance of <code>SimpleWorkspaceAccessManager</code>, since
+ * with the <code>DefaultLoginModule</code> the existance of the user
+ * is checked in order to successfully complete the login. Since with this
+ * SecurityManager users are stored separately in each workspace, a user
+ * may only login to a workspace if the corresponding user node exists.
+ * Consequently a lazy workspace access manager is sufficient.<p/>
+ *
+ * If this SecurityManager is used with a distict <code>LoginModule</code>
+ * implementation, the {@link org.apache.jackrabbit.core.config.SecurityManagerConfig#getWorkspaceAccessConfig() configuration}
+ * for <code>WorkspaceAccessManager</code> should be adjusted as well.
+ *
+ * @return An new instance of {@link SimpleWorkspaceAccessManager}.
+ */
+ @Override
+ protected WorkspaceAccessManager createDefaultWorkspaceAccessManager() {
+ return new WorkspaceAccessManagerImpl();
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ * Workaround to get a default (user-based) principal provider depending
+ * on the workspace beeing accessed. This is required for this security
+ * manager as users aren't stored in a single, dedicated workspace.
+ */
+ private final class WorkspaceBasedPrincipalProviderRegistry implements PrincipalProviderRegistry {
+
+ private final PrincipalProvider defaultPrincipalProvider;
+
+ public WorkspaceBasedPrincipalProviderRegistry(PrincipalProvider defaultPrincipalProvider) {
+ this.defaultPrincipalProvider = defaultPrincipalProvider;
+ }
+
+ public PrincipalProvider registerProvider(Properties configuration) throws RepositoryException {
+ throw new UnsupportedOperationException();
+ }
+
+ public PrincipalProvider getDefault() {
+ return defaultPrincipalProvider;
+ }
+
+ public PrincipalProvider getProvider(String className) {
+ PrincipalProvider p = getPrincipalProviderRegistry().getProvider(className);
+ if (p == null && defaultPrincipalProvider.getClass().getName().equals(className)) {
+ p = defaultPrincipalProvider;
+ }
+ return p;
+ }
+
+ public PrincipalProvider[] getProviders() {
+ List<PrincipalProvider> l = new ArrayList();
+ l.addAll(Arrays.asList(getPrincipalProviderRegistry().getProviders()));
+ l.add(defaultPrincipalProvider);
+ return l.toArray(new PrincipalProvider[l.size()]);
+ }
+ }
+
+ private final class WorkspaceAccessManagerImpl extends SimpleWorkspaceAccessManager {
+ @Override
+ public boolean grants(Set<Principal> principals, String workspaceName) throws RepositoryException {
+ if (!(Arrays.asList(((RepositoryImpl) getRepository()).getWorkspaceNames())).contains(workspaceName)) {
+ return false;
+ } else {
+ return super.grants(principals, workspaceName);
+ }
+ }
+ }
+}
\ No newline at end of file
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java?rev=828791&r1=828790&r2=828791&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java Thu Oct 22 17:26:37 2009
@@ -835,7 +835,7 @@
}
Importer importer = new WorkspaceImporter(parentPath, this,
- rep.getNodeTypeRegistry(), uuidBehavior);
+ rep.getNodeTypeRegistry(), uuidBehavior, wspConfig.getImportConfig());
return new ImportHandler(importer, session);
}
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/ImportConfig.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/ImportConfig.java?rev=828791&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/ImportConfig.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/ImportConfig.java Thu Oct 22 17:26:37 2009
@@ -0,0 +1,84 @@
+/*
+ * 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.core.config;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.core.xml.ProtectedNodeImporter;
+import org.apache.jackrabbit.core.xml.ProtectedPropertyImporter;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * <code>XmlImportConfig</code>...
+ */
+public class ImportConfig {
+
+ /**
+ * logger instance
+ */
+ private static final Logger log = LoggerFactory.getLogger(ImportConfig.class);
+
+ private final List<BeanConfig> protectedNodeImporters;
+ private final List<BeanConfig> protectedPropertyImporters;
+
+ public ImportConfig() {
+ protectedNodeImporters = Collections.emptyList();
+ protectedPropertyImporters = Collections.emptyList();
+ }
+
+ public ImportConfig(List<BeanConfig> protectedNodeImporters, List<BeanConfig> protectedPropertyImporters) {
+ this.protectedNodeImporters = protectedNodeImporters;
+ this.protectedPropertyImporters = protectedPropertyImporters;
+ }
+
+ public List<ProtectedNodeImporter> getProtectedNodeImporters() {
+ List<ProtectedNodeImporter> pnis = new ArrayList();
+ for (BeanConfig bc : protectedNodeImporters) {
+ try {
+ Object o = bc.newInstance();
+ if (o instanceof ProtectedNodeImporter) {
+ pnis.add((ProtectedNodeImporter) o);
+ } else {
+ log.warn("Invalid configuration entry: " + bc.getClassName() +" does not implement ProtectedNodeImporter.");
+ }
+ } catch (ConfigurationException e) {
+ log.warn(e.getMessage());
+ }
+ }
+ return pnis;
+ }
+
+ public List<ProtectedPropertyImporter> getProtectedPropertyImporters() {
+ List<ProtectedPropertyImporter> ppis = new ArrayList();
+ for (BeanConfig bc : protectedPropertyImporters) {
+ try {
+ Object o = bc.newInstance();
+ if (o instanceof ProtectedPropertyImporter) {
+ ppis.add((ProtectedPropertyImporter) o);
+ } else {
+ log.warn("Invalid configuration entry: " + bc.getClassName() +" does not implement ProtectedPropertyImporter.");
+ }
+ } catch (ConfigurationException e) {
+ log.warn(e.getMessage());
+ }
+ }
+ return ppis;
+ }
+}
\ No newline at end of file
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java?rev=828791&r1=828790&r2=828791&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java Thu Oct 22 17:26:37 2009
@@ -46,6 +46,8 @@
import java.io.IOException;
import java.util.Properties;
import java.util.UUID;
+import java.util.List;
+import java.util.ArrayList;
import javax.jcr.RepositoryException;
@@ -181,6 +183,19 @@
private static final String AC_PROVIDER_ELEMENT = "AccessControlProvider";
/**
+ * Element specifying the class of principals used to retrieve the userID
+ * in the 'class' attribute.
+ */
+ private static final String USERID_CLASS = "UserIdClass";
+
+ /**
+ * Name of the optional XmlImport config entry inside the workspace configuration.
+ */
+ private static final String IMPORT_ELEMENT = "Import";
+ private static final String IMPORT_PNI_ELEMENT = "ProtectedNodeImporter";
+ private static final String IMPORT_PPI_ELEMENT = "ProtectedPropertyImporter";
+
+ /**
* Name of the cluster node id file.
*/
private static final String CLUSTER_NODE_ID_FILE = "cluster_node.id";
@@ -348,12 +363,19 @@
wac = parseBeanConfig(smElement, WORKSPACE_ACCESS_ELEMENT);
}
- BeanConfig umc = null;
+ UserManagerConfig umc = null;
element = getElement(smElement, USER_MANAGER_ELEMENT, false);
if (element != null) {
- umc = parseBeanConfig(smElement, USER_MANAGER_ELEMENT);
+ umc = new UserManagerConfig(parseBeanConfig(smElement, USER_MANAGER_ELEMENT));
+ }
+
+ BeanConfig uidcc = null;
+ element = getElement(smElement, USERID_CLASS, false);
+ if (element != null) {
+ uidcc = parseBeanConfig(element);
}
- return new SecurityManagerConfig(bc, wspAttr, wac, umc);
+
+ return new SecurityManagerConfig(bc, wspAttr, wac, umc, uidcc);
} else {
return null;
}
@@ -443,7 +465,6 @@
* @return workspace configuration
* @throws ConfigurationException if the configuration is broken
* @see #parseBeanConfig(Element, String)
- * @see #parseSearchConfig(Element)
* @see #parseWorkspaceSecurityConfig(Element)
*/
public WorkspaceConfig parseWorkspaceConfig(InputSource xml)
@@ -472,7 +493,7 @@
// Clustered attribute
boolean clustered = Boolean.valueOf(
- getAttribute(root, CLUSTERED_ATTRIBUTE, "true")).booleanValue();
+ getAttribute(root, CLUSTERED_ATTRIBUTE, "true"));
// Create a temporary parser that contains the ${wsp.name} variable
Properties tmpVariables = (Properties) getVariables().clone();
@@ -496,9 +517,12 @@
// workspace specific security configuration
WorkspaceSecurityConfig workspaceSecurityConfig = tmpParser.parseWorkspaceSecurityConfig(root);
+ // optinal config for import handling
+ ImportConfig importConfig = tmpParser.parseImportConfig(root);
+
return new WorkspaceConfig(
home, name, clustered, fsf, pmc, qhf,
- ismLockingFactory, workspaceSecurityConfig);
+ ismLockingFactory, workspaceSecurityConfig, importConfig);
}
/**
@@ -597,6 +621,49 @@
}
/**
+ * Read the optional XmlImport Element of Workspace's configuration. It uses
+ * the following format:
+ * <pre>
+ * <XmlImport>
+ * <ProtectedNodeImporter class="..." (optional)>
+ * <ProtectedNodeImporter class="..." (optional)>
+ * ...
+ * <ProtectedPropertyImporter class="..." (optional)>
+ * </XmlImport>
+ * </pre>
+ *
+ * @param parent Workspace-Root-Element
+ * @return a new <code>XmlImportConfig</code>
+ * @throws ConfigurationException
+ */
+ public ImportConfig parseImportConfig(Element parent) throws ConfigurationException {
+ List<BeanConfig> protectedNodeImporters = new ArrayList();
+ List<BeanConfig> protectedPropertyImporters = new ArrayList();
+
+ Element element = getElement(parent, IMPORT_ELEMENT, false);
+ if (element != null) {
+ NodeList children = element.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if (child.getNodeType() == Node.ELEMENT_NODE) {
+ if (IMPORT_PNI_ELEMENT.equals(child.getNodeName())) {
+ String className = getAttribute((Element) child, CLASS_ATTRIBUTE);
+ BeanConfig bc = new BeanConfig(className, parseParameters((Element) child));
+ bc.setValidate(false);
+ protectedNodeImporters.add(bc);
+ } else if (IMPORT_PPI_ELEMENT.equals(child.getNodeName())) {
+ String className = getAttribute((Element) child, CLASS_ATTRIBUTE);
+ BeanConfig bc = new BeanConfig(className, parseParameters((Element) child));
+ bc.setValidate(false);
+ protectedPropertyImporters.add(bc);
+ } // else: some other entry -> ignore.
+ }
+ }
+ }
+ return new ImportConfig(protectedNodeImporters, protectedPropertyImporters);
+ }
+
+ /**
* Returns an ISM locking factory that creates {@link ISMLocking} instances
* based on the given configuration. ISM locking configuration uses the
* following format:
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/SecurityManagerConfig.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/SecurityManagerConfig.java?rev=828791&r1=828790&r2=828791&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/SecurityManagerConfig.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/SecurityManagerConfig.java Thu Oct 22 17:26:37 2009
@@ -16,6 +16,9 @@
*/
package org.apache.jackrabbit.core.config;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
* Security manager configuration. This bean configuration class
* is used to create configured security manager objects.
@@ -27,9 +30,19 @@
*/
public class SecurityManagerConfig extends BeanConfig {
+ /**
+ * the default logger
+ */
+ private static final Logger log = LoggerFactory.getLogger(SecurityManagerConfig.class);
+
private final String workspaceName;
private final BeanConfig workspaceAccessConfig;
- private final BeanConfig userManagerConfig;
+ private final UserManagerConfig userManagerConfig;
+
+ /**
+ * Optional class used to retrieve userID from the subject.
+ */
+ private final Class uidClass;
/**
* Creates an security manager configuration object from the
@@ -41,7 +54,7 @@
*/
public SecurityManagerConfig(BeanConfig config, String workspaceName,
BeanConfig workspaceAccessConfig) {
- this(config, workspaceName, workspaceAccessConfig, null);
+ this(config, workspaceName, workspaceAccessConfig, null, null);
}
/**
@@ -55,11 +68,21 @@
*/
public SecurityManagerConfig(BeanConfig config, String workspaceName,
BeanConfig workspaceAccessConfig,
- BeanConfig userManagerConfig) {
+ UserManagerConfig userManagerConfig,
+ BeanConfig uidClassConfig) {
super(config);
this.workspaceName = workspaceName;
this.workspaceAccessConfig = workspaceAccessConfig;
this.userManagerConfig = userManagerConfig;
+ Class cl = null;
+ if (uidClassConfig != null) {
+ try {
+ cl = Class.forName(uidClassConfig.getClassName(), true, uidClassConfig.getClassLoader());
+ } catch (ClassNotFoundException e) {
+ log.error("Configured bean implementation class " + uidClassConfig.getClassName() + " was not found -> Ignoring UserIdClass element.", e);
+ }
+ }
+ this.uidClass = cl;
}
/**
@@ -86,7 +109,16 @@
* May be <code>null</code> if the configuration entry is missing (i.e.
* the system default should be used).
*/
- public BeanConfig getUserManagerConfig() {
+ public UserManagerConfig getUserManagerConfig() {
return userManagerConfig;
}
+
+ /**
+ * @return Class which is used to retrieve the UserID from the Subject.
+ * @see org.apache.jackrabbit.core.security.JackrabbitSecurityManager#getUserID(javax.security.auth.Subject, String)
+ * @see javax.security.auth.Subject#getPrincipals(Class)
+ */
+ public Class getUserIdClass() {
+ return uidClass;
+ }
}