]> git.argeo.org Git - lgpl/argeo-commons.git/blob - security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/ArgeoSecurityManager.java
Use versions 1.1.3
[lgpl/argeo-commons.git] / security / runtime / org.argeo.security.jackrabbit / src / main / java / org / argeo / security / jackrabbit / ArgeoSecurityManager.java
1 package org.argeo.security.jackrabbit;
2
3 import java.security.Principal;
4 import java.util.ArrayList;
5 import java.util.Iterator;
6 import java.util.List;
7 import java.util.Set;
8
9 import javax.jcr.Node;
10 import javax.jcr.RepositoryException;
11 import javax.jcr.Session;
12 import javax.jcr.security.AccessControlList;
13 import javax.jcr.security.AccessControlManager;
14 import javax.jcr.security.AccessControlPolicy;
15 import javax.jcr.security.AccessControlPolicyIterator;
16 import javax.jcr.security.Privilege;
17 import javax.security.auth.Subject;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.apache.jackrabbit.api.security.user.Group;
22 import org.apache.jackrabbit.api.security.user.User;
23 import org.apache.jackrabbit.api.security.user.UserManager;
24 import org.apache.jackrabbit.core.DefaultSecurityManager;
25 import org.apache.jackrabbit.core.security.SecurityConstants;
26 import org.apache.jackrabbit.core.security.SystemPrincipal;
27 import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager;
28 import org.argeo.ArgeoException;
29 import org.argeo.jcr.JcrUtils;
30 import org.springframework.security.Authentication;
31 import org.springframework.security.GrantedAuthority;
32
33 /** Intermediary class in order to have a consistent naming in config files. */
34 public class ArgeoSecurityManager extends DefaultSecurityManager {
35 private Log log = LogFactory.getLog(ArgeoSecurityManager.class);
36
37 @Override
38 /** Since this is called once when the session is created, we take the opportunity to synchronize Spring and Jackrabbit users and groups.*/
39 public String getUserID(Subject subject, String workspaceName)
40 throws RepositoryException {
41 long begin = System.currentTimeMillis();
42
43 if (!subject.getPrincipals(SystemPrincipal.class).isEmpty())
44 return super.getUserID(subject, workspaceName);
45
46 Authentication authen;
47 Set<Authentication> authens = subject
48 .getPrincipals(Authentication.class);
49 if (authens.size() == 0)
50 throw new ArgeoException("No Spring authentication found in "
51 + subject);
52 else
53 authen = authens.iterator().next();
54
55 UserManager systemUm = getSystemUserManager(workspaceName);
56
57 String userId = authen.getName();
58 User user = (User) systemUm.getAuthorizable(userId);
59 if (user == null) {
60 user = systemUm.createUser(userId, authen.getCredentials()
61 .toString(), authen, null);
62 log.info(userId + " added as " + user);
63 }
64
65 setHomeNodeAuthorizations(user);
66
67 // process groups
68 List<String> userGroupIds = new ArrayList<String>();
69 for (GrantedAuthority ga : authen.getAuthorities()) {
70 Group group = (Group) systemUm.getAuthorizable(ga.getAuthority());
71 if (group == null) {
72 group = systemUm.createGroup(ga.getAuthority());
73 log.info(ga.getAuthority() + " added as " + group);
74 }
75 if (!group.isMember(user))
76 group.addMember(user);
77 userGroupIds.add(ga.getAuthority());
78
79 }
80
81 // check if user has not been removed from some groups
82 for (Iterator<Group> it = user.declaredMemberOf(); it.hasNext();) {
83 Group group = it.next();
84 if (!userGroupIds.contains(group.getID()))
85 group.removeMember(user);
86 }
87
88 if (log.isTraceEnabled())
89 log.trace("Spring and Jackrabbit Security synchronized for user "
90 + userId + " in " + (System.currentTimeMillis() - begin)
91 + " ms");
92 return userId;
93 }
94
95 protected void setHomeNodeAuthorizations(User user) {
96 // give all privileges on user home
97 // FIXME: fails on an empty repo
98 String userId = "<not yet set>";
99 try {
100 userId = user.getID();
101 Node userHome = JcrUtils.getUserHome(getSystemSession(), userId);
102 if (userHome != null) {
103 String path = userHome.getPath();
104 AccessControlPolicy policy = null;
105 AccessControlManager acm = getSystemSession()
106 .getAccessControlManager();
107 AccessControlPolicyIterator policyIterator = acm
108 .getApplicablePolicies(path);
109 if (policyIterator.hasNext()) {
110 policy = policyIterator.nextAccessControlPolicy();
111 } else {
112 AccessControlPolicy[] existingPolicies = acm
113 .getPolicies(path);
114 policy = existingPolicies[0];
115 }
116 if (policy instanceof AccessControlList) {
117 Privilege[] privileges = { acm
118 .privilegeFromName(Privilege.JCR_ALL) };
119 ((AccessControlList) policy).addAccessControlEntry(
120 user.getPrincipal(), privileges);
121 acm.setPolicy(path, policy);
122 }
123 }
124 } catch (Exception e) {
125 log.warn("Cannot set authorization on user node for " + userId
126 + ": " + e.getMessage());
127 }
128
129 }
130
131 @Override
132 protected WorkspaceAccessManager createDefaultWorkspaceAccessManager() {
133 WorkspaceAccessManager wam = super
134 .createDefaultWorkspaceAccessManager();
135 return new ArgeoWorkspaceAccessManagerImpl(wam);
136 }
137
138 private class ArgeoWorkspaceAccessManagerImpl implements SecurityConstants,
139 WorkspaceAccessManager {
140 private final WorkspaceAccessManager wam;
141
142 // private String defaultWorkspace;
143
144 public ArgeoWorkspaceAccessManagerImpl(WorkspaceAccessManager wam) {
145 super();
146 this.wam = wam;
147 }
148
149 public void init(Session systemSession) throws RepositoryException {
150 wam.init(systemSession);
151 // defaultWorkspace = ((RepositoryImpl) getRepository()).getConfig()
152 // .getDefaultWorkspaceName();
153 }
154
155 public void close() throws RepositoryException {
156 }
157
158 public boolean grants(Set<Principal> principals, String workspaceName)
159 throws RepositoryException {
160 // everybody has access to all workspaces
161 // TODO: implements finer access to workspaces
162 return true;
163
164 // anonymous has access to the default workspace (required for
165 // remoting which does a default login when initializing the
166 // repository)
167 // Boolean anonymous = false;
168 // for (Principal principal : principals)
169 // if (principal instanceof AnonymousPrincipal)
170 // anonymous = true;
171 //
172 // if (anonymous && workspaceName.equals(defaultWorkspace))
173 // return true;
174 // else
175 // return wam.grants(principals, workspaceName);
176 }
177 }
178
179 }