]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/auth/NodeUserLoginModule.java
Remove deprecated APIs
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / auth / NodeUserLoginModule.java
1 package org.argeo.cms.auth;
2
3 import java.security.Principal;
4 import java.util.Arrays;
5 import java.util.Collections;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Set;
9
10 import javax.naming.InvalidNameException;
11 import javax.naming.ldap.LdapName;
12 import javax.security.auth.Subject;
13 import javax.security.auth.callback.CallbackHandler;
14 import javax.security.auth.login.FailedLoginException;
15 import javax.security.auth.login.LoginException;
16 import javax.security.auth.spi.LoginModule;
17 import javax.security.auth.x500.X500Principal;
18
19 import org.apache.jackrabbit.core.security.AnonymousPrincipal;
20 import org.apache.jackrabbit.core.security.SecurityConstants;
21 import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
22 import org.argeo.cms.CmsException;
23 import org.argeo.cms.internal.auth.ImpliedByPrincipal;
24 import org.argeo.node.NodeConstants;
25 import org.osgi.service.useradmin.Authorization;
26
27 public class NodeUserLoginModule implements LoginModule, AuthConstants {
28 private Subject subject;
29 private Map<String, Object> sharedState = null;
30
31 private final static LdapName ROLE_ADMIN_NAME, ROLE_ANONYMOUS_NAME, ROLE_USER_NAME;
32 private final static List<LdapName> RESERVED_ROLES;
33 private final static X500Principal ROLE_ANONYMOUS_PRINCIPAL;
34 static {
35 try {
36 // ROLE_KERNEL_NAME = new LdapName(AuthConstants.ROLE_KERNEL);
37 ROLE_ADMIN_NAME = new LdapName(NodeConstants.ROLE_ADMIN);
38 ROLE_USER_NAME = new LdapName(NodeConstants.ROLE_USER);
39 ROLE_ANONYMOUS_NAME = new LdapName(NodeConstants.ROLE_ANONYMOUS);
40 RESERVED_ROLES = Collections.unmodifiableList(Arrays.asList(new LdapName[] { ROLE_ADMIN_NAME,
41 ROLE_ANONYMOUS_NAME, ROLE_USER_NAME, new LdapName(AuthConstants.ROLE_GROUP_ADMIN),
42 new LdapName(NodeConstants.ROLE_USER_ADMIN) }));
43 ROLE_ANONYMOUS_PRINCIPAL = new X500Principal(ROLE_ANONYMOUS_NAME.toString());
44 } catch (InvalidNameException e) {
45 throw new Error("Cannot initialize login module class", e);
46 }
47 }
48
49 private Authorization authorization;
50
51 @SuppressWarnings("unchecked")
52 @Override
53 public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
54 Map<String, ?> options) {
55 this.subject = subject;
56 this.sharedState = (Map<String, Object>) sharedState;
57 }
58
59 @Override
60 public boolean login() throws LoginException {
61 authorization = (Authorization) sharedState.get(SHARED_STATE_AUTHORIZATION);
62 if (authorization == null)
63 throw new FailedLoginException("No authorization available");
64 // Iterator<Authorization> auth = subject.getPrivateCredentials(
65 // Authorization.class).iterator();
66 // if (!auth.hasNext())
67 // throw new FailedLoginException("No authorization available");
68 // authorization = auth.next();
69 return true;
70 }
71
72 @Override
73 public boolean commit() throws LoginException {
74 if (authorization == null)
75 throw new LoginException("Authorization should not be null");
76 // required for display name:
77 subject.getPrivateCredentials().add(authorization);
78
79 Set<Principal> principals = subject.getPrincipals();
80 try {
81 String authName = authorization.getName();
82
83 // determine user's principal
84 final LdapName name;
85 final Principal userPrincipal;
86 if (authName == null) {
87 name = ROLE_ANONYMOUS_NAME;
88 userPrincipal = ROLE_ANONYMOUS_PRINCIPAL;
89 principals.add(userPrincipal);
90 principals.add(new AnonymousPrincipal());
91 } else {
92 name = new LdapName(authName);
93 checkUserName(name);
94 userPrincipal = new X500Principal(name.toString());
95 principals.add(userPrincipal);
96 principals.add(new ImpliedByPrincipal(ROLE_USER_NAME, userPrincipal));
97 }
98
99 // Add roles provided by authorization
100 for (String role : authorization.getRoles()) {
101 LdapName roleName = new LdapName(role);
102 if (roleName.equals(name)) {
103 // skip
104 } else {
105 checkImpliedPrincipalName(roleName);
106 principals.add(new ImpliedByPrincipal(roleName.toString(), userPrincipal));
107 if (roleName.equals(ROLE_ADMIN_NAME))
108 principals.add(new AdminPrincipal(SecurityConstants.ADMIN_ID));
109 }
110 }
111
112 return true;
113 } catch (InvalidNameException e) {
114 throw new CmsException("Cannot commit", e);
115 }
116 }
117
118 @Override
119 public boolean abort() throws LoginException {
120 cleanUp();
121 return true;
122 }
123
124 @Override
125 public boolean logout() throws LoginException {
126 if (subject == null)
127 throw new LoginException("Subject should not be null");
128 // Clean up principals
129 // Argeo
130 subject.getPrincipals().removeAll(subject.getPrincipals(X500Principal.class));
131 subject.getPrincipals().removeAll(subject.getPrincipals(ImpliedByPrincipal.class));
132 // Jackrabbit
133 subject.getPrincipals().removeAll(subject.getPrincipals(AdminPrincipal.class));
134 subject.getPrincipals().removeAll(subject.getPrincipals(AnonymousPrincipal.class));
135 // Clean up private credentials
136 subject.getPrivateCredentials().clear();
137 cleanUp();
138 return true;
139 }
140
141 private void cleanUp() {
142 subject = null;
143 authorization = null;
144 }
145
146 private void checkUserName(LdapName name) {
147 if (RESERVED_ROLES.contains(name))
148 throw new CmsException(name + " is a reserved name");
149 }
150
151 private void checkImpliedPrincipalName(LdapName roleName) {
152 if (ROLE_USER_NAME.equals(roleName) || ROLE_ANONYMOUS_NAME.equals(roleName))
153 throw new CmsException(roleName + " cannot be listed as role");
154 }
155 }