From ee0981fe4c265fd9cd01e1cc47599fd018bf363a Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Mon, 21 Mar 2011 11:30:37 +0000 Subject: [PATCH] Allows to initialize Jackrabbit container in tests git-svn-id: https://svn.argeo.org/commons/trunk@4328 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../java/org/argeo/security/ArgeoUser.java | 1 + .../org/argeo/security/SimpleArgeoUser.java | 1 + .../security/jcr/CurrentUserServiceJcr.java | 57 +++++++++++++ .../org/argeo/security/jcr/JcrArgeoUser.java | 79 +++++++++++++++++++ .../jcr/JcrAuthenticationProvider.java | 7 +- .../argeo/security/jcr/JcrUserDetails.java | 46 +++++++++++ .../security/nature/SimpleUserNature.java | 1 + .../JackrabbitAuthenticationProvider.java | 15 ++++ .../security/ldap/ArgeoSecurityDaoLdap.java | 1 + .../argeo/jackrabbit/JackrabbitContainer.java | 27 +++++-- 10 files changed, 228 insertions(+), 7 deletions(-) create mode 100644 security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/CurrentUserServiceJcr.java create mode 100644 security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrArgeoUser.java diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ArgeoUser.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ArgeoUser.java index 465c2fab9..71009604d 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ArgeoUser.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ArgeoUser.java @@ -27,6 +27,7 @@ public interface ArgeoUser { public Map getUserNatures(); /** Implementation should refuse to add new user natures via this method. */ + @Deprecated public void updateUserNatures(Map userNatures); public List getRoles(); diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/SimpleArgeoUser.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/SimpleArgeoUser.java index 94c7f9389..291664721 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/SimpleArgeoUser.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/SimpleArgeoUser.java @@ -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 { 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 index 000000000..2c2a1ce41 --- /dev/null +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/CurrentUserServiceJcr.java @@ -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 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 index 000000000..131d6ea5e --- /dev/null +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrArgeoUser.java @@ -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 roles; + private final Boolean enabled; + private final String password; + + public JcrArgeoUser(Node home, String password, List roles, + Boolean enabled) { + this.home = home; + this.password = password; + this.roles = Collections.unmodifiableList(new ArrayList(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 getUserNatures() { + throw new UnsupportedOperationException("deprecated"); + } + + public void updateUserNatures(Map userNatures) { + throw new UnsupportedOperationException("deprecated"); + } + + public List 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(); + } +} diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrAuthenticationProvider.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrAuthenticationProvider.java index b7680ad1b..ce7d91812 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrAuthenticationProvider.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrAuthenticationProvider.java @@ -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) { diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrUserDetails.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrUserDetails.java index f200a28a4..ea66b5ff7 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrUserDetails.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrUserDetails.java @@ -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 gas = new ArrayList(); + 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 roles = new ArrayList(); + for (GrantedAuthority ga : jcrUserDetails.getAuthorities()) + roles.add(ga.getAuthority()); + return new JcrArgeoUser(userHome, jcrUserDetails.getPassword(), roles, + jcrUserDetails.isEnabled()); + + } } diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/nature/SimpleUserNature.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/nature/SimpleUserNature.java index a10ac4dbd..e400e99d9 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/nature/SimpleUserNature.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/nature/SimpleUserNature.java @@ -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 diff --git a/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/providers/JackrabbitAuthenticationProvider.java b/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/providers/JackrabbitAuthenticationProvider.java index b7dedad79..d9f9f379a 100644 --- a/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/providers/JackrabbitAuthenticationProvider.java +++ b/security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/providers/JackrabbitAuthenticationProvider.java @@ -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); + } + } + } diff --git a/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java b/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java index 4c6e62b98..200ed351e 100644 --- a/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java +++ b/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java @@ -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) { diff --git a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java index 67126362b..51063ace7 100644 --- a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java +++ b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java @@ -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; + } + } -- 2.30.2