]> git.argeo.org Git - lgpl/argeo-commons.git/blob - security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/jcr/SimpleJcrSecurityModel.java
Change system username from 'system' to 'admin'
[lgpl/argeo-commons.git] / security / runtime / org.argeo.security.core / src / main / java / org / argeo / security / jcr / SimpleJcrSecurityModel.java
1 package org.argeo.security.jcr;
2
3 import java.util.List;
4
5 import javax.jcr.Node;
6 import javax.jcr.RepositoryException;
7 import javax.jcr.Session;
8 import javax.jcr.Value;
9 import javax.jcr.security.Privilege;
10 import javax.jcr.version.VersionManager;
11
12 import org.apache.commons.logging.Log;
13 import org.apache.commons.logging.LogFactory;
14 import org.argeo.ArgeoException;
15 import org.argeo.jcr.ArgeoJcrConstants;
16 import org.argeo.jcr.ArgeoNames;
17 import org.argeo.jcr.ArgeoTypes;
18 import org.argeo.jcr.JcrUtils;
19 import org.argeo.jcr.UserJcrUtils;
20
21 /**
22 * Manages data expected by the Argeo security model, such as user home and
23 * profile.
24 */
25 public class SimpleJcrSecurityModel implements JcrSecurityModel {
26 private final static Log log = LogFactory
27 .getLog(SimpleJcrSecurityModel.class);
28 // ArgeoNames not implemented as interface in order to ease derivation by
29 // Jackrabbit bundles
30
31 /** The home base path. */
32 private String homeBasePath = "/home";
33
34 public synchronized Node sync(Session session, String username,
35 List<String> roles) {
36 // TODO check user name validity (e.g. should not start by ROLE_)
37
38 try {
39 Node userHome = UserJcrUtils.getUserHome(session, username);
40 if (userHome == null) {
41 String homePath = generateUserPath(homeBasePath, username);
42 userHome = JcrUtils.mkdirs(session, homePath);
43 // userHome = JcrUtils.mkfolders(session, homePath);
44 userHome.addMixin(ArgeoTypes.ARGEO_USER_HOME);
45 userHome.setProperty(ArgeoNames.ARGEO_USER_ID, username);
46 session.save();
47
48 JcrUtils.clearAccessControList(session, homePath, username);
49 JcrUtils.addPrivilege(session, homePath, username,
50 Privilege.JCR_ALL);
51 } else {
52 // for backward compatibility with pre 1.0 security model
53 if (userHome.hasNode(ArgeoNames.ARGEO_PROFILE)) {
54 userHome.getNode(ArgeoNames.ARGEO_PROFILE).remove();
55 userHome.getSession().save();
56 }
57 }
58
59 // Remote roles
60 if (roles != null) {
61 // writeRemoteRoles(userHome, roles);
62 }
63
64 Node userProfile = UserJcrUtils.getUserProfile(session, username);
65 if (userProfile == null) {
66 String personPath = generateUserPath(
67 ArgeoJcrConstants.PEOPLE_BASE_PATH, username);
68 Node personBase = JcrUtils.mkdirs(session, personPath);
69 userProfile = personBase.addNode(ArgeoNames.ARGEO_PROFILE);
70 userProfile.addMixin(ArgeoTypes.ARGEO_USER_PROFILE);
71 userProfile.setProperty(ArgeoNames.ARGEO_USER_ID, username);
72 userProfile.setProperty(ArgeoNames.ARGEO_ENABLED, true);
73 userProfile.setProperty(ArgeoNames.ARGEO_ACCOUNT_NON_EXPIRED,
74 true);
75 userProfile.setProperty(ArgeoNames.ARGEO_ACCOUNT_NON_LOCKED,
76 true);
77 userProfile.setProperty(
78 ArgeoNames.ARGEO_CREDENTIALS_NON_EXPIRED, true);
79 session.save();
80
81 JcrUtils.clearAccessControList(session, userProfile.getPath(),
82 username);
83 JcrUtils.addPrivilege(session, userProfile.getPath(), username,
84 Privilege.JCR_READ);
85
86 VersionManager versionManager = session.getWorkspace()
87 .getVersionManager();
88 if (versionManager.isCheckedOut(userProfile.getPath()))
89 versionManager.checkin(userProfile.getPath());
90 }
91 return userProfile;
92 } catch (RepositoryException e) {
93 JcrUtils.discardQuietly(session);
94 throw new ArgeoException("Cannot sync node security model for "
95 + username, e);
96 }
97 }
98
99 /** Generate path for a new user home */
100 protected String generateUserPath(String base, String username) {
101 int atIndex = username.indexOf('@');
102 if (atIndex > 0) {
103 String domain = username.substring(0, atIndex);
104 String name = username.substring(atIndex + 1);
105 return base + '/' + JcrUtils.firstCharsToPath(domain, 2) + '/'
106 + domain + '/' + JcrUtils.firstCharsToPath(name, 2) + '/'
107 + name;
108 } else if (atIndex == 0 || atIndex == (username.length() - 1)) {
109 throw new ArgeoException("Unsupported username " + username);
110 } else {
111 return base + '/' + JcrUtils.firstCharsToPath(username, 2) + '/'
112 + username;
113 }
114 }
115
116 /** Write remote roles used by remote access in the home directory */
117 protected void writeRemoteRoles(Node userHome, List<String> roles)
118 throws RepositoryException {
119 boolean writeRoles = false;
120 if (userHome.hasProperty(ArgeoNames.ARGEO_REMOTE_ROLES)) {
121 Value[] remoteRoles = userHome.getProperty(
122 ArgeoNames.ARGEO_REMOTE_ROLES).getValues();
123 if (remoteRoles.length != roles.size())
124 writeRoles = true;
125 else
126 for (int i = 0; i < remoteRoles.length; i++)
127 if (!remoteRoles[i].getString().equals(roles.get(i)))
128 writeRoles = true;
129 } else
130 writeRoles = true;
131
132 if (writeRoles) {
133 userHome.getSession().getWorkspace().getVersionManager()
134 .checkout(userHome.getPath());
135 String[] roleIds = roles.toArray(new String[roles.size()]);
136 userHome.setProperty(ArgeoNames.ARGEO_REMOTE_ROLES, roleIds);
137 JcrUtils.updateLastModified(userHome);
138 userHome.getSession().save();
139 userHome.getSession().getWorkspace().getVersionManager()
140 .checkin(userHome.getPath());
141 if (log.isDebugEnabled())
142 log.debug("Wrote remote roles " + roles + " for "
143 + userHome.getProperty(ArgeoNames.ARGEO_USER_ID));
144 }
145
146 }
147
148 public void setHomeBasePath(String homeBasePath) {
149 this.homeBasePath = homeBasePath;
150 }
151
152 }