]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/JcrAuthenticationProvider.java
First working remote node
[lgpl/argeo-commons.git] / security / runtime / org.argeo.security.core / src / main / java / org / argeo / security / jcr / JcrAuthenticationProvider.java
index 844984a52b3c75400f1b12460712b52b0acf3c23..c19e709a1547e91e7fd144c628e6507ce1c23698 100644 (file)
@@ -2,47 +2,35 @@ package org.argeo.security.jcr;
 
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import javax.jcr.Credentials;
 import javax.jcr.Node;
 import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.RepositoryFactory;
 import javax.jcr.Session;
 import javax.jcr.SimpleCredentials;
+import javax.jcr.Value;
 
 import org.argeo.ArgeoException;
 import org.argeo.jcr.ArgeoJcrConstants;
 import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.ArgeoTypes;
+import org.argeo.jcr.JcrUtils;
 import org.argeo.security.SiteAuthenticationToken;
 import org.springframework.security.Authentication;
 import org.springframework.security.AuthenticationException;
 import org.springframework.security.GrantedAuthority;
 import org.springframework.security.GrantedAuthorityImpl;
 import org.springframework.security.providers.AuthenticationProvider;
+import org.springframework.security.userdetails.UserDetails;
 
-/** Connects to a JCR repository and delegate authentication to it. */
+/** Connects to a JCR repository and delegates authentication to it. */
 public class JcrAuthenticationProvider implements AuthenticationProvider {
-       private List<RepositoryFactory> repositoryFactories = new ArrayList<RepositoryFactory>();
-       private final String defaultHome;
-       private final String userRole;
+       public final static String ROLE_REMOTE_JCR_AUTHENTICATED = "ROLE_REMOTE_JCR_AUTHENTICATED";
 
-       public JcrAuthenticationProvider() {
-               this("ROLE_USER", "home");
-       }
-
-       public JcrAuthenticationProvider(String userRole) {
-               this(userRole, "home");
-       }
-
-       public JcrAuthenticationProvider(String defaultHome, String userRole) {
-               super();
-               this.defaultHome = defaultHome;
-               this.userRole = userRole;
-       }
+       private RepositoryFactory repositoryFactory;
 
        public Authentication authenticate(Authentication authentication)
                        throws AuthenticationException {
@@ -54,83 +42,92 @@ public class JcrAuthenticationProvider implements AuthenticationProvider {
                        return null;
 
                try {
-                       Map<String, String> parameters = new HashMap<String, String>();
-                       parameters.put(ArgeoJcrConstants.JCR_REPOSITORY_URI, url);
-
-                       Repository repository = null;
-                       for (Iterator<RepositoryFactory> it = repositoryFactories
-                                       .iterator(); it.hasNext();) {
-                               repository = it.next().getRepository(parameters);
-                       }
+                       SimpleCredentials sp = new SimpleCredentials(siteAuth.getName(),
+                                       siteAuth.getCredentials().toString().toCharArray());
+                       // get repository
+                       Repository repository = getRepository(url, sp);
                        if (repository == null)
                                return null;
 
-                       SimpleCredentials sp = new SimpleCredentials(siteAuth.getName(),
-                                       siteAuth.getCredentials().toString().toCharArray());
                        String workspace = siteAuth.getWorkspace();
                        Session session;
                        if (workspace == null || workspace.trim().equals(""))
                                session = repository.login(sp);
                        else
                                session = repository.login(sp, workspace);
-                       Node userHome = getUserHome(session);
-                       GrantedAuthority[] authorities = {};
-                       return new JcrAuthenticationToken(siteAuth.getPrincipal(),
-                                       siteAuth.getCredentials(), authorities, url, userHome);
+
+                       Node userHome = JcrUtils.getUserHome(session);
+
+                       // retrieve remote roles
+                       Node userProfile = JcrUtils.getUserProfile(session);
+                       List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
+                       if (userProfile.hasProperty(ArgeoNames.ARGEO_REMOTE_ROLES)) {
+                               Value[] roles = userProfile.getProperty(
+                                               ArgeoNames.ARGEO_REMOTE_ROLES).getValues();
+                               for (int i = 0; i < roles.length; i++)
+                                       authorities.add(new GrantedAuthorityImpl(roles[i]
+                                                       .getString()));
+                       }
+                       JcrAuthenticationToken authen = new JcrAuthenticationToken(
+                                       siteAuth.getPrincipal(),
+                                       siteAuth.getCredentials(),
+                                       authorities.toArray(new GrantedAuthority[authorities.size()]),
+                                       url, userHome);
+                       authen.setDetails(getUserDetails(userHome, authen));
+
+                       return authen;
                } catch (RepositoryException e) {
                        throw new ArgeoException(
                                        "Unexpected exception when authenticating to " + url, e);
                }
        }
 
-       protected GrantedAuthority[] getGrantedAuthorities(Session session) {
-               return new GrantedAuthority[] { new GrantedAuthorityImpl(userRole) };
+       protected Repository getRepository(String url, Credentials credentials)
+                       throws RepositoryException {
+               Map<String, String> parameters = new HashMap<String, String>();
+               parameters.put(ArgeoJcrConstants.JCR_REPOSITORY_URI, url);
+               return repositoryFactory.getRepository(parameters);
        }
 
-       @SuppressWarnings("rawtypes")
-       public boolean supports(Class authentication) {
-               return SiteAuthenticationToken.class.isAssignableFrom(authentication);
+       /**
+        * By default, assigns only the role {@value #ROLE_REMOTE_JCR_AUTHENTICATED}
+        * . Should typically be overridden in order to assign more relevant roles.
+        */
+       protected GrantedAuthority[] getGrantedAuthorities(Session session) {
+               return new GrantedAuthority[] { new GrantedAuthorityImpl(
+                               ROLE_REMOTE_JCR_AUTHENTICATED) };
        }
 
-       protected Node getUserHome(Session session) {
-               String userID = "<not yet logged in>";
+       /** Builds user details based on the authentication and the user home. */
+       protected UserDetails getUserDetails(Node userHome, Authentication authen) {
                try {
-                       userID = session.getUserID();
-                       Node rootNode = session.getRootNode();
-                       Node homeNode;
-                       if (!rootNode.hasNode(defaultHome)) {
-                               homeNode = rootNode.addNode(defaultHome, ArgeoTypes.ARGEO_HOME);
-                       } else {
-                               homeNode = rootNode.getNode(defaultHome);
-                       }
-
-                       Node userHome;
-                       if (!homeNode.hasNode(userID)) {
-                               userHome = homeNode.addNode(userID);
-                               userHome.addMixin(ArgeoTypes.ARGEO_USER_HOME);
-                               userHome.setProperty(ArgeoNames.ARGEO_USER_ID, userID);
-                       } else {
-                               userHome = homeNode.getNode(userID);
-                       }
-                       session.save();
-                       return userHome;
+                       // TODO: loads enabled, locked, etc. from the home node.
+                       return new JcrUserDetails(userHome.getPath(), authen.getPrincipal()
+                                       .toString(), authen.getCredentials().toString(),
+                                       isEnabled(userHome), true, true, true,
+                                       authen.getAuthorities());
                } catch (Exception e) {
-                       throw new ArgeoException("Cannot initialize home for user '"
-                                       + userID + "'", e);
+                       throw new ArgeoException("Cannot get user details for " + userHome,
+                                       e);
                }
        }
 
-       public void setRepositoryFactories(
-                       List<RepositoryFactory> repositoryFactories) {
-               this.repositoryFactories = repositoryFactories;
+       protected Boolean isEnabled(Node userHome) {
+               return true;
        }
 
-       public String getDefaultHome() {
-               return defaultHome;
+       @SuppressWarnings("rawtypes")
+       public boolean supports(Class authentication) {
+               return SiteAuthenticationToken.class.isAssignableFrom(authentication);
        }
 
-       public String getUserRole() {
-               return userRole;
+       public void register(RepositoryFactory repositoryFactory,
+                       Map<String, String> parameters) {
+               this.repositoryFactory = repositoryFactory;
        }
 
+       public void unregister(RepositoryFactory repositoryFactory,
+                       Map<String, String> parameters) {
+               this.repositoryFactory = null;
+       }
 }