Refactor JCR utils and home usage
authorMathieu Baudier <mbaudier@argeo.org>
Wed, 22 Aug 2012 15:02:00 +0000 (15:02 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Wed, 22 Aug 2012 15:02:00 +0000 (15:02 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@5535 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

28 files changed:
base/runtime/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/JcrPreferenceStore.java
security/modules/org.argeo.security.dao.jackrabbit/META-INF/spring/security-jcr-osgi.xml
security/modules/org.argeo.security.dao.jackrabbit/META-INF/spring/security-jcr-services.xml
security/modules/org.argeo.security.dao.ldap/META-INF/spring/security-ldap-osgi.xml
security/modules/org.argeo.security.dao.ldap/META-INF/spring/security-ldap-services.xml
security/modules/org.argeo.security.dao.os/META-INF/spring/security-os-osgi.xml
security/modules/org.argeo.security.dao.os/META-INF/spring/security-os.xml
security/plugins/org.argeo.security.ui.admin/src/main/java/org/argeo/security/ui/admin/editors/ArgeoUserEditor.java
security/plugins/org.argeo.security.ui.admin/src/main/java/org/argeo/security/ui/admin/wizards/NewUserWizard.java
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/SystemExecutionService.java
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrUserDetails.java
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/OsJcrAuthenticationProvider.java
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/OsJcrUserAdminService.java
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/RemoteJcrAuthenticationProvider.java
security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoSecurityManager.java
security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/jcr/JcrLdapSynchronizer.java
security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/jcr/JcrUserDetailsContextMapper.java
server/plugins/org.argeo.jcr.ui.explorer/META-INF/spring/commands.xml
server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/JcrExplorerConstants.java
server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/browser/NodeContentProvider.java
server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/commands/AddRemoteRepository.java
server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/model/RepositoriesNode.java
server/plugins/org.argeo.jcr.ui.explorer/src/main/java/org/argeo/jcr/ui/explorer/utils/JcrUiUtils.java
server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/remote/SimpleSessionProvider.java
server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ArgeoJcrUtils.java [new file with mode: 0644]
server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java
server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/security/JcrKeyring.java
server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/security/SecurityJcrUtils.java [new file with mode: 0644]

index 7090055973f4cf7d916fc8918ddb6aac23325830..93d0f045474e3fa43ecb1c9eb7cd2f96cf7412c6 100644 (file)
@@ -29,6 +29,7 @@ import javax.jcr.version.VersionManager;
 
 import org.apache.commons.io.IOUtils;
 import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoJcrUtils;
 import org.argeo.jcr.ArgeoNames;
 import org.argeo.jcr.ArgeoTypes;
 import org.argeo.jcr.JcrUtils;
@@ -52,7 +53,7 @@ public class JcrPreferenceStore extends PreferenceStore implements ArgeoNames {
                try {
                        if (session.hasPendingChanges())
                                session.save();
-                       Node userHome = JcrUtils.getUserHome(session);
+                       Node userHome = ArgeoJcrUtils.getUserHome(session);
                        if (userHome == null)
                                throw new ArgeoException("No user home for "
                                                + session.getUserID());
index 53f66d558d9107002f5098424fbc675ff76e500e..de60f22ea2165fd650ae2f7296ff3a4e9e18a4f9 100644 (file)
@@ -13,8 +13,6 @@
        <reference id="repositoryFactory" interface="javax.jcr.RepositoryFactory" />\r
 \r
        <!-- SERVICES -->\r
-       <service ref="systemExecutionService" interface="org.argeo.security.SystemExecutionService" />\r
-\r
        <service ref="authenticationManager"\r
                interface="org.springframework.security.AuthenticationManager" />\r
 \r
index 49ace03d0df041e0d806b62e186b29f5f864a397..1a3d2eefe9a6d546ed091afa869ba1559383468b 100644 (file)
                </property>
        </bean>
 
-       <bean id="systemExecutionService" class="org.argeo.security.core.KeyBasedSystemExecutionService">
-               <property name="systemAuthenticationKey" value="${argeo.security.systemKey}" />
-               <property name="authenticationManager" ref="authenticationManager" />
-       </bean>
-
        <bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
                <property name="providers">
                        <list>
index 3af0501ed0377b145b974d4745f5cfa33d1bc5ec..aa3b67ac64e222245415f0eb39c7165ed812e8de 100644 (file)
@@ -11,7 +11,6 @@
                filter="(argeo.jcr.repository.alias=node)" />\r
 \r
        <!-- SERVICES -->\r
-       <service ref="systemExecutionService" interface="org.argeo.security.SystemExecutionService" />\r
        <service ref="authenticationManager"\r
                interface="org.springframework.security.AuthenticationManager"\r
                context-class-loader="service-provider" />\r
index 57686c8881cc93069241a34dfe2a5797a9f5ebb2..36dedf3891587823d384000e6f777dea902e1b01 100644 (file)
@@ -4,11 +4,6 @@
        xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
-       <bean id="systemExecutionService" class="org.argeo.security.core.KeyBasedSystemExecutionService">
-               <property name="authenticationManager" ref="authenticationManager" />
-               <property name="systemAuthenticationKey" value="${argeo.security.systemKey}" />
-       </bean>
-
        <bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
                <property name="providers">
                        <list>
index 8c6977a687e3406e7cf73cdbec7ef2fa1f7b1b7b..5d827b4a5ba96025d10b8da1918baffc844cf837 100644 (file)
@@ -17,8 +17,6 @@
        <service ref="authenticationManager"\r
                interface="org.springframework.security.AuthenticationManager" />\r
 \r
-       <service ref="systemExecutionService" interface="org.argeo.security.SystemExecutionService" />\r
-\r
        <!-- User management -->\r
        <service ref="userDetailsManager"\r
                interface="org.springframework.security.userdetails.UserDetailsService"\r
index 41b23cc092c1abe8397b7b22988df4b1704284bb..ee424b9e214c68e3f708fdc3f550fd2156a79ed8 100644 (file)
                <property name="bundleContext" ref="bundleContext" />
        </bean>
 
-       <bean id="systemExecutionService" class="org.argeo.security.core.KeyBasedSystemExecutionService">
-               <property name="authenticationManager" ref="authenticationManager" />
-               <property name="systemAuthenticationKey" value="${argeo.security.systemKey}" />
-       </bean>
-
        <bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
                <property name="providers">
                        <list>
index 1c1a3788bd7938656248388c1e5376d28aa9a9f2..fab34323af2bfd93f5ebd805b14cca6230df46c8 100644 (file)
@@ -20,8 +20,8 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
 import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoJcrUtils;
 import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.JcrUtils;
 import org.argeo.security.UserAdminService;
 import org.argeo.security.jcr.JcrUserDetails;
 import org.argeo.security.ui.admin.SecurityAdminPlugin;
@@ -48,7 +48,7 @@ public class ArgeoUserEditor extends FormEditor {
                super.init(site, input);
                String username = ((ArgeoUserEditorInput) getEditorInput())
                                .getUsername();
-               userHome = JcrUtils.getUserHome(session, username);
+               userHome = ArgeoJcrUtils.getUserHome(session, username);
 
                if (userAdminService.userExists(username)) {
                        userDetails = (JcrUserDetails) userAdminService
index f9a3024ea10770b5cac1be800dee01181bd1a36b..a4cd0edb8a4ee06e89ea8777d819e648b99c625a 100644 (file)
@@ -22,7 +22,9 @@ import javax.jcr.Session;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.eclipse.ui.ErrorFeedback;
+import org.argeo.jcr.ArgeoJcrUtils;
 import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.security.SecurityJcrUtils;
 import org.argeo.security.UserAdminService;
 import org.argeo.security.jcr.JcrUserDetails;
 import org.eclipse.jface.wizard.Wizard;
@@ -55,7 +57,7 @@ public class NewUserWizard extends Wizard {
 
                String username = mainUserInfo.getUsername();
                try {
-                       Node userProfile = JcrUtils.createUserProfile(session, username);
+                       Node userProfile = SecurityJcrUtils.createUserProfile(session, username);
                        // session.getWorkspace().getVersionManager()
                        // .checkout(userProfile.getPath());
                        mainUserInfo.mapToProfileNode(userProfile);
@@ -70,7 +72,7 @@ public class NewUserWizard extends Wizard {
                        return true;
                } catch (Exception e) {
                        JcrUtils.discardQuietly(session);
-                       Node userHome = JcrUtils.getUserHome(session, username);
+                       Node userHome = ArgeoJcrUtils.getUserHome(session, username);
                        if (userHome != null) {
                                try {
                                        userHome.remove();
index 2d5bcb7092753be7b5c1651f87a591dec9aa18bf..258a08e4c5be2c9cc18b1d6742c64db72a07682d 100644 (file)
@@ -21,22 +21,22 @@ import java.util.concurrent.Future;
 
 /**
  * Allows to execute code authenticated as a system user (that is not a real
- * person). The {@link Executor} interface interface is not used directly in
- * order to allow future extension of this interface and to simplify its
- * publication (e.g. as an OSGi service) and interception.
+ * person). The {@link Executor} interface is not used directly in order to
+ * allow future extension of this interface and to simplify its publication
+ * (e.g. as an OSGi service) and interception.
  */
 public interface SystemExecutionService extends Executor {
        /**
         * Executes this {@link Runnable} within a system authenticated context.
         * Implementations should make sure that this method is properly secured via
-        * Java permissions since it could access to everything without credentials.
+        * Java permissions since it could access everything without credentials.
         */
        public void execute(Runnable runnable);
-       
+
        /**
         * Executes this {@link Callable} within a system authenticated context.
         * Implementations should make sure that this method is properly secured via
-        * Java permissions since it could access to everything without credentials.
+        * Java permissions since it could access everything without credentials.
         */
        public <T> Future<T> submit(Callable<T> task);
 }
index 88ea425902d3254792096059a2c282cc77762005..1a19ecb20c1a030c9bc82fefa92edc0b6e509653 100644 (file)
@@ -24,7 +24,7 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
 import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.security.SecurityJcrUtils;
 import org.springframework.security.BadCredentialsException;
 import org.springframework.security.DisabledException;
 import org.springframework.security.GrantedAuthority;
@@ -90,7 +90,7 @@ public class JcrUserDetails extends User implements ArgeoNames {
         */
        public JcrUserDetails(Session session, String username, String password,
                        GrantedAuthority[] authorities) throws RepositoryException {
-               this(JcrUtils.getUserProfile(session, username),
+               this(SecurityJcrUtils.getUserProfile(session, username),
                                password != null ? password : "", authorities);
        }
 
index 917733dbcb5a059c5389445908fc4ee27e3885da..d304dc36571d8e41da2dec883179be220bcdd57b 100644 (file)
@@ -22,6 +22,7 @@ import javax.jcr.Session;
 
 import org.argeo.ArgeoException;
 import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.security.SecurityJcrUtils;
 import org.argeo.security.OsAuthenticationToken;
 import org.argeo.security.core.OsAuthenticationProvider;
 import org.springframework.security.Authentication;
@@ -76,13 +77,13 @@ public class OsJcrAuthenticationProvider extends OsAuthenticationProvider {
                                // WARNING: at this stage we assume that the java properties
                                // will have the same value
                                String username = System.getProperty("user.name");
-                               Node userProfile = JcrUtils.createUserProfileIfNeeded(
+                               Node userProfile = SecurityJcrUtils.createUserProfileIfNeeded(
                                                securitySession, username);
                                JcrUserDetails.checkAccountStatus(userProfile);
 
                                // each user should have a writable area in the default
                                // workspace of the node
-                               JcrUtils.createUserHomeIfNeeded(nodeSession, username);
+                               SecurityJcrUtils.createUserHomeIfNeeded(nodeSession, username);
                                userDetails = new JcrUserDetails(userProfile, authen
                                                .getCredentials().toString(), getBaseAuthorities());
                                authen.setDetails(userDetails);
index 483cc408df823654067c055e61671c752b5217f0..80ef1e55963d99544c3194896d9584f2419fb39c 100644 (file)
@@ -10,6 +10,7 @@ import javax.jcr.Session;
 
 import org.argeo.ArgeoException;
 import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.security.SecurityJcrUtils;
 import org.argeo.security.UserAdminService;
 import org.springframework.dao.DataAccessException;
 import org.springframework.security.userdetails.UserDetails;
@@ -67,7 +68,7 @@ public class OsJcrUserAdminService implements UserAdminService {
        public UserDetails loadUserByUsername(String username)
                        throws UsernameNotFoundException, DataAccessException {
                if (getSPropertyUsername().equals(username)) {
-                       Node userProfile = JcrUtils.getUserProfile(securitySession,
+                       Node userProfile = SecurityJcrUtils.getUserProfile(securitySession,
                                        username);
                        JcrUserDetails userDetails;
                        try {
index 7087536a338490d4298c0b7ccd07e8c6df6a4281..62dc982147b66334e8adc3ee97a457c2e9add0e5 100644 (file)
@@ -31,8 +31,8 @@ import javax.jcr.Value;
 
 import org.argeo.ArgeoException;
 import org.argeo.jcr.ArgeoJcrConstants;
+import org.argeo.jcr.ArgeoJcrUtils;
 import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.JcrUtils;
 import org.argeo.security.NodeAuthenticationToken;
 import org.springframework.security.Authentication;
 import org.springframework.security.AuthenticationException;
@@ -65,7 +65,7 @@ public class RemoteJcrAuthenticationProvider implements AuthenticationProvider,
 
                        String workspace = siteAuth.getSecurityWorkspace();
                        session = repository.login(sp, workspace);
-                       Node userHome = JcrUtils.getUserHome(session);
+                       Node userHome = ArgeoJcrUtils.getUserHome(session);
                        if (userHome == null || !userHome.hasNode(ArgeoNames.ARGEO_PROFILE))
                                throw new ArgeoException("No profile for user "
                                                + siteAuth.getName() + " in security workspace "
index 1109980696d61d110aab683ddbde53f937286d4b..4af5d3f3d5a53997b79418e7a019d7c0f8e8cc4c 100644 (file)
@@ -17,26 +17,16 @@ package org.argeo.security.jackrabbit;
 
 import java.security.Principal;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
-import javax.jcr.Node;
-import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
-import javax.jcr.Value;
-import javax.jcr.ValueFactory;
-import javax.jcr.security.Privilege;
 import javax.security.auth.Subject;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
-import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
-import org.apache.jackrabbit.api.security.JackrabbitAccessControlPolicy;
 import org.apache.jackrabbit.api.security.user.Group;
 import org.apache.jackrabbit.api.security.user.User;
 import org.apache.jackrabbit.api.security.user.UserManager;
@@ -45,11 +35,10 @@ import org.apache.jackrabbit.core.security.AnonymousPrincipal;
 import org.apache.jackrabbit.core.security.SecurityConstants;
 import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager;
 import org.argeo.ArgeoException;
-import org.argeo.jcr.JcrUtils;
 import org.springframework.security.Authentication;
 import org.springframework.security.GrantedAuthority;
 
-/** Intermediary class in order to have a consistent naming in config files. */
+/** Integrates Spring Security and Jackrabbit Security user and roles. */
 public class ArgeoSecurityManager extends DefaultSecurityManager {
        private Log log = LogFactory.getLog(ArgeoSecurityManager.class);
 
@@ -61,8 +50,6 @@ public class ArgeoSecurityManager extends DefaultSecurityManager {
        @Override
        public String getUserID(Subject subject, String workspaceName)
                        throws RepositoryException {
-               long begin = System.currentTimeMillis();
-
                if (log.isTraceEnabled())
                        log.trace(subject);
                // skip anonymous user (no rights)
@@ -72,6 +59,8 @@ public class ArgeoSecurityManager extends DefaultSecurityManager {
                if (!subject.getPrincipals(ArgeoSystemPrincipal.class).isEmpty())
                        return super.getUserID(subject, workspaceName);
 
+               // retrieve Spring authentication from JAAS
+               // TODO? use Spring Security context holder
                Authentication authen;
                Set<Authentication> authens = subject
                                .getPrincipals(Authentication.class);
@@ -81,16 +70,32 @@ public class ArgeoSecurityManager extends DefaultSecurityManager {
                else
                        authen = authens.iterator().next();
 
-               UserManager systemUm = getSystemUserManager(workspaceName);
+               // sync Spring and Jackrabbit
+               syncSpringAndJackrabbitSecurity(authen);
+
+               return authen.getName();
+       }
+
+       /**
+        * Make sure that the Jackrabbit security model contains this user and its
+        * granted authorities
+        */
+       protected void syncSpringAndJackrabbitSecurity(Authentication authen)
+                       throws RepositoryException {
+               long begin = System.currentTimeMillis();
+
+               // workspace is irrelevant here
+               UserManager systemUm = getSystemUserManager(null);
 
                String userId = authen.getName();
                User user = (User) systemUm.getAuthorizable(userId);
                if (user == null) {
                        user = systemUm.createUser(userId, authen.getCredentials()
                                        .toString(), authen, null);
-                       JcrUtils.createUserHomeIfNeeded(getSystemSession(), userId);
-                       getSystemSession().save();
-                       setSecurityHomeAuthorizations(user);
+                       // SecurityJcrUtils.createUserHomeIfNeeded(getSystemSession(),
+                       // userId);
+                       // getSystemSession().save();
+                       // setSecurityHomeAuthorizations(user);
                        log.info(userId + " added as " + user);
                }
 
@@ -118,51 +123,51 @@ public class ArgeoSecurityManager extends DefaultSecurityManager {
                        log.trace("Spring and Jackrabbit Security synchronized for user "
                                        + userId + " in " + (System.currentTimeMillis() - begin)
                                        + " ms");
-               return userId;
        }
 
-       protected synchronized void setSecurityHomeAuthorizations(User user) {
-               // give read privileges on user security home
-               String userId = "<not yet set>";
-               try {
-                       userId = user.getID();
-                       Node userHome = JcrUtils.getUserHome(getSystemSession(), userId);
-                       if (userHome == null)
-                               throw new ArgeoException("No security home available for user "
-                                               + userId);
-
-                       String path = userHome.getPath();
-                       Principal principal = user.getPrincipal();
-
-                       JackrabbitAccessControlManager acm = (JackrabbitAccessControlManager) getSystemSession()
-                                       .getAccessControlManager();
-                       JackrabbitAccessControlPolicy[] ps = acm
-                                       .getApplicablePolicies(principal);
-                       if (ps.length == 0) {
-                               // log.warn("No ACL found for " + user);
-                               return;
-                       }
-
-                       JackrabbitAccessControlList list = (JackrabbitAccessControlList) ps[0];
-
-                       // add entry
-                       Privilege[] privileges = new Privilege[] { acm
-                                       .privilegeFromName(Privilege.JCR_READ) };
-                       Map<String, Value> restrictions = new HashMap<String, Value>();
-                       ValueFactory vf = getSystemSession().getValueFactory();
-                       restrictions.put("rep:nodePath",
-                                       vf.createValue(path, PropertyType.PATH));
-                       restrictions.put("rep:glob", vf.createValue("*"));
-                       list.addEntry(principal, privileges, true /* allow or deny */,
-                                       restrictions);
-               } catch (Exception e) {
-                       e.printStackTrace();
-                       throw new ArgeoException(
-                                       "Cannot set authorization on security home for " + userId
-                                                       + ": " + e.getMessage());
-               }
-
-       }
+       // protected synchronized void setSecurityHomeAuthorizations(User user) {
+       // // give read privileges on user security home
+       // String userId = "<not yet set>";
+       // try {
+       // userId = user.getID();
+       // Node userHome = SecurityJcrUtils.getUserHome(getSystemSession(), userId);
+       // if (userHome == null)
+       // throw new ArgeoException("No security home available for user "
+       // + userId);
+       //
+       // String path = userHome.getPath();
+       // Principal principal = user.getPrincipal();
+       //
+       // JackrabbitAccessControlManager acm = (JackrabbitAccessControlManager)
+       // getSystemSession()
+       // .getAccessControlManager();
+       // JackrabbitAccessControlPolicy[] ps = acm
+       // .getApplicablePolicies(principal);
+       // if (ps.length == 0) {
+       // // log.warn("No ACL found for " + user);
+       // return;
+       // }
+       //
+       // JackrabbitAccessControlList list = (JackrabbitAccessControlList) ps[0];
+       //
+       // // add entry
+       // Privilege[] privileges = new Privilege[] { acm
+       // .privilegeFromName(Privilege.JCR_READ) };
+       // Map<String, Value> restrictions = new HashMap<String, Value>();
+       // ValueFactory vf = getSystemSession().getValueFactory();
+       // restrictions.put("rep:nodePath",
+       // vf.createValue(path, PropertyType.PATH));
+       // restrictions.put("rep:glob", vf.createValue("*"));
+       // list.addEntry(principal, privileges, true /* allow or deny */,
+       // restrictions);
+       // } catch (Exception e) {
+       // e.printStackTrace();
+       // throw new ArgeoException(
+       // "Cannot set authorization on security home for " + userId
+       // + ": " + e.getMessage());
+       // }
+       //
+       // }
 
        @Override
        protected WorkspaceAccessManager createDefaultWorkspaceAccessManager() {
index 11e8e81998ea449960a1fe6e0a89f360372dd64d..178785602d5aa7eff0ad8d5583c39210f0350fb0 100644 (file)
@@ -59,6 +59,7 @@ import org.argeo.ArgeoException;
 import org.argeo.jcr.ArgeoNames;
 import org.argeo.jcr.ArgeoTypes;
 import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.security.SecurityJcrUtils;
 import org.argeo.security.jcr.JcrUserDetails;
 import org.springframework.ldap.core.ContextExecutor;
 import org.springframework.ldap.core.ContextMapper;
@@ -223,9 +224,10 @@ public class JcrLdapSynchronizer implements UserDetailsContextMapper,
        /** Called during authentication in order to retrieve user details */
        public UserDetails mapUserFromContext(final DirContextOperations ctx,
                        final String username, GrantedAuthority[] authorities) {
+               log.debug("mapUserFromContext");
                if (ctx == null)
                        throw new ArgeoException("No LDAP information for user " + username);
-               Node userProfile = JcrUtils.createUserProfileIfNeeded(securitySession,
+               Node userProfile = SecurityJcrUtils.createUserProfileIfNeeded(securitySession,
                                username);
                JcrUserDetails.checkAccountStatus(userProfile);
 
@@ -260,7 +262,7 @@ public class JcrLdapSynchronizer implements UserDetailsContextMapper,
                try {
                        // process
                        String username = ctx.getStringAttribute(usernameAttribute);
-                       Node userHome = JcrUtils.createUserHomeIfNeeded(session, username);
+                       Node userHome = SecurityJcrUtils.createUserHomeIfNeeded(session, username);
                        Node userProfile; // = userHome.getNode(ARGEO_PROFILE);
                        if (userHome.hasNode(ARGEO_PROFILE)) {
                                userProfile = userHome.getNode(ARGEO_PROFILE);
@@ -279,7 +281,7 @@ public class JcrLdapSynchronizer implements UserDetailsContextMapper,
                                                        .checkin(userProfile.getPath());
                                }
                        } else {
-                               userProfile = JcrUtils.createUserProfile(securitySession,
+                               userProfile = SecurityJcrUtils.createUserProfile(securitySession,
                                                username);
                                userProfile.getSession().save();
                                userProfile.getSession().getWorkspace().getVersionManager()
index 1db81167d521c4a851f3de1a28f5dcd6882f8c2b..72c120728354e660c2e7edf9d1fb9937e85a23f2 100644 (file)
@@ -23,6 +23,7 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
 import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoJcrUtils;
 import org.argeo.jcr.ArgeoNames;
 import org.argeo.jcr.JcrUtils;
 import org.argeo.security.jcr.JcrUserDetails;
@@ -32,7 +33,8 @@ import org.springframework.security.GrantedAuthority;
 import org.springframework.security.userdetails.UserDetails;
 import org.springframework.security.userdetails.ldap.UserDetailsContextMapper;
 
-/** Read only mapping from LDAP to user details */
+/** @deprecated Read only mapping from LDAP to user details */
+@Deprecated
 public class JcrUserDetailsContextMapper implements UserDetailsContextMapper,
                ArgeoNames {
        /** Admin session on the security workspace */
@@ -59,7 +61,7 @@ public class JcrUserDetailsContextMapper implements UserDetailsContextMapper,
                        final String username, GrantedAuthority[] authorities) {
                if (ctx == null)
                        throw new ArgeoException("No LDAP information for user " + username);
-               Node userHome = JcrUtils.getUserHome(securitySession, username);
+               Node userHome = ArgeoJcrUtils.getUserHome(securitySession, username);
                if (userHome == null)
                        throw new ArgeoException("No JCR information for user " + username);
 
index d57c98974270f086a7e52828e7e956c2fa46e58f..e3bad2892c67863294363d95c962470213b05560 100644 (file)
@@ -22,7 +22,6 @@
 
        <bean id="addRemoteRepository" class="org.argeo.jcr.ui.explorer.commands.AddRemoteRepository">
                <property name="repositoryFactory" ref="repositoryFactory" />
-               <property name="bundleContext" ref="bundleContext" />
                <property name="keyring" ref="jcrKeyring" />
        </bean>
 
index 8591a4d35262c1eeefc57b20df714b16c87a7bf9..b4e3ca45ca1bc62d10646799ace4a27a4bf26d9a 100644 (file)
@@ -17,8 +17,6 @@ package org.argeo.jcr.ui.explorer;
 
 /** Constants used across the application. */
 public interface JcrExplorerConstants {
-       public final static String PARAM_REPOSITORY_URI = "org.argeo.jcr.ui.explorer.repositoryUri";
-
        /*
         * MISCEALLENEOUS
         */
index 36c44d01d71f732275adb69fa3f3b2fc7cc6bac8..a1aca2b20ca3e608612e08184a1adcae67b92206 100644 (file)
@@ -25,7 +25,7 @@ import javax.jcr.Session;
 
 import org.argeo.eclipse.ui.TreeParent;
 import org.argeo.jcr.ArgeoJcrConstants;
-import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.ArgeoJcrUtils;
 import org.argeo.jcr.RepositoryRegister;
 import org.argeo.jcr.security.JcrKeyring;
 import org.argeo.jcr.ui.explorer.model.RepositoriesNode;
@@ -72,7 +72,7 @@ public class NodeContentProvider implements ITreeContentProvider {
                        return;
 
                if (userSession != null) {
-                       Node userHome = JcrUtils.getUserHome(userSession);
+                       Node userHome = ArgeoJcrUtils.getUserHome(userSession);
                        if (userHome != null) {
                                // TODO : find a way to dynamically get alias for the node
                                if (homeNode != null)
index 6b5dfa8b0c490bafaa37059d6b38098b7e9e962b..7f101b8bc36e246634b4226af35270449ce95cf2 100644 (file)
@@ -27,10 +27,12 @@ import javax.jcr.SimpleCredentials;
 import org.argeo.ArgeoException;
 import org.argeo.eclipse.ui.ErrorFeedback;
 import org.argeo.jcr.ArgeoJcrConstants;
+import org.argeo.jcr.ArgeoJcrUtils;
 import org.argeo.jcr.ArgeoNames;
 import org.argeo.jcr.ArgeoTypes;
 import org.argeo.jcr.JcrUtils;
 import org.argeo.jcr.security.JcrKeyring;
+import org.argeo.jcr.security.SecurityJcrUtils;
 import org.argeo.jcr.ui.explorer.JcrExplorerConstants;
 import org.eclipse.core.commands.AbstractHandler;
 import org.eclipse.core.commands.ExecutionEvent;
@@ -52,7 +54,6 @@ import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Text;
-import org.osgi.framework.BundleContext;
 
 /**
  * Connect to a remote repository and, if successful publish it as an OSGi
@@ -62,37 +63,13 @@ public class AddRemoteRepository extends AbstractHandler implements
                JcrExplorerConstants, ArgeoNames {
 
        private RepositoryFactory repositoryFactory;
-       private BundleContext bundleContext;
-
        private JcrKeyring keyring;
 
        public Object execute(ExecutionEvent event) throws ExecutionException {
-               String uri = null;
-               if (event.getParameters().containsKey(PARAM_REPOSITORY_URI)) {
-                       // FIXME remove this
-                       uri = event.getParameter(PARAM_REPOSITORY_URI);
-                       if (uri == null)
-                               return null;
-
-                       try {
-                               Hashtable<String, String> params = new Hashtable<String, String>();
-                               params.put(ArgeoJcrConstants.JCR_REPOSITORY_URI, uri);
-                               // by default we use the URI as alias
-                               params.put(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS, uri);
-                               Repository repository = repositoryFactory.getRepository(params);
-                               bundleContext.registerService(Repository.class.getName(),
-                                               repository, params);
-                       } catch (Exception e) {
-                               ErrorFeedback.show("Cannot add remote repository " + uri, e);
-                       }
-               } else {
-                       RemoteRepositoryLoginDialog dlg = new RemoteRepositoryLoginDialog(
-                                       Display.getDefault().getActiveShell());
-                       if (dlg.open() == Dialog.OK) {
-                               // uri = dlg.getUri();
-                       }
+               RemoteRepositoryLoginDialog dlg = new RemoteRepositoryLoginDialog(
+                               Display.getDefault().getActiveShell());
+               if (dlg.open() == Dialog.OK) {
                }
-
                return null;
        }
 
@@ -100,10 +77,6 @@ public class AddRemoteRepository extends AbstractHandler implements
                this.repositoryFactory = repositoryFactory;
        }
 
-       public void setBundleContext(BundleContext bundleContext) {
-               this.bundleContext = bundleContext;
-       }
-
        public void setKeyring(JcrKeyring keyring) {
                this.keyring = keyring;
        }
@@ -162,9 +135,6 @@ public class AddRemoteRepository extends AbstractHandler implements
 
                                Hashtable<String, String> params = new Hashtable<String, String>();
                                params.put(ArgeoJcrConstants.JCR_REPOSITORY_URI, checkedUriStr);
-                               // by default we use the URI as alias
-                               params.put(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS,
-                                               checkedUriStr);
                                Repository repository = repositoryFactory.getRepository(params);
                                if (username.getText().trim().equals("")) {// anonymous
                                        session = repository.login();
@@ -190,11 +160,11 @@ public class AddRemoteRepository extends AbstractHandler implements
                protected void okPressed() {
                        try {
                                Session nodeSession = keyring.getSession();
-                               Node home = JcrUtils.getUserHome(nodeSession);
+                               Node home = ArgeoJcrUtils.getUserHome(nodeSession);
 
                                // FIXME better deal with non existing home dir
                                if (home == null)
-                                       home = JcrUtils.createUserHomeIfNeeded(nodeSession,
+                                       home = SecurityJcrUtils.createUserHomeIfNeeded(nodeSession,
                                                        nodeSession.getUserID());
 
                                Node remote = home.hasNode(ARGEO_REMOTE) ? home
index 975c87cba480d48f9414e46f647579e2e60e3ca9..3289b420da16542bc1870e6eee524a0d7b346d43 100644 (file)
@@ -29,8 +29,8 @@ import org.argeo.ArgeoException;
 import org.argeo.eclipse.ui.ErrorFeedback;
 import org.argeo.eclipse.ui.TreeParent;
 import org.argeo.jcr.ArgeoJcrConstants;
+import org.argeo.jcr.ArgeoJcrUtils;
 import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.JcrUtils;
 import org.argeo.jcr.RepositoryRegister;
 import org.argeo.jcr.security.JcrKeyring;
 
@@ -93,7 +93,7 @@ public class RepositoriesNode extends TreeParent implements ArgeoNames {
        protected void addRemoteRepositories(JcrKeyring jcrKeyring)
                        throws RepositoryException {
                Session userSession = jcrKeyring.getSession();
-               Node userHome = JcrUtils.getUserHome(userSession);
+               Node userHome = ArgeoJcrUtils.getUserHome(userSession);
                if (userHome != null && userHome.hasNode(ARGEO_REMOTE)) {
                        NodeIterator it = userHome.getNode(ARGEO_REMOTE).getNodes();
                        while (it.hasNext()) {
index af06ba22074a1e863dea1dc60a354367614bf164..e8c0cb7a29871794f0f0c07e4ba6236fd44fabb4 100644 (file)
@@ -47,9 +47,11 @@ public class JcrUiUtils {
                                doRefresh = true;
                        else if (element instanceof RepositoryNode) {
                                RepositoryNode rn = (RepositoryNode) element;
-                               String[] wkpNames = rn.getAccessibleWorkspaceNames();
-                               if (element.getChildren().length != wkpNames.length)
-                                       doRefresh = true;
+                               if (rn.isConnected()) {
+                                       String[] wkpNames = rn.getAccessibleWorkspaceNames();
+                                       if (element.getChildren().length != wkpNames.length)
+                                               doRefresh = true;
+                               }
                        } else if (element instanceof RepositoriesNode) {
                                RepositoriesNode rn = (RepositoriesNode) element;
                                if (element.getChildren().length != rn.getRepositoryRegister()
index 12315930b61995cca0fc48625da9e845252592b3..54e12bd7d52226110eaed212c41b9d61849964d3 100644 (file)
@@ -40,6 +40,7 @@ import org.apache.jackrabbit.api.security.user.User;
 import org.apache.jackrabbit.api.security.user.UserManager;
 import org.apache.jackrabbit.server.SessionProvider;
 import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoJcrUtils;
 import org.argeo.jcr.ArgeoNames;
 import org.argeo.jcr.JcrUtils;
 
@@ -118,7 +119,7 @@ public class SimpleSessionProvider implements SessionProvider, Serializable {
                                userGroupIds.add(it.next().getID());
 
                // write roles if needed
-               Node userProfile = JcrUtils.getUserHome(session).getNode(
+               Node userProfile = ArgeoJcrUtils.getUserHome(session).getNode(
                                ArgeoNames.ARGEO_PROFILE);
                boolean writeRoles = false;
                if (userProfile.hasProperty(ArgeoNames.ARGEO_REMOTE_ROLES)) {
diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ArgeoJcrUtils.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ArgeoJcrUtils.java
new file mode 100644 (file)
index 0000000..b0d7757
--- /dev/null
@@ -0,0 +1,103 @@
+package org.argeo.jcr;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.RepositoryFactory;
+import javax.jcr.Session;
+
+import org.argeo.ArgeoException;
+
+/** Utilities related to Argeo model in JCR */
+public class ArgeoJcrUtils implements ArgeoJcrConstants {
+       /**
+        * Returns the home node of the session user or null if none was found.
+        * 
+        * @param session
+        *            the session to use in order to perform the search, this can be
+        *            a session with a different user ID than the one searched,
+        *            typically when a system or admin session is used.
+        * @param username
+        *            the username of the user
+        */
+       public static Node getUserHome(Session session, String username) {
+               try {
+                       String homePath = ArgeoJcrUtils.getUserHomePath(username);
+                       return session.itemExists(homePath) ? session.getNode(homePath)
+                                       : null;
+                       // kept for example of QOM queries
+                       // QueryObjectModelFactory qomf = session.getWorkspace()
+                       // .getQueryManager().getQOMFactory();
+                       // Selector userHomeSel = qomf.selector(ArgeoTypes.ARGEO_USER_HOME,
+                       // "userHome");
+                       // DynamicOperand userIdDop = qomf.propertyValue("userHome",
+                       // ArgeoNames.ARGEO_USER_ID);
+                       // StaticOperand userIdSop = qomf.literal(session.getValueFactory()
+                       // .createValue(username));
+                       // Constraint constraint = qomf.comparison(userIdDop,
+                       // QueryObjectModelFactory.JCR_OPERATOR_EQUAL_TO, userIdSop);
+                       // Query query = qomf.createQuery(userHomeSel, constraint, null,
+                       // null);
+                       // Node userHome = JcrUtils.querySingleNode(query);
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot find home for user " + username, e);
+               }
+       }
+
+       /** Returns the home node of the session user or null if none was found. */
+       public static Node getUserHome(Session session) {
+               String userID = session.getUserID();
+               return getUserHome(session, userID);
+       }
+
+       /** @deprecated Use {@link #getUserHome(Session, String)} directly */
+       @Deprecated
+       public static String getUserHomePath(String username) {
+               String homeBasePath = DEFAULT_HOME_BASE_PATH;
+               return homeBasePath + '/' + JcrUtils.firstCharsToPath(username, 2)
+                               + '/' + username;
+       }
+
+       /**
+        * Wraps the call to the repository factory based on parameter
+        * {@link ArgeoJcrConstants#JCR_REPOSITORY_ALIAS} in order to simplify it
+        * and protect against future API changes.
+        */
+       public static Repository getRepositoryByAlias(
+                       RepositoryFactory repositoryFactory, String alias) {
+               try {
+                       Map<String, String> parameters = new HashMap<String, String>();
+                       parameters.put(JCR_REPOSITORY_ALIAS, alias);
+                       return repositoryFactory.getRepository(parameters);
+               } catch (RepositoryException e) {
+                       throw new ArgeoException(
+                                       "Unexpected exception when trying to retrieve repository with alias "
+                                                       + alias, e);
+               }
+       }
+
+       /**
+        * Wraps the call to the repository factory based on parameter
+        * {@link ArgeoJcrConstants#JCR_REPOSITORY_URI} in order to simplify it and
+        * protect against future API changes.
+        */
+       public static Repository getRepositoryByUri(
+                       RepositoryFactory repositoryFactory, String uri) {
+               try {
+                       Map<String, String> parameters = new HashMap<String, String>();
+                       parameters.put(JCR_REPOSITORY_URI, uri);
+                       return repositoryFactory.getRepository(parameters);
+               } catch (RepositoryException e) {
+                       throw new ArgeoException(
+                                       "Unexpected exception when trying to retrieve repository with uri "
+                                                       + uri, e);
+               }
+       }
+
+       private ArgeoJcrUtils() {
+       }
+
+}
index e7b3656cfd8e5e7e195a873924f65b92c95eefcb..3364ebfea896fbb79d391756bb8ec4cd27ae6e8e 100644 (file)
@@ -31,7 +31,6 @@ import java.util.Calendar;
 import java.util.Collections;
 import java.util.Date;
 import java.util.GregorianCalendar;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -47,7 +46,6 @@ import javax.jcr.PropertyIterator;
 import javax.jcr.PropertyType;
 import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
 import javax.jcr.Session;
 import javax.jcr.Value;
 import javax.jcr.Workspace;
@@ -61,7 +59,6 @@ import javax.jcr.security.AccessControlManager;
 import javax.jcr.security.AccessControlPolicy;
 import javax.jcr.security.AccessControlPolicyIterator;
 import javax.jcr.security.Privilege;
-import javax.jcr.version.VersionManager;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
@@ -1046,42 +1043,6 @@ public class JcrUtils implements ArgeoJcrConstants {
                return path.toString();
        }
 
-       /**
-        * Wraps the call to the repository factory based on parameter
-        * {@link ArgeoJcrConstants#JCR_REPOSITORY_ALIAS} in order to simplify it
-        * and protect against future API changes.
-        */
-       public static Repository getRepositoryByAlias(
-                       RepositoryFactory repositoryFactory, String alias) {
-               try {
-                       Map<String, String> parameters = new HashMap<String, String>();
-                       parameters.put(JCR_REPOSITORY_ALIAS, alias);
-                       return repositoryFactory.getRepository(parameters);
-               } catch (RepositoryException e) {
-                       throw new ArgeoException(
-                                       "Unexpected exception when trying to retrieve repository with alias "
-                                                       + alias, e);
-               }
-       }
-
-       /**
-        * Wraps the call to the repository factory based on parameter
-        * {@link ArgeoJcrConstants#JCR_REPOSITORY_URI} in order to simplify it and
-        * protect against future API changes.
-        */
-       public static Repository getRepositoryByUri(
-                       RepositoryFactory repositoryFactory, String uri) {
-               try {
-                       Map<String, String> parameters = new HashMap<String, String>();
-                       parameters.put(JCR_REPOSITORY_URI, uri);
-                       return repositoryFactory.getRepository(parameters);
-               } catch (RepositoryException e) {
-                       throw new ArgeoException(
-                                       "Unexpected exception when trying to retrieve repository with uri "
-                                                       + uri, e);
-               }
-       }
-
        /**
         * Discards the current changes in the session attached to this node. To be
         * used typically in a catch block.
@@ -1176,235 +1137,6 @@ public class JcrUtils implements ArgeoJcrConstants {
                }
        }
 
-       /** Returns the home node of the session user or null if none was found. */
-       public static Node getUserHome(Session session) {
-               String userID = session.getUserID();
-               return getUserHome(session, userID);
-       }
-
-       /** User home path is NOT configurable */
-       public static String getUserHomePath(String username) {
-               String homeBasePath = DEFAULT_HOME_BASE_PATH;
-               return homeBasePath + '/' + firstCharsToPath(username, 2) + '/'
-                               + username;
-       }
-
-       /**
-        * Returns the home node of the session user or null if none was found.
-        * 
-        * @param session
-        *            the session to use in order to perform the search, this can be
-        *            a session with a different user ID than the one searched,
-        *            typically when a system or admin session is used.
-        * @param username
-        *            the username of the user
-        */
-       public static Node getUserHome(Session session, String username) {
-               try {
-                       String homePath = getUserHomePath(username);
-                       return session.itemExists(homePath) ? session.getNode(homePath)
-                                       : null;
-                       // kept for example of QOM queries
-                       // QueryObjectModelFactory qomf = session.getWorkspace()
-                       // .getQueryManager().getQOMFactory();
-                       // Selector userHomeSel = qomf.selector(ArgeoTypes.ARGEO_USER_HOME,
-                       // "userHome");
-                       // DynamicOperand userIdDop = qomf.propertyValue("userHome",
-                       // ArgeoNames.ARGEO_USER_ID);
-                       // StaticOperand userIdSop = qomf.literal(session.getValueFactory()
-                       // .createValue(username));
-                       // Constraint constraint = qomf.comparison(userIdDop,
-                       // QueryObjectModelFactory.JCR_OPERATOR_EQUAL_TO, userIdSop);
-                       // Query query = qomf.createQuery(userHomeSel, constraint, null,
-                       // null);
-                       // Node userHome = JcrUtils.querySingleNode(query);
-               } catch (RepositoryException e) {
-                       throw new ArgeoException("Cannot find home for user " + username, e);
-               }
-       }
-
-       /**
-        * Creates an Argeo user home, does nothing if it already exists. Session is
-        * NOT saved.
-        */
-       public static Node createUserHomeIfNeeded(Session session, String username) {
-               try {
-                       String homePath = getUserHomePath(username);
-                       if (session.itemExists(homePath))
-                               return session.getNode(homePath);
-                       else {
-                               Node userHome = JcrUtils.mkdirs(session, homePath);
-                               userHome.addMixin(ArgeoTypes.ARGEO_USER_HOME);
-                               userHome.setProperty(ArgeoNames.ARGEO_USER_ID, username);
-                               return userHome;
-                       }
-               } catch (RepositoryException e) {
-                       discardQuietly(session);
-                       throw new ArgeoException("Cannot create home for " + username
-                                       + " in workspace " + session.getWorkspace().getName(), e);
-               }
-       }
-
-       /**
-        * Creates a user profile in the home of this user. Creates the home if
-        * needed, but throw an exception if a profile already exists. The session
-        * is not saved and the node is in a checkedOut state (that is, it requires
-        * a subsequent checkin after saving the session).
-        */
-       public static Node createUserProfile(Session session, String username) {
-               try {
-                       Node userHome = createUserHomeIfNeeded(session, username);
-                       if (userHome.hasNode(ArgeoNames.ARGEO_PROFILE))
-                               throw new ArgeoException(
-                                               "There is already a user profile under " + userHome);
-                       Node userProfile = userHome.addNode(ArgeoNames.ARGEO_PROFILE);
-                       userProfile.addMixin(ArgeoTypes.ARGEO_USER_PROFILE);
-                       userProfile.setProperty(ArgeoNames.ARGEO_USER_ID, username);
-                       userProfile.setProperty(ArgeoNames.ARGEO_ENABLED, true);
-                       userProfile.setProperty(ArgeoNames.ARGEO_ACCOUNT_NON_EXPIRED, true);
-                       userProfile.setProperty(ArgeoNames.ARGEO_ACCOUNT_NON_LOCKED, true);
-                       userProfile.setProperty(ArgeoNames.ARGEO_CREDENTIALS_NON_EXPIRED,
-                                       true);
-                       return userProfile;
-               } catch (RepositoryException e) {
-                       discardQuietly(session);
-                       throw new ArgeoException("Cannot create user profile for "
-                                       + username + " in workspace "
-                                       + session.getWorkspace().getName(), e);
-               }
-       }
-
-       /**
-        * Create user profile if needed, the session IS saved.
-        * 
-        * @return the user profile
-        */
-       public static Node createUserProfileIfNeeded(Session securitySession,
-                       String username) {
-               try {
-                       Node userHome = JcrUtils.createUserHomeIfNeeded(securitySession,
-                                       username);
-                       Node userProfile = userHome.hasNode(ArgeoNames.ARGEO_PROFILE) ? userHome
-                                       .getNode(ArgeoNames.ARGEO_PROFILE) : JcrUtils
-                                       .createUserProfile(securitySession, username);
-                       if (securitySession.hasPendingChanges())
-                               securitySession.save();
-                       VersionManager versionManager = securitySession.getWorkspace()
-                                       .getVersionManager();
-                       if (versionManager.isCheckedOut(userProfile.getPath()))
-                               versionManager.checkin(userProfile.getPath());
-                       return userProfile;
-               } catch (RepositoryException e) {
-                       discardQuietly(securitySession);
-                       throw new ArgeoException("Cannot create user profile for "
-                                       + username + " in workspace "
-                                       + securitySession.getWorkspace().getName(), e);
-               }
-       }
-
-       /** Creates an Argeo user home. */
-       // public static Node createUserHome(Session session, String homeBasePath,
-       // String username) {
-       // try {
-       // if (session == null)
-       // throw new ArgeoException("Session is null");
-       // if (session.hasPendingChanges())
-       // throw new ArgeoException(
-       // "Session has pending changes, save them first");
-       //
-       // String homePath = getUserHomePath(username);
-       //
-       // if (session.itemExists(homePath)) {
-       // try {
-       // throw new ArgeoException(
-       // "Trying to create a user home that already exists");
-       // } catch (Exception e) {
-       // // we use this workaround to be sure to get the stack trace
-       // // to identify the sink of the bug.
-       // log.warn("trying to create an already existing userHome at path:"
-       // + homePath + ". Stack trace : ");
-       // e.printStackTrace();
-       // }
-       // }
-       //
-       // Node userHome = JcrUtils.mkdirs(session, homePath);
-       // Node userProfile;
-       // if (userHome.hasNode(ArgeoNames.ARGEO_PROFILE)) {
-       // log.warn("userProfile node already exists for userHome path: "
-       // + homePath + ". We do not add a new one");
-       // } else {
-       // userProfile = userHome.addNode(ArgeoNames.ARGEO_PROFILE);
-       // userProfile.addMixin(ArgeoTypes.ARGEO_USER_PROFILE);
-       // // session.getWorkspace().getVersionManager()
-       // // .checkout(userProfile.getPath());
-       // userProfile.setProperty(ArgeoNames.ARGEO_USER_ID, username);
-       // session.save();
-       // session.getWorkspace().getVersionManager()
-       // .checkin(userProfile.getPath());
-       // // we need to save the profile before adding the user home type
-       // }
-       // userHome.addMixin(ArgeoTypes.ARGEO_USER_HOME);
-       // // see
-       // //
-       // http://jackrabbit.510166.n4.nabble.com/Jackrabbit-2-0-beta-6-Problem-adding-a-Mixin-type-with-mandatory-properties-after-setting-propertiesn-td1290332.html
-       // userHome.setProperty(ArgeoNames.ARGEO_USER_ID, username);
-       // session.save();
-       // return userHome;
-       // } catch (RepositoryException e) {
-       // discardQuietly(session);
-       // throw new ArgeoException("Cannot create home node for user "
-       // + username, e);
-       // }
-       // }
-
-       /**
-        * Returns user home has path, embedding exceptions. Contrary to
-        * {@link #getUserHome(Session)}, it never returns null but throws and
-        * exception if not found.
-        * 
-        * @deprecated use getUserHome() instead, throwing an exception if it
-        *             returns null
-        */
-       @Deprecated
-       public static String getUserHomePath(Session session) {
-               String userID = session.getUserID();
-               try {
-                       String homePath = getUserHomePath(userID);
-                       if (session.itemExists(homePath))
-                               return homePath;
-                       else
-                               throw new ArgeoException("No home registered for " + userID);
-               } catch (RepositoryException e) {
-                       throw new ArgeoException("Cannot find user home path", e);
-               }
-       }
-
-       /**
-        * @return null if not found *
-        */
-       public static Node getUserProfile(Session session, String username) {
-               try {
-                       Node userHome = getUserHome(session, username);
-                       if (userHome == null)
-                               return null;
-                       if (userHome.hasNode(ArgeoNames.ARGEO_PROFILE))
-                               return userHome.getNode(ArgeoNames.ARGEO_PROFILE);
-                       else
-                               return null;
-               } catch (RepositoryException e) {
-                       throw new ArgeoException(
-                                       "Cannot find profile for user " + username, e);
-               }
-       }
-
-       /**
-        * Get the profile of the user attached to this session.
-        */
-       public static Node getUserProfile(Session session) {
-               String userID = session.getUserID();
-               return getUserProfile(session, userID);
-       }
-
        /**
         * Quietly unregisters an {@link EventListener} from the udnerlying
         * workspace of this node.
index e10cccf60fc48c45dac74801654ba8fee0993ea4..91dd202011f261de9e9d7838ef3abfee1dea9319 100644 (file)
@@ -31,6 +31,7 @@ import javax.jcr.Session;
 
 import org.apache.commons.io.IOUtils;
 import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoJcrUtils;
 import org.argeo.jcr.ArgeoNames;
 import org.argeo.jcr.ArgeoTypes;
 import org.argeo.jcr.JcrUtils;
@@ -62,7 +63,7 @@ public class JcrKeyring extends AbstractKeyring implements ArgeoNames {
                        if (notYetSavedKeyring.get() != null)
                                return true;
 
-                       Node userHome = JcrUtils.getUserHome(session);
+                       Node userHome = ArgeoJcrUtils.getUserHome(session);
                        return userHome.hasNode(ARGEO_KEYRING);
                } catch (RepositoryException e) {
                        throw new ArgeoException("Cannot check whether keyring is setup", e);
@@ -74,7 +75,7 @@ public class JcrKeyring extends AbstractKeyring implements ArgeoNames {
                Binary binary = null;
                InputStream in = null;
                try {
-                       Node userHome = JcrUtils.getUserHome(session);
+                       Node userHome = ArgeoJcrUtils.getUserHome(session);
                        if (userHome.hasNode(ARGEO_KEYRING))
                                throw new ArgeoException("Keyring already setup");
                        Node keyring = userHome.addNode(ARGEO_KEYRING);
@@ -125,7 +126,7 @@ public class JcrKeyring extends AbstractKeyring implements ArgeoNames {
        @Override
        protected void handleKeySpecCallback(PBEKeySpecCallback pbeCallback) {
                try {
-                       Node userHome = JcrUtils.getUserHome(session);
+                       Node userHome = ArgeoJcrUtils.getUserHome(session);
                        Node keyring;
                        if (userHome.hasNode(ARGEO_KEYRING))
                                keyring = userHome.getNode(ARGEO_KEYRING);
@@ -249,7 +250,7 @@ public class JcrKeyring extends AbstractKeyring implements ArgeoNames {
 
        protected Cipher createCipher() {
                try {
-                       Node userHome = JcrUtils.getUserHome(session);
+                       Node userHome = ArgeoJcrUtils.getUserHome(session);
                        if (!userHome.hasNode(ARGEO_KEYRING))
                                throw new ArgeoException("Keyring not setup");
                        Node keyring = userHome.getNode(ARGEO_KEYRING);
diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/security/SecurityJcrUtils.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/security/SecurityJcrUtils.java
new file mode 100644 (file)
index 0000000..abf4347
--- /dev/null
@@ -0,0 +1,123 @@
+package org.argeo.jcr.security;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.version.VersionManager;
+
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoJcrConstants;
+import org.argeo.jcr.ArgeoJcrUtils;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.ArgeoTypes;
+import org.argeo.jcr.JcrUtils;
+
+/** Utilities related to Argeo security model in JCR */
+public class SecurityJcrUtils implements ArgeoJcrConstants {
+       /**
+        * Creates an Argeo user home, does nothing if it already exists. Session is
+        * NOT saved.
+        */
+       public static Node createUserHomeIfNeeded(Session session, String username) {
+               try {
+                       String homePath = generateUserHomePath(username);
+                       if (session.itemExists(homePath))
+                               return session.getNode(homePath);
+                       else {
+                               Node userHome = JcrUtils.mkdirs(session, homePath);
+                               userHome.addMixin(ArgeoTypes.ARGEO_USER_HOME);
+                               userHome.setProperty(ArgeoNames.ARGEO_USER_ID, username);
+                               
+                               //JcrUtils.addPrivilege(session, homePath, username, "jcr:all");
+                               return userHome;
+                       }
+               } catch (RepositoryException e) {
+                       JcrUtils.discardQuietly(session);
+                       throw new ArgeoException("Cannot create home for " + username
+                                       + " in workspace " + session.getWorkspace().getName(), e);
+               }
+       }
+
+       private static String generateUserHomePath(String username) {
+               String homeBasePath = DEFAULT_HOME_BASE_PATH;
+               return homeBasePath + '/' + JcrUtils.firstCharsToPath(username, 2)
+                               + '/' + username;
+       }
+
+       /**
+        * Creates a user profile in the home of this user. Creates the home if
+        * needed, but throw an exception if a profile already exists. The session
+        * is not saved and the node is in a checkedOut state (that is, it requires
+        * a subsequent checkin after saving the session).
+        */
+       public static Node createUserProfile(Session session, String username) {
+               try {
+                       Node userHome = createUserHomeIfNeeded(session, username);
+                       if (userHome.hasNode(ArgeoNames.ARGEO_PROFILE))
+                               throw new ArgeoException(
+                                               "There is already a user profile under " + userHome);
+                       Node userProfile = userHome.addNode(ArgeoNames.ARGEO_PROFILE);
+                       userProfile.addMixin(ArgeoTypes.ARGEO_USER_PROFILE);
+                       userProfile.setProperty(ArgeoNames.ARGEO_USER_ID, username);
+                       userProfile.setProperty(ArgeoNames.ARGEO_ENABLED, true);
+                       userProfile.setProperty(ArgeoNames.ARGEO_ACCOUNT_NON_EXPIRED, true);
+                       userProfile.setProperty(ArgeoNames.ARGEO_ACCOUNT_NON_LOCKED, true);
+                       userProfile.setProperty(ArgeoNames.ARGEO_CREDENTIALS_NON_EXPIRED,
+                                       true);
+                       return userProfile;
+               } catch (RepositoryException e) {
+                       JcrUtils.discardQuietly(session);
+                       throw new ArgeoException("Cannot create user profile for "
+                                       + username + " in workspace "
+                                       + session.getWorkspace().getName(), e);
+               }
+       }
+
+       /**
+        * Create user profile if needed, the session IS saved.
+        * 
+        * @return the user profile
+        */
+       public static Node createUserProfileIfNeeded(Session securitySession,
+                       String username) {
+               try {
+                       Node userHome = createUserHomeIfNeeded(securitySession, username);
+                       Node userProfile = userHome.hasNode(ArgeoNames.ARGEO_PROFILE) ? userHome
+                                       .getNode(ArgeoNames.ARGEO_PROFILE) : createUserProfile(
+                                       securitySession, username);
+                       if (securitySession.hasPendingChanges())
+                               securitySession.save();
+                       VersionManager versionManager = securitySession.getWorkspace()
+                                       .getVersionManager();
+                       if (versionManager.isCheckedOut(userProfile.getPath()))
+                               versionManager.checkin(userProfile.getPath());
+                       return userProfile;
+               } catch (RepositoryException e) {
+                       JcrUtils.discardQuietly(securitySession);
+                       throw new ArgeoException("Cannot create user profile for "
+                                       + username + " in workspace "
+                                       + securitySession.getWorkspace().getName(), e);
+               }
+       }
+
+       /**
+        * @return null if not found *
+        */
+       public static Node getUserProfile(Session session, String username) {
+               try {
+                       Node userHome = ArgeoJcrUtils.getUserHome(session, username);
+                       if (userHome == null)
+                               return null;
+                       if (userHome.hasNode(ArgeoNames.ARGEO_PROFILE))
+                               return userHome.getNode(ArgeoNames.ARGEO_PROFILE);
+                       else
+                               return null;
+               } catch (RepositoryException e) {
+                       throw new ArgeoException(
+                                       "Cannot find profile for user " + username, e);
+               }
+       }
+
+       private SecurityJcrUtils() {
+       }
+}