]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - org.argeo.cms/src/org/argeo/cms/auth/NodeUserLoginModule.java
Change webdav and remoting URLs
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / auth / NodeUserLoginModule.java
index 74fe4e421e747e0998b7e2763663ae0ab1be0f03..956b4a65cd512ba70f6575cf9d9105c803a3a33a 100644 (file)
@@ -3,7 +3,6 @@ package org.argeo.cms.auth;
 import java.security.Principal;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -12,6 +11,7 @@ import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
 import javax.security.auth.Subject;
 import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.FailedLoginException;
 import javax.security.auth.login.LoginException;
 import javax.security.auth.spi.LoginModule;
 import javax.security.auth.x500.X500Principal;
@@ -21,28 +21,26 @@ import org.apache.jackrabbit.core.security.SecurityConstants;
 import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
 import org.argeo.cms.CmsException;
 import org.argeo.cms.internal.auth.ImpliedByPrincipal;
+import org.argeo.node.NodeConstants;
 import org.osgi.service.useradmin.Authorization;
 
-public class NodeUserLoginModule implements LoginModule {
+public class NodeUserLoginModule implements LoginModule, AuthConstants {
        private Subject subject;
+       private Map<String, Object> sharedState = null;
 
-       private final static LdapName ROLE_KERNEL_NAME, ROLE_ADMIN_NAME,
-                       ROLE_ANONYMOUS_NAME, ROLE_USER_NAME;
+       private final static LdapName ROLE_ADMIN_NAME, ROLE_ANONYMOUS_NAME, ROLE_USER_NAME;
        private final static List<LdapName> RESERVED_ROLES;
        private final static X500Principal ROLE_ANONYMOUS_PRINCIPAL;
        static {
                try {
-                       ROLE_KERNEL_NAME = new LdapName(AuthConstants.ROLE_KERNEL);
-                       ROLE_ADMIN_NAME = new LdapName(AuthConstants.ROLE_ADMIN);
-                       ROLE_USER_NAME = new LdapName(AuthConstants.ROLE_USER);
-                       ROLE_ANONYMOUS_NAME = new LdapName(AuthConstants.ROLE_ANONYMOUS);
-                       RESERVED_ROLES = Collections.unmodifiableList(Arrays
-                                       .asList(new LdapName[] { ROLE_KERNEL_NAME, ROLE_ADMIN_NAME,
-                                                       ROLE_ANONYMOUS_NAME, ROLE_USER_NAME,
-                                                       new LdapName(AuthConstants.ROLE_GROUP_ADMIN),
-                                                       new LdapName(AuthConstants.ROLE_USER_ADMIN) }));
-                       ROLE_ANONYMOUS_PRINCIPAL = new X500Principal(
-                                       ROLE_ANONYMOUS_NAME.toString());
+                       // ROLE_KERNEL_NAME = new LdapName(AuthConstants.ROLE_KERNEL);
+                       ROLE_ADMIN_NAME = new LdapName(NodeConstants.ROLE_ADMIN);
+                       ROLE_USER_NAME = new LdapName(NodeConstants.ROLE_USER);
+                       ROLE_ANONYMOUS_NAME = new LdapName(NodeConstants.ROLE_ANONYMOUS);
+                       RESERVED_ROLES = Collections.unmodifiableList(Arrays.asList(new LdapName[] { ROLE_ADMIN_NAME,
+                                       ROLE_ANONYMOUS_NAME, ROLE_USER_NAME, new LdapName(AuthConstants.ROLE_GROUP_ADMIN),
+                                       new LdapName(NodeConstants.ROLE_USER_ADMIN) }));
+                       ROLE_ANONYMOUS_PRINCIPAL = new X500Principal(ROLE_ANONYMOUS_NAME.toString());
                } catch (InvalidNameException e) {
                        throw new Error("Cannot initialize login module class", e);
                }
@@ -50,67 +48,71 @@ public class NodeUserLoginModule implements LoginModule {
 
        private Authorization authorization;
 
+       @SuppressWarnings("unchecked")
        @Override
-       public void initialize(Subject subject, CallbackHandler callbackHandler,
-                       Map<String, ?> sharedState, Map<String, ?> options) {
+       public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
+                       Map<String, ?> options) {
                this.subject = subject;
+               this.sharedState = (Map<String, Object>) sharedState;
        }
 
        @Override
        public boolean login() throws LoginException {
-               Iterator<Authorization> auth = subject.getPrivateCredentials(
-                               Authorization.class).iterator();
-               if (!auth.hasNext())
-                       return false;
-               authorization = auth.next();
+               authorization = (Authorization) sharedState.get(SHARED_STATE_AUTHORIZATION);
+               if (authorization == null)
+                       throw new FailedLoginException("No authorization available");
+               // Iterator<Authorization> auth = subject.getPrivateCredentials(
+               // Authorization.class).iterator();
+               // if (!auth.hasNext())
+               // throw new FailedLoginException("No authorization available");
+               // authorization = auth.next();
                return true;
        }
 
        @Override
        public boolean commit() throws LoginException {
-               if (authorization != null) {
-                       Set<Principal> principals = subject.getPrincipals();
-                       try {
-                               String authName = authorization.getName();
-
-                               // determine user's principal
-                               final LdapName name;
-                               final Principal userPrincipal;
-                               if (authName == null) {
-                                       name = ROLE_ANONYMOUS_NAME;
-                                       userPrincipal = ROLE_ANONYMOUS_PRINCIPAL;
-                                       principals.add(userPrincipal);
-                                       principals.add(new AnonymousPrincipal());
-                               } else {
-                                       name = new LdapName(authName);
-                                       checkUserName(name);
-                                       userPrincipal = new X500Principal(name.toString());
-                                       principals.add(userPrincipal);
-                                       principals.add(new ImpliedByPrincipal(ROLE_USER_NAME,
-                                                       userPrincipal));
-                               }
+               if (authorization == null)
+                       throw new LoginException("Authorization should not be null");
+               // required for display name:
+               subject.getPrivateCredentials().add(authorization);
 
-                               // Add roles provided by authorization
-                               for (String role : authorization.getRoles()) {
-                                       LdapName roleName = new LdapName(role);
-                                       if (roleName.equals(name)) {
-                                               // skip
-                                       } else {
-                                               checkImpliedPrincipalName(roleName);
-                                               principals.add(new ImpliedByPrincipal(roleName
-                                                               .toString(), userPrincipal));
-                                               if (roleName.equals(ROLE_ADMIN_NAME))
-                                                       principals.add(new AdminPrincipal(
-                                                                       SecurityConstants.ADMIN_ID));
-                                       }
-                               }
+               Set<Principal> principals = subject.getPrincipals();
+               try {
+                       String authName = authorization.getName();
+
+                       // determine user's principal
+                       final LdapName name;
+                       final Principal userPrincipal;
+                       if (authName == null) {
+                               name = ROLE_ANONYMOUS_NAME;
+                               userPrincipal = ROLE_ANONYMOUS_PRINCIPAL;
+                               principals.add(userPrincipal);
+                               principals.add(new AnonymousPrincipal());
+                       } else {
+                               name = new LdapName(authName);
+                               checkUserName(name);
+                               userPrincipal = new X500Principal(name.toString());
+                               principals.add(userPrincipal);
+                               principals.add(new ImpliedByPrincipal(ROLE_USER_NAME, userPrincipal));
+                       }
 
-                               return true;
-                       } catch (InvalidNameException e) {
-                               throw new CmsException("Cannot commit", e);
+                       // Add roles provided by authorization
+                       for (String role : authorization.getRoles()) {
+                               LdapName roleName = new LdapName(role);
+                               if (roleName.equals(name)) {
+                                       // skip
+                               } else {
+                                       checkImpliedPrincipalName(roleName);
+                                       principals.add(new ImpliedByPrincipal(roleName.toString(), userPrincipal));
+                                       if (roleName.equals(ROLE_ADMIN_NAME))
+                                               principals.add(new AdminPrincipal(SecurityConstants.ADMIN_ID));
+                               }
                        }
-               } else
-                       return false;
+
+                       return true;
+               } catch (InvalidNameException e) {
+                       throw new CmsException("Cannot commit", e);
+               }
        }
 
        @Override
@@ -121,18 +123,17 @@ public class NodeUserLoginModule implements LoginModule {
 
        @Override
        public boolean logout() throws LoginException {
-               // TODO better deal with successive logout
                if (subject == null)
-                       return true;
-               // TODO make it less brutal
-               subject.getPrincipals().removeAll(
-                               subject.getPrincipals(X500Principal.class));
-               subject.getPrincipals().removeAll(
-                               subject.getPrincipals(ImpliedByPrincipal.class));
-               subject.getPrincipals().removeAll(
-                               subject.getPrincipals(AdminPrincipal.class));
-               subject.getPrincipals().removeAll(
-                               subject.getPrincipals(AnonymousPrincipal.class));
+                       throw new LoginException("Subject should not be null");
+               // Clean up principals
+               // Argeo
+               subject.getPrincipals().removeAll(subject.getPrincipals(X500Principal.class));
+               subject.getPrincipals().removeAll(subject.getPrincipals(ImpliedByPrincipal.class));
+               // Jackrabbit
+               subject.getPrincipals().removeAll(subject.getPrincipals(AdminPrincipal.class));
+               subject.getPrincipals().removeAll(subject.getPrincipals(AnonymousPrincipal.class));
+               // Clean up private credentials
+               subject.getPrivateCredentials().clear();
                cleanUp();
                return true;
        }
@@ -148,9 +149,7 @@ public class NodeUserLoginModule implements LoginModule {
        }
 
        private void checkImpliedPrincipalName(LdapName roleName) {
-               if (ROLE_USER_NAME.equals(roleName)
-                               || ROLE_ANONYMOUS_NAME.equals(roleName)
-                               || ROLE_KERNEL_NAME.equals(roleName))
+               if (ROLE_USER_NAME.equals(roleName) || ROLE_ANONYMOUS_NAME.equals(roleName))
                        throw new CmsException(roleName + " cannot be listed as role");
        }
 }