]> git.argeo.org Git - lgpl/argeo-commons.git/blob - security/runtime/org.argeo.security.jackrabbit/src/main/java/org/argeo/security/jackrabbit/JackrabbitSecurityModel.java
16dd2981d1be56fd39f6404873658fe40e1c9459
[lgpl/argeo-commons.git] / security / runtime / org.argeo.security.jackrabbit / src / main / java / org / argeo / security / jackrabbit / JackrabbitSecurityModel.java
1 package org.argeo.security.jackrabbit;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5 import java.util.List;
6
7 import javax.jcr.Node;
8 import javax.jcr.RepositoryException;
9 import javax.jcr.Session;
10
11 import org.apache.commons.logging.Log;
12 import org.apache.commons.logging.LogFactory;
13 import org.apache.jackrabbit.api.JackrabbitSession;
14 import org.apache.jackrabbit.api.security.user.Group;
15 import org.apache.jackrabbit.api.security.user.User;
16 import org.apache.jackrabbit.api.security.user.UserManager;
17 import org.argeo.ArgeoException;
18 import org.argeo.jcr.ArgeoNames;
19 import org.argeo.security.jcr.SimpleJcrSecurityModel;
20
21 /** Make sure that user authorizable exists before syncing user directories. */
22 public class JackrabbitSecurityModel extends SimpleJcrSecurityModel {
23 private final static Log log = LogFactory
24 .getLog(JackrabbitSecurityModel.class);
25
26 @Override
27 public synchronized Node sync(Session session, String username,
28 List<String> roles) {
29 if (!(session instanceof JackrabbitSession))
30 return super.sync(session, username, roles);
31
32 try {
33 UserManager userManager = ((JackrabbitSession) session)
34 .getUserManager();
35 User user = (User) userManager.getAuthorizable(username);
36 if (user != null) {
37 String principalName = user.getPrincipal().getName();
38 if (!principalName.equals(username)) {
39 log.warn("Jackrabbit principal is '" + principalName
40 + "' but username is '" + username
41 + "'. Recreating...");
42 user.remove();
43 user = userManager.createUser(username, "");
44 }
45 } else {
46 // create new principal
47 user = userManager.createUser(username, "");
48 log.info(username + " added as Jackrabbit user " + user);
49 }
50
51 // generic JCR sync
52 Node userProfile = super.sync(session, username, roles);
53
54 Boolean enabled = userProfile.getProperty(ArgeoNames.ARGEO_ENABLED)
55 .getBoolean();
56 if (enabled && user.isDisabled())
57 user.disable(null);
58 else if (!enabled && !user.isDisabled())
59 user.disable(userProfile.getPath() + " is disabled");
60
61 // Sync Jackrabbit roles
62 if (roles != null)
63 syncRoles(userManager, user, roles);
64
65 return userProfile;
66 } catch (RepositoryException e) {
67 throw new ArgeoException(
68 "Cannot perform Jackrabbit specific operations", e);
69 }
70 }
71
72 /** Make sure Jackrabbit roles are in line with authentication */
73 void syncRoles(UserManager userManager, User user, List<String> roles)
74 throws RepositoryException {
75 List<String> userGroupIds = new ArrayList<String>();
76 for (String role : roles) {
77 Group group = (Group) userManager.getAuthorizable(role);
78 if (group == null) {
79 group = userManager.createGroup(role);
80 log.info(role + " added as " + group);
81 }
82 if (!group.isMember(user))
83 group.addMember(user);
84 userGroupIds.add(role);
85 }
86
87 // check if user has not been removed from some groups
88 for (Iterator<Group> it = user.declaredMemberOf(); it.hasNext();) {
89 Group group = it.next();
90 if (!userGroupIds.contains(group.getID()))
91 group.removeMember(user);
92 }
93 }
94 }