Allows to initialize Jackrabbit container in tests
authorMathieu Baudier <mbaudier@argeo.org>
Mon, 21 Mar 2011 11:30:37 +0000 (11:30 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Mon, 21 Mar 2011 11:30:37 +0000 (11:30 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@4328 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ArgeoUser.java
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/SimpleArgeoUser.java
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/CurrentUserServiceJcr.java [new file with mode: 0644]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrArgeoUser.java [new file with mode: 0644]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrAuthenticationProvider.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/nature/SimpleUserNature.java
security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/providers/JackrabbitAuthenticationProvider.java
security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java
server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java

index 465c2fab9271aa0634d51f69664b338878fe4793..71009604d08235a33154e2ef42e6d532e11f9955 100644 (file)
@@ -27,6 +27,7 @@ public interface ArgeoUser {
        public Map<String, UserNature> getUserNatures();
 
        /** Implementation should refuse to add new user natures via this method. */
+       @Deprecated
        public void updateUserNatures(Map<String, UserNature> userNatures);
 
        public List<String> getRoles();
index 94c7f9389f1d0dbdb81fa94c265ece4ae446310e..29166472146f8bd3e6e39aa30597da0c2b6f835d 100644 (file)
@@ -28,6 +28,7 @@ import org.argeo.ArgeoException;
  * Read-write implementation of an Argeo user. Typically initialized with a
  * generic instance (read-only9 in order to modify a user.
  */
+@Deprecated
 public class SimpleArgeoUser implements ArgeoUser, Serializable,
                Comparable<ArgeoUser> {
        private static final long serialVersionUID = 1L;
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/CurrentUserServiceJcr.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/CurrentUserServiceJcr.java
new file mode 100644 (file)
index 0000000..2c2a1ce
--- /dev/null
@@ -0,0 +1,57 @@
+package org.argeo.security.jcr;
+
+import java.util.Map;
+
+import javax.jcr.Session;
+
+import org.argeo.ArgeoException;
+import org.argeo.security.ArgeoUser;
+import org.argeo.security.CurrentUserDao;
+import org.argeo.security.CurrentUserService;
+import org.argeo.security.UserNature;
+import org.springframework.security.Authentication;
+import org.springframework.security.context.SecurityContextHolder;
+
+public class CurrentUserServiceJcr implements CurrentUserService {
+       private Session session;
+       private CurrentUserDao currentUserDao;
+
+       public ArgeoUser getCurrentUser() {
+               Authentication authentication = SecurityContextHolder.getContext()
+                               .getAuthentication();
+
+               Session userSession;
+               if (authentication instanceof JcrAuthenticationToken) {
+                       userSession = ((JcrAuthenticationToken) authentication)
+                                       .getSession();
+               } else {
+                       if (session == null)
+                               throw new ArgeoException("No user JCR session available");
+                       userSession = session;
+               }
+
+               JcrUserDetails jcrUserDetails = (JcrUserDetails) authentication
+                               .getDetails();
+               return JcrUserDetails.jcrUserDetailsToArgeoUser(userSession,
+                               jcrUserDetails);
+       }
+
+       public void updateCurrentUserPassword(String oldPassword, String newPassword) {
+               currentUserDao.updateCurrentUserPassword(oldPassword, newPassword);
+
+       }
+
+       public void updateCurrentUserNatures(Map<String, UserNature> userNatures) {
+               // TODO Auto-generated method stub
+
+       }
+
+       public void setSession(Session session) {
+               this.session = session;
+       }
+
+       public void setCurrentUserDao(CurrentUserDao currentUserDao) {
+               this.currentUserDao = currentUserDao;
+       }
+
+}
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrArgeoUser.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrArgeoUser.java
new file mode 100644 (file)
index 0000000..131d6ea
--- /dev/null
@@ -0,0 +1,79 @@
+package org.argeo.security.jcr;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.ArgeoException;
+import org.argeo.security.ArgeoUser;
+import org.argeo.security.UserNature;
+
+public class JcrArgeoUser implements ArgeoUser {
+       /** Cached for performance reasons. */
+       private final String username;
+       private final Node home;
+       private final List<String> roles;
+       private final Boolean enabled;
+       private final String password;
+
+       public JcrArgeoUser(Node home, String password, List<String> roles,
+                       Boolean enabled) {
+               this.home = home;
+               this.password = password;
+               this.roles = Collections.unmodifiableList(new ArrayList<String>(roles));
+               this.enabled = enabled;
+               try {
+                       username = home.getSession().getUserID();
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot find JCR user id", e);
+               }
+
+       }
+
+       public String getUsername() {
+               return username;
+       }
+
+       public Map<String, UserNature> getUserNatures() {
+               throw new UnsupportedOperationException("deprecated");
+       }
+
+       public void updateUserNatures(Map<String, UserNature> userNatures) {
+               throw new UnsupportedOperationException("deprecated");
+       }
+
+       public List<String> getRoles() {
+               return roles;
+       }
+
+       public String getPassword() {
+               return password;
+       }
+
+       public Node getHome() {
+               return home;
+       }
+
+       public Boolean getEnabled() {
+               return enabled;
+       }
+
+       public boolean equals(Object obj) {
+               if (!(obj instanceof ArgeoUser))
+                       return false;
+               return ((ArgeoUser) obj).getUsername().equals(username);
+       }
+
+       @Override
+       public int hashCode() {
+               return username.hashCode();
+       }
+
+       public String toString() {
+               return getUsername() + "@" + getHome();
+       }
+}
index b7680ad1b338eea1600e9e3e98ee4ff0a91caae0..ce7d9181232e8e0318cb3a9e157bf48a6745e085 100644 (file)
@@ -84,13 +84,18 @@ public class JcrAuthenticationProvider implements AuthenticationProvider {
                try {
                        // TODO: loads enabled, locked, etc. from the home node.
                        return new JcrUserDetails(userHome.getPath(), authen.getPrincipal()
-                                       .toString(), authen.getCredentials().toString(), true,
+                                       .toString(), authen.getCredentials().toString(),
+                                       isEnabled(userHome),
                                        true, true, true, authen.getAuthorities());
                } catch (Exception e) {
                        throw new ArgeoException("Cannot get user details for " + userHome,
                                        e);
                }
        }
+       
+       protected Boolean isEnabled(Node userHome){
+               return true;
+       }
 
        @SuppressWarnings("rawtypes")
        public boolean supports(Class authentication) {
index f200a28a420bdc225314408b790366f617649082..ea66b5ff74e529f03d2bb97b766253b51e227f7d 100644 (file)
@@ -1,6 +1,15 @@
 package org.argeo.security.jcr;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.ArgeoException;
 import org.springframework.security.GrantedAuthority;
+import org.springframework.security.GrantedAuthorityImpl;
 import org.springframework.security.userdetails.User;
 
 public class JcrUserDetails extends User {
@@ -20,4 +29,41 @@ public class JcrUserDetails extends User {
                return homePath;
        }
 
+       public static JcrUserDetails argeoUserToJcrUserDetails(
+                       JcrArgeoUser argeoUser) {
+               try {
+                       List<GrantedAuthority> gas = new ArrayList<GrantedAuthority>();
+                       for (String role : argeoUser.getRoles())
+                               gas.add(new GrantedAuthorityImpl(role));
+                       return new JcrUserDetails(argeoUser.getHome().getPath(),
+                                       argeoUser.getUsername(), argeoUser.getPassword(),
+                                       argeoUser.getEnabled(), true, true, true,
+                                       gas.toArray(new GrantedAuthority[gas.size()]));
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot convert " + argeoUser
+                                       + " to JCR user details", e);
+               }
+       }
+
+       public static JcrArgeoUser jcrUserDetailsToArgeoUser(Session userSession,
+                       JcrUserDetails jcrUserDetails) {
+               if (!userSession.getUserID().equals(jcrUserDetails.getUsername()))
+                       throw new ArgeoException("User session has user id "
+                                       + userSession.getUserID() + " while details has username "
+                                       + jcrUserDetails.getUsername());
+
+               Node userHome;
+               try {
+                       userHome = userSession.getNode(jcrUserDetails.getHomePath());
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot retrieve user home with path "
+                                       + jcrUserDetails.getHomePath(), e);
+               }
+               List<String> roles = new ArrayList<String>();
+               for (GrantedAuthority ga : jcrUserDetails.getAuthorities())
+                       roles.add(ga.getAuthority());
+               return new JcrArgeoUser(userHome, jcrUserDetails.getPassword(), roles,
+                               jcrUserDetails.isEnabled());
+
+       }
 }
index a10ac4dbde9dcc002d95721c8d185ea3828fd5f1..e400e99d92f879de8fcfed6f289e96b9cfe1482b 100644 (file)
@@ -21,6 +21,7 @@ import org.argeo.security.AbstractUserNature;
 import org.argeo.security.ArgeoUser;
 import org.argeo.security.UserNature;
 
+@Deprecated
 public class SimpleUserNature extends AbstractUserNature {
        /**
         * No PAI, for internal use within the Argeo Security framework. Will
index b7dedad79e42e027eca179f5e42d88330b27c3ba..d9f9f379a79a9cd6c127c78c870af4b8534b6633 100644 (file)
@@ -4,6 +4,7 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
+import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
@@ -35,4 +36,18 @@ public class JackrabbitAuthenticationProvider extends JcrAuthenticationProvider
                }
        }
 
+       @Override
+       protected Boolean isEnabled(Node userHome) {
+               try {
+                       UserManager userManager = ((JackrabbitSession) userHome
+                                       .getSession()).getUserManager();
+                       User user = (User) userManager.getAuthorizable(userHome
+                                       .getSession().getUserID());
+                       return !user.isDisabled();
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot check whether " + userHome
+                                       + " is enabled", e);
+               }
+       }
+
 }
index 4c6e62b98bf8bec91d19d59607ad8dd393848991..200ed351e93b48fc92699ab46daf5aa4874290fe 100644 (file)
@@ -199,6 +199,7 @@ public class ArgeoSecurityDaoLdap implements CurrentUserDao, UserAdminDao {
                        throw new ArgeoException("Old password is not correct.");
                user.setPassword(encodePassword(newPassword));
                updateUser(user);
+               //userDetailsManager.changePassword(oldPassword, newPassword);
        }
 
        public void updateUserPassword(String username, String password) {
index 67126362b5bd8437285eaa79510e105bd3d0ded3..51063ace7640b2323e3cf23e1cf676de2a01ae20 100644 (file)
@@ -85,6 +85,7 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean,
        private Boolean autocreateWorkspaces = false;
 
        private Executor systemExecutor;
+       private Credentials adminCredentials;
 
        public void afterPropertiesSet() throws Exception {
                // remote repository
@@ -135,7 +136,8 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean,
                else
                        repository = RepositoryImpl.create(config);
 
-               importNodeTypeDefinitions(repository);
+               if (cndFiles != null && cndFiles.size() > 0)
+                       importNodeTypeDefinitions(repository);
 
                log.info("Initialized Jackrabbit repository " + repository + " in "
                                + homeDirectory + " with config " + configuration);
@@ -147,17 +149,22 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean,
         * will be thrown.
         */
        protected void importNodeTypeDefinitions(final Repository repository) {
+               final Credentials credentialsToUse;
                if (systemExecutor == null) {
-                       log.warn("No system executor found");
-                       return;
+                       if (adminCredentials == null)
+                               throw new ArgeoException(
+                                               "No system executor or admin credentials found");
+                       credentialsToUse = adminCredentials;
+               } else {
+                       credentialsToUse = null;
                }
 
-               systemExecutor.execute(new Runnable() {
+               Runnable action = new Runnable() {
                        public void run() {
                                Reader reader = null;
                                Session session = null;
                                try {
-                                       session = repository.login();
+                                       session = repository.login(credentialsToUse);
                                        // Load cnds as resources
                                        for (String resUrl : cndFiles) {
                                                Resource res = resourceLoader.getResource(resUrl);
@@ -177,8 +184,12 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean,
                                        JcrUtils.logoutQuietly(session);
                                }
                        }
-               });
+               };
 
+               if (systemExecutor != null)
+                       systemExecutor.execute(action);
+               else
+                       action.run();
        }
 
        public void destroy() throws Exception {
@@ -335,4 +346,8 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean,
                this.systemExecutor = systemExecutor;
        }
 
+       public void setAdminCredentials(Credentials adminCredentials) {
+               this.adminCredentials = adminCredentials;
+       }
+
 }