]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/internal/kernel/HomeRepository.java
c6f3a600df13d67d16300065204aec741af5abaa
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / internal / kernel / HomeRepository.java
1 package org.argeo.cms.internal.kernel;
2
3 import java.security.PrivilegedAction;
4 import java.util.HashSet;
5 import java.util.Set;
6
7 import javax.jcr.Node;
8 import javax.jcr.Repository;
9 import javax.jcr.RepositoryException;
10 import javax.jcr.Session;
11 import javax.jcr.security.Privilege;
12 import javax.naming.InvalidNameException;
13 import javax.naming.ldap.LdapName;
14 import javax.security.auth.Subject;
15 import javax.security.auth.login.LoginContext;
16
17 import org.apache.jackrabbit.core.security.SecurityConstants;
18 import org.argeo.cms.CmsException;
19 import org.argeo.cms.auth.AuthConstants;
20 import org.argeo.jcr.ArgeoJcrConstants;
21 import org.argeo.jcr.ArgeoNames;
22 import org.argeo.jcr.ArgeoTypes;
23 import org.argeo.jcr.JcrRepositoryWrapper;
24 import org.argeo.jcr.JcrUtils;
25 import org.argeo.jcr.UserJcrUtils;
26
27 /**
28 * Make sure each user has a home directory available in the default workspace.
29 */
30 class HomeRepository extends JcrRepositoryWrapper implements KernelConstants, ArgeoJcrConstants {
31 /** The home base path. */
32 private String homeBasePath = "/home";
33 private String peopleBasePath = ArgeoJcrConstants.PEOPLE_BASE_PATH;
34
35 private Set<String> checkedUsers = new HashSet<String>();
36
37 public HomeRepository(Repository repository) {
38 setRepository(repository);
39 LoginContext lc;
40 try {
41 lc = new LoginContext(AuthConstants.LOGIN_CONTEXT_DATA_ADMIN);
42 lc.login();
43 } catch (javax.security.auth.login.LoginException e1) {
44 throw new CmsException("Cannot login as systrem", e1);
45 }
46 Subject.doAs(lc.getSubject(), new PrivilegedAction<Void>() {
47
48 @Override
49 public Void run() {
50 try {
51 initJcr(getRepository().login());
52 } catch (RepositoryException e) {
53 throw new CmsException("Cannot init JCR home", e);
54 }
55 return null;
56 }
57
58 });
59 }
60
61 // @Override
62 // public Session login() throws LoginException, RepositoryException {
63 // Session session = super.login();
64 // String username = session.getUserID();
65 // if (username == null)
66 // return session;
67 // if (session.getUserID().equals(AuthConstants.ROLE_ANONYMOUS))
68 // return session;
69 //
70 // if (checkedUsers.contains(username))
71 // return session;
72 // Session adminSession = KernelUtils.openAdminSession(getRepository(),
73 // session.getWorkspace().getName());
74 // try {
75 // syncJcr(adminSession, username);
76 // checkedUsers.add(username);
77 // } finally {
78 // JcrUtils.logoutQuietly(adminSession);
79 // }
80 // return session;
81 // }
82
83 @Override
84 protected void processNewSession(Session session) {
85 String username = session.getUserID();
86 if (username == null)
87 return;
88 if (session.getUserID().equals(AuthConstants.ROLE_ANONYMOUS))
89 return;
90 if (session.getUserID().equals(AuthConstants.ROLE_KERNEL))
91 return;
92 if (session.getUserID().equals(SecurityConstants.ADMIN_ID))
93 return;
94
95 if (checkedUsers.contains(username))
96 return;
97 Session adminSession = KernelUtils.openAdminSession(getRepository(), session.getWorkspace().getName());
98 try {
99 syncJcr(adminSession, username);
100 checkedUsers.add(username);
101 } finally {
102 JcrUtils.logoutQuietly(adminSession);
103 }
104 }
105
106 /*
107 * JCR
108 */
109 /** Session is logged out. */
110 private void initJcr(Session adminSession) {
111 try {
112 JcrUtils.mkdirs(adminSession, homeBasePath);
113 JcrUtils.mkdirs(adminSession, peopleBasePath);
114 adminSession.save();
115
116 JcrUtils.addPrivilege(adminSession, homeBasePath, AuthConstants.ROLE_USER_ADMIN, Privilege.JCR_READ);
117 JcrUtils.addPrivilege(adminSession, peopleBasePath, AuthConstants.ROLE_USER_ADMIN, Privilege.JCR_ALL);
118 adminSession.save();
119 } catch (RepositoryException e) {
120 throw new CmsException("Cannot initialize node user admin", e);
121 } finally {
122 JcrUtils.logoutQuietly(adminSession);
123 }
124 }
125
126 private Node syncJcr(Session session, String username) {
127 try {
128 Node userHome = UserJcrUtils.getUserHome(session, username);
129 if (userHome == null) {
130 String homePath = generateUserPath(homeBasePath, username);
131 if (session.itemExists(homePath))// duplicate user id
132 userHome = session.getNode(homePath).getParent().addNode(JcrUtils.lastPathElement(homePath));
133 else
134 userHome = JcrUtils.mkdirs(session, homePath);
135 // userHome = JcrUtils.mkfolders(session, homePath);
136 userHome.addMixin(ArgeoTypes.ARGEO_USER_HOME);
137 userHome.setProperty(ArgeoNames.ARGEO_USER_ID, username);
138 session.save();
139
140 JcrUtils.clearAccessControList(session, homePath, username);
141 JcrUtils.addPrivilege(session, homePath, username, Privilege.JCR_ALL);
142 }
143
144 Node userProfile = UserJcrUtils.getUserProfile(session, username);
145 // new user
146 if (userProfile == null) {
147 String personPath = generateUserPath(peopleBasePath, username);
148 Node personBase;
149 if (session.itemExists(personPath))// duplicate user id
150 personBase = session.getNode(personPath).getParent().addNode(JcrUtils.lastPathElement(personPath));
151 else
152 personBase = JcrUtils.mkdirs(session, personPath);
153 userProfile = personBase.addNode(ArgeoNames.ARGEO_PROFILE);
154 userProfile.addMixin(ArgeoTypes.ARGEO_USER_PROFILE);
155 userProfile.setProperty(ArgeoNames.ARGEO_USER_ID, username);
156 // userProfile.setProperty(ArgeoNames.ARGEO_ENABLED, true);
157 // userProfile.setProperty(ArgeoNames.ARGEO_ACCOUNT_NON_EXPIRED,
158 // true);
159 // userProfile.setProperty(ArgeoNames.ARGEO_ACCOUNT_NON_LOCKED,
160 // true);
161 // userProfile.setProperty(ArgeoNames.ARGEO_CREDENTIALS_NON_EXPIRED,
162 // true);
163 session.save();
164
165 JcrUtils.clearAccessControList(session, userProfile.getPath(), username);
166 JcrUtils.addPrivilege(session, userProfile.getPath(), username, Privilege.JCR_READ);
167 }
168
169 // Remote roles
170 // if (roles != null) {
171 // writeRemoteRoles(userProfile, roles);
172 // }
173 if (session.hasPendingChanges())
174 session.save();
175 return userProfile;
176 } catch (RepositoryException e) {
177 JcrUtils.discardQuietly(session);
178 throw new CmsException("Cannot sync node security model for " + username, e);
179 }
180 }
181
182 /** Generate path for a new user home */
183 private String generateUserPath(String base, String username) {
184 LdapName dn;
185 try {
186 dn = new LdapName(username);
187 } catch (InvalidNameException e) {
188 throw new CmsException("Invalid name " + username, e);
189 }
190 String userId = dn.getRdn(dn.size() - 1).getValue().toString();
191 int atIndex = userId.indexOf('@');
192 if (atIndex > 0) {
193 String domain = userId.substring(0, atIndex);
194 String name = userId.substring(atIndex + 1);
195 return base + '/' + JcrUtils.firstCharsToPath(domain, 2) + '/' + domain + '/'
196 + JcrUtils.firstCharsToPath(name, 2) + '/' + name;
197 } else if (atIndex == 0 || atIndex == (userId.length() - 1)) {
198 throw new CmsException("Unsupported username " + userId);
199 } else {
200 return base + '/' + JcrUtils.firstCharsToPath(userId, 2) + '/' + userId;
201 }
202 }
203
204 }