]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeUserAdmin.java
Standardise user admin unit tests
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / internal / kernel / NodeUserAdmin.java
1 package org.argeo.cms.internal.kernel;
2
3 import java.net.URI;
4 import java.net.URISyntaxException;
5 import java.util.ArrayList;
6 import java.util.Arrays;
7 import java.util.Dictionary;
8 import java.util.HashMap;
9 import java.util.HashSet;
10 import java.util.Hashtable;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.Set;
14
15 import javax.naming.InvalidNameException;
16 import javax.naming.ldap.LdapName;
17 import javax.transaction.TransactionManager;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.argeo.cms.CmsException;
22 import org.argeo.cms.auth.AuthConstants;
23 import org.argeo.node.NodeConstants;
24 import org.argeo.osgi.useradmin.LdapUserAdmin;
25 import org.argeo.osgi.useradmin.LdifUserAdmin;
26 import org.argeo.osgi.useradmin.UserAdminConf;
27 import org.argeo.osgi.useradmin.UserDirectory;
28 import org.argeo.osgi.useradmin.UserDirectoryException;
29 import org.osgi.framework.BundleContext;
30 import org.osgi.framework.Constants;
31 import org.osgi.framework.FrameworkUtil;
32 import org.osgi.framework.InvalidSyntaxException;
33 import org.osgi.framework.ServiceReference;
34 import org.osgi.framework.ServiceRegistration;
35 import org.osgi.service.cm.ConfigurationException;
36 import org.osgi.service.cm.ManagedServiceFactory;
37 import org.osgi.service.useradmin.Authorization;
38 import org.osgi.service.useradmin.Role;
39 import org.osgi.service.useradmin.User;
40 import org.osgi.service.useradmin.UserAdmin;
41 import org.osgi.util.tracker.ServiceTracker;
42
43 import bitronix.tm.resource.ehcache.EhCacheXAResourceProducer;
44
45 /**
46 * Aggregates multiple {@link UserDirectory} and integrates them with this node
47 * system roles.
48 */
49 class NodeUserAdmin implements UserAdmin, ManagedServiceFactory, KernelConstants {
50 private final static Log log = LogFactory.getLog(NodeUserAdmin.class);
51 final static LdapName ROLES_BASE;
52 static {
53 try {
54 ROLES_BASE = new LdapName(AuthConstants.ROLES_BASEDN);
55 } catch (InvalidNameException e) {
56 throw new UserDirectoryException("Cannot initialize " + NodeUserAdmin.class, e);
57 }
58 }
59
60 private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
61
62 // DAOs
63 private UserAdmin nodeRoles = null;
64 private Map<LdapName, UserAdmin> userAdmins = new HashMap<LdapName, UserAdmin>();
65 private Map<String, LdapName> pidToBaseDn = new HashMap<>();
66
67 private ServiceRegistration<UserAdmin> userAdminReg;
68
69 private final ServiceTracker<TransactionManager, TransactionManager> tmTracker;
70
71 // JCR
72 // private String homeBasePath = "/home";
73 // private String peopleBasePath = ArgeoJcrConstants.PEOPLE_BASE_PATH;
74 // private Repository repository;
75 // private Session adminSession;
76
77 private final String cacheName = UserDirectory.class.getName();
78
79 public NodeUserAdmin() {
80 // DAOs
81 // File nodeBaseDir = new File(getOsgiInstanceDir(), DIR_NODE);
82 // nodeBaseDir.mkdirs();
83 // String userAdminUri = getFrameworkProp(NodeConstants.USERADMIN_URIS);
84 // initUserAdmins(userAdminUri, nodeBaseDir);
85 // String nodeRolesUri = getFrameworkProp(NodeConstants.ROLES_URI);
86 // initNodeRoles(nodeRolesUri, nodeBaseDir);
87
88 // new ServiceTracker<>(bc, TransactionManager.class, new
89 // TransactionManagerStc()).open();
90 tmTracker = new TransactionManagerStc();
91 tmTracker.open();
92 }
93
94 @Override
95 public void updated(String pid, Dictionary<String, ?> properties) throws ConfigurationException {
96 String uri = (String) properties.get(UserAdminConf.uri.name());
97 URI u;
98 try {
99 u = new URI(uri);
100 } catch (URISyntaxException e) {
101 throw new CmsException("Badly formatted URI " + uri, e);
102 }
103 UserDirectory userDirectory = u.getScheme().equals("ldap") ? new LdapUserAdmin(properties)
104 : new LdifUserAdmin(properties);
105 LdapName baseDn;
106 try {
107 baseDn = new LdapName(userDirectory.getBaseDn());
108 } catch (InvalidNameException e) {
109 throw new CmsException("Badly formatted base DN " + userDirectory.getBaseDn(), e);
110 }
111 if (isRolesDnBase(baseDn)) {
112 nodeRoles = (UserAdmin) userDirectory;
113 userDirectory.setExternalRoles(this);
114 }
115 userDirectory.init();
116 addUserAdmin(baseDn.toString(), (UserAdmin) userDirectory);
117
118 // publish user directory
119 Dictionary<String, Object> regProps = new Hashtable<>();
120 regProps.put(Constants.SERVICE_PID, pid);
121 regProps.put(UserAdminConf.baseDn.name(), baseDn);
122 bc.registerService(UserDirectory.class, userDirectory, regProps);
123 pidToBaseDn.put(pid, baseDn);
124
125 if (log.isDebugEnabled()) {
126 log.debug("User directory " + userDirectory.getBaseDn() + " [" + u.getScheme() + "] enabled.");
127 }
128
129 if (!isRolesDnBase(baseDn)) {
130 if (userAdminReg != null)
131 userAdminReg.unregister();
132 // register self as main user admin
133 userAdminReg = bc.registerService(UserAdmin.class, this, currentState());
134 }
135 }
136
137 private boolean isRolesDnBase(LdapName baseDn) {
138 return baseDn.equals(ROLES_BASE);
139 }
140
141 @Override
142 public void deleted(String pid) {
143 LdapName baseDn = pidToBaseDn.remove(pid);
144 UserAdmin userAdmin = userAdmins.remove(baseDn);
145 ((UserDirectory) userAdmin).destroy();
146 }
147
148 @Override
149 public String getName() {
150 return "Node user admin";
151 }
152
153 private class TransactionManagerStc extends ServiceTracker<TransactionManager, TransactionManager> {
154
155 public TransactionManagerStc() {
156 super(bc, TransactionManager.class, null);
157 }
158
159 @Override
160 public TransactionManager addingService(ServiceReference<TransactionManager> reference) {
161 TransactionManager transactionManager = bc.getService(reference);
162 if (nodeRoles != null)
163 ((UserDirectory) nodeRoles).setTransactionManager(transactionManager);
164 for (UserAdmin userAdmin : userAdmins.values()) {
165 if (userAdmin instanceof UserDirectory)
166 ((UserDirectory) userAdmin).setTransactionManager(transactionManager);
167 }
168 if (log.isDebugEnabled())
169 log.debug("Set transaction manager");
170 return transactionManager;
171 }
172
173 @Override
174 public void removedService(ServiceReference<TransactionManager> reference, TransactionManager service) {
175 ((UserDirectory) nodeRoles).setTransactionManager(null);
176 for (UserAdmin userAdmin : userAdmins.values()) {
177 if (userAdmin instanceof UserDirectory)
178 ((UserDirectory) userAdmin).setTransactionManager(null);
179 }
180 }
181
182 }
183
184 // @Deprecated
185 // public NodeUserAdmin(TransactionManager transactionManager, Repository
186 // repository) {
187 // // this.repository = repository;
188 // // try {
189 // // this.adminSession = this.repository.login();
190 // // } catch (RepositoryException e) {
191 // // throw new CmsException("Cannot log-in", e);
192 // // }
193 //
194 // // DAOs
195 // File nodeBaseDir = new File(getOsgiInstanceDir(), DIR_NODE);
196 // nodeBaseDir.mkdirs();
197 // String userAdminUri = getFrameworkProp(NodeConstants.USERADMIN_URIS);
198 // initUserAdmins(userAdminUri, nodeBaseDir);
199 // String nodeRolesUri = getFrameworkProp(NodeConstants.ROLES_URI);
200 // initNodeRoles(nodeRolesUri, nodeBaseDir);
201 //
202 // // Transaction manager
203 // ((UserDirectory) nodeRoles).setTransactionManager(transactionManager);
204 // for (UserAdmin userAdmin : userAdmins.values()) {
205 // if (userAdmin instanceof UserDirectory)
206 // ((UserDirectory) userAdmin).setTransactionManager(transactionManager);
207 // }
208 //
209 // // JCR
210 // // initJcr(adminSession);
211 // }
212
213 Dictionary<String, Object> currentState() {
214 Dictionary<String, Object> res = new Hashtable<String, Object>();
215 res.put(NodeConstants.CN, NodeConstants.DEFAULT);
216 for (LdapName name : userAdmins.keySet()) {
217 StringBuilder buf = new StringBuilder();
218 if (userAdmins.get(name) instanceof UserDirectory) {
219 UserDirectory userDirectory = (UserDirectory) userAdmins.get(name);
220 String uri = UserAdminConf.propertiesAsUri(userDirectory.getProperties()).toString();
221 res.put(uri, "");
222 } else {
223 buf.append('/').append(name.toString()).append("?readOnly=true");
224 }
225 }
226 return res;
227 }
228
229 public void destroy() {
230 for (LdapName name : userAdmins.keySet()) {
231 if (userAdmins.get(name) instanceof UserDirectory) {
232 UserDirectory userDirectory = (UserDirectory) userAdmins.get(name);
233 try {
234 // FIXME Make it less bitronix dependant
235 EhCacheXAResourceProducer.unregisterXAResource(cacheName, userDirectory.getXaResource());
236 } catch (Exception e) {
237 log.error("Cannot unregister resource from Bitronix", e);
238 }
239 userDirectory.destroy();
240
241 }
242 }
243 }
244
245 @Override
246 public Role createRole(String name, int type) {
247 return findUserAdmin(name).createRole(name, type);
248 }
249
250 @Override
251 public boolean removeRole(String name) {
252 boolean actuallyDeleted = findUserAdmin(name).removeRole(name);
253 nodeRoles.removeRole(name);
254 return actuallyDeleted;
255 }
256
257 @Override
258 public Role getRole(String name) {
259 return findUserAdmin(name).getRole(name);
260 }
261
262 @Override
263 public Role[] getRoles(String filter) throws InvalidSyntaxException {
264 List<Role> res = new ArrayList<Role>();
265 for (UserAdmin userAdmin : userAdmins.values()) {
266 res.addAll(Arrays.asList(userAdmin.getRoles(filter)));
267 }
268 res.addAll(Arrays.asList(nodeRoles.getRoles(filter)));
269 return res.toArray(new Role[res.size()]);
270 }
271
272 @Override
273 public User getUser(String key, String value) {
274 List<User> res = new ArrayList<User>();
275 for (UserAdmin userAdmin : userAdmins.values()) {
276 User u = userAdmin.getUser(key, value);
277 if (u != null)
278 res.add(u);
279 }
280 // Note: node roles cannot contain users, so it is not searched
281 return res.size() == 1 ? res.get(0) : null;
282 }
283
284 @Override
285 public Authorization getAuthorization(User user) {
286 if (user == null) {// anonymous
287 return nodeRoles.getAuthorization(null);
288 }
289 UserAdmin userAdmin = findUserAdmin(user.getName());
290 Authorization rawAuthorization = userAdmin.getAuthorization(user);
291 // gather system roles
292 Set<String> systemRoles = new HashSet<String>();
293 for (String role : rawAuthorization.getRoles()) {
294 Authorization auth = nodeRoles.getAuthorization((User) userAdmin.getRole(role));
295 systemRoles.addAll(Arrays.asList(auth.getRoles()));
296 }
297 Authorization authorization = new NodeAuthorization(rawAuthorization.getName(), rawAuthorization.toString(),
298 systemRoles, rawAuthorization.getRoles());
299 // syncJcr(adminSession, authorization);
300 return authorization;
301 }
302
303 //
304 // USER ADMIN AGGREGATOR
305 //
306 public void addUserAdmin(String baseDn, UserAdmin userAdmin) {
307 try {
308 LdapName key = new LdapName(baseDn);
309 if (userAdmins.containsKey(key))
310 throw new UserDirectoryException("There is already a user admin for " + baseDn);
311 userAdmins.put(key, userAdmin);
312 } catch (InvalidNameException e) {
313 throw new UserDirectoryException("Badly formatted base DN " + baseDn, e);
314 }
315 if (userAdmin instanceof UserDirectory) {
316 UserDirectory userDirectory = (UserDirectory) userAdmin;
317 try {
318 userDirectory.setTransactionManager(tmTracker.getService());
319 // FIXME Make it less bitronix dependant
320 EhCacheXAResourceProducer.registerXAResource(cacheName, ((UserDirectory) userAdmin).getXaResource());
321 } catch (Exception e) {
322 log.error("Cannot register resource to Bitronix", e);
323 }
324 }
325 }
326
327 private UserAdmin findUserAdmin(String name) {
328 try {
329 return findUserAdmin(new LdapName(name));
330 } catch (InvalidNameException e) {
331 throw new UserDirectoryException("Badly formatted name " + name, e);
332 }
333 }
334
335 private UserAdmin findUserAdmin(LdapName name) {
336 if (name.startsWith(ROLES_BASE))
337 return nodeRoles;
338 List<UserAdmin> res = new ArrayList<UserAdmin>(1);
339 for (LdapName baseDn : userAdmins.keySet()) {
340 if (name.startsWith(baseDn))
341 res.add(userAdmins.get(baseDn));
342 }
343 if (res.size() == 0)
344 throw new UserDirectoryException("Cannot find user admin for " + name);
345 if (res.size() > 1)
346 throw new UserDirectoryException("Multiple user admin found for " + name);
347 return res.get(0);
348 }
349
350 public void setTransactionManager(TransactionManager transactionManager) {
351 if (nodeRoles instanceof UserDirectory)
352 ((UserDirectory) nodeRoles).setTransactionManager(transactionManager);
353 for (UserAdmin userAdmin : userAdmins.values()) {
354 if (userAdmin instanceof UserDirectory)
355 ((UserDirectory) userAdmin).setTransactionManager(transactionManager);
356 }
357 }
358
359 // private void initUserAdmins(String userAdminUri, File nodeBaseDir) {
360 // // if (userAdminUri == null) {
361 // // String demoBaseDn = "dc=example,dc=com";
362 // // File businessRolesFile = new File(nodeBaseDir, demoBaseDn + ".ldif");
363 // // if (!businessRolesFile.exists())
364 // // try {
365 // //
366 // FileUtils.copyInputStreamToFile(getClass().getResourceAsStream(demoBaseDn
367 // // + ".ldif"),
368 // // businessRolesFile);
369 // // } catch (IOException e) {
370 // // throw new CmsException("Cannot copy demo resource", e);
371 // // }
372 // // userAdminUri = businessRolesFile.toURI().toString();
373 // // }
374 // String[] uris = userAdminUri.split(" ");
375 // for (String uri : uris) {
376 // URI u;
377 // try {
378 // u = new URI(uri);
379 // if (u.getPath() == null)
380 // throw new CmsException("URI " + uri + " must have a path in order to
381 // determine base DN");
382 // if (u.getScheme() == null) {
383 // if (uri.startsWith("/") || uri.startsWith("./") || uri.startsWith("../"))
384 // u = new File(uri).getCanonicalFile().toURI();
385 // else if (!uri.contains("/")) {
386 // u = new URI(nodeBaseDir.toURI() + uri);
387 // // u = new File(nodeBaseDir, uri).getCanonicalFile()
388 // // .toURI();
389 // } else
390 // throw new CmsException("Cannot interpret " + uri + " as an uri");
391 // } else if (u.getScheme().equals("file")) {
392 // u = new File(u).getCanonicalFile().toURI();
393 // }
394 // } catch (Exception e) {
395 // throw new CmsException("Cannot interpret " + uri + " as an uri", e);
396 // }
397 // Dictionary<String, ?> properties =
398 // UserAdminConf.uriAsProperties(u.toString());
399 // UserDirectory businessRoles;
400 // if (u.getScheme().startsWith("ldap")) {
401 // businessRoles = new LdapUserAdmin(properties);
402 // } else {
403 // businessRoles = new LdifUserAdmin(properties);
404 // }
405 // businessRoles.init();
406 // String baseDn = businessRoles.getBaseDn();
407 // if (userAdmins.containsKey(baseDn))
408 // throw new UserDirectoryException("There is already a user admin for " +
409 // baseDn);
410 // try {
411 // userAdmins.put(new LdapName(baseDn), (UserAdmin) businessRoles);
412 // } catch (InvalidNameException e) {
413 // throw new UserDirectoryException("Badly formatted base DN " + baseDn, e);
414 // }
415 // addUserAdmin(businessRoles.getBaseDn(), (UserAdmin) businessRoles);
416 // if (log.isDebugEnabled())
417 // log.debug("User directory " + businessRoles.getBaseDn() + " [" +
418 // u.getScheme() + "] enabled.");
419 // }
420 //
421 // }
422 //
423 // private void initNodeRoles(String nodeRolesUri, File nodeBaseDir) {
424 // String baseNodeRoleDn = AuthConstants.ROLES_BASEDN;
425 // if (nodeRolesUri == null) {
426 // File nodeRolesFile = new File(nodeBaseDir, baseNodeRoleDn + ".ldif");
427 // if (!nodeRolesFile.exists())
428 // try {
429 // FileUtils.copyInputStreamToFile(getClass().getResourceAsStream(baseNodeRoleDn
430 // + ".ldif"),
431 // nodeRolesFile);
432 // } catch (IOException e) {
433 // throw new CmsException("Cannot copy demo resource", e);
434 // }
435 // nodeRolesUri = nodeRolesFile.toURI().toString();
436 // }
437 //
438 // Dictionary<String, ?> nodeRolesProperties =
439 // UserAdminConf.uriAsProperties(nodeRolesUri);
440 // if
441 // (!nodeRolesProperties.get(UserAdminConf.baseDn.name()).equals(baseNodeRoleDn))
442 // {
443 // throw new CmsException("Invalid base dn for node roles");
444 // // TODO deal with "mounted" roles with a different baseDN
445 // }
446 // if (nodeRolesUri.startsWith("ldap")) {
447 // nodeRoles = new LdapUserAdmin(nodeRolesProperties);
448 // } else {
449 // nodeRoles = new LdifUserAdmin(nodeRolesProperties);
450 // }
451 // ((UserDirectory) nodeRoles).setExternalRoles(this);
452 // ((UserDirectory) nodeRoles).init();
453 // addUserAdmin(baseNodeRoleDn, (UserAdmin) nodeRoles);
454 // if (log.isTraceEnabled())
455 // log.trace("Node roles enabled.");
456 //
457 // }
458
459 /*
460 * JCR
461 */
462 // private void initJcr(Session adminSession) {
463 // try {
464 // JcrUtils.mkdirs(adminSession, homeBasePath);
465 // JcrUtils.mkdirs(adminSession, peopleBasePath);
466 // adminSession.save();
467 //
468 // JcrUtils.addPrivilege(adminSession, homeBasePath,
469 // AuthConstants.ROLE_USER_ADMIN, Privilege.JCR_READ);
470 // JcrUtils.addPrivilege(adminSession, peopleBasePath,
471 // AuthConstants.ROLE_USER_ADMIN, Privilege.JCR_ALL);
472 // adminSession.save();
473 // } catch (RepositoryException e) {
474 // throw new CmsException("Cannot initialize node user admin", e);
475 // }
476 // }
477 //
478 // private Node syncJcr(Session session, Authorization authorization) {
479 // // TODO check user name validity (e.g. should not start by ROLE_)
480 // String username = authorization.getName();
481 // // String[] roles = authorization.getRoles();
482 // try {
483 // Node userHome = UserJcrUtils.getUserHome(session, username);
484 // if (userHome == null) {
485 // String homePath = generateUserPath(homeBasePath, username);
486 // if (session.itemExists(homePath))// duplicate user id
487 // userHome =
488 // session.getNode(homePath).getParent().addNode(JcrUtils.lastPathElement(homePath));
489 // else
490 // userHome = JcrUtils.mkdirs(session, homePath);
491 // // userHome = JcrUtils.mkfolders(session, homePath);
492 // userHome.addMixin(ArgeoTypes.ARGEO_USER_HOME);
493 // userHome.setProperty(ArgeoNames.ARGEO_USER_ID, username);
494 // session.save();
495 //
496 // JcrUtils.clearAccessControList(session, homePath, username);
497 // JcrUtils.addPrivilege(session, homePath, username, Privilege.JCR_ALL);
498 // }
499 //
500 // Node userProfile = UserJcrUtils.getUserProfile(session, username);
501 // // new user
502 // if (userProfile == null) {
503 // String personPath = generateUserPath(peopleBasePath, username);
504 // Node personBase;
505 // if (session.itemExists(personPath))// duplicate user id
506 // personBase =
507 // session.getNode(personPath).getParent().addNode(JcrUtils.lastPathElement(personPath));
508 // else
509 // personBase = JcrUtils.mkdirs(session, personPath);
510 // userProfile = personBase.addNode(ArgeoNames.ARGEO_PROFILE);
511 // userProfile.addMixin(ArgeoTypes.ARGEO_USER_PROFILE);
512 // userProfile.setProperty(ArgeoNames.ARGEO_USER_ID, username);
513 // userProfile.setProperty(ArgeoNames.ARGEO_ENABLED, true);
514 // userProfile.setProperty(ArgeoNames.ARGEO_ACCOUNT_NON_EXPIRED, true);
515 // userProfile.setProperty(ArgeoNames.ARGEO_ACCOUNT_NON_LOCKED, true);
516 // userProfile.setProperty(ArgeoNames.ARGEO_CREDENTIALS_NON_EXPIRED, true);
517 // session.save();
518 //
519 // JcrUtils.clearAccessControList(session, userProfile.getPath(), username);
520 // JcrUtils.addPrivilege(session, userProfile.getPath(), username,
521 // Privilege.JCR_READ);
522 // }
523 //
524 // // Remote roles
525 // // if (roles != null) {
526 // // writeRemoteRoles(userProfile, roles);
527 // // }
528 // if (adminSession.hasPendingChanges())
529 // adminSession.save();
530 // return userProfile;
531 // } catch (RepositoryException e) {
532 // JcrUtils.discardQuietly(session);
533 // throw new ArgeoException("Cannot sync node security model for " +
534 // username, e);
535 // }
536 // }
537 //
538 // /** Generate path for a new user home */
539 // private String generateUserPath(String base, String username) {
540 // LdapName dn;
541 // try {
542 // dn = new LdapName(username);
543 // } catch (InvalidNameException e) {
544 // throw new ArgeoException("Invalid name " + username, e);
545 // }
546 // String userId = dn.getRdn(dn.size() - 1).getValue().toString();
547 // int atIndex = userId.indexOf('@');
548 // if (atIndex > 0) {
549 // String domain = userId.substring(0, atIndex);
550 // String name = userId.substring(atIndex + 1);
551 // return base + '/' + JcrUtils.firstCharsToPath(domain, 2) + '/' + domain +
552 // '/'
553 // + JcrUtils.firstCharsToPath(name, 2) + '/' + name;
554 // } else if (atIndex == 0 || atIndex == (userId.length() - 1)) {
555 // throw new ArgeoException("Unsupported username " + userId);
556 // } else {
557 // return base + '/' + JcrUtils.firstCharsToPath(userId, 2) + '/' + userId;
558 // }
559 // }
560
561 // /** Write remote roles used by remote access in the home directory */
562 // private void writeRemoteRoles(Node userHome, String[] roles)
563 // throws RepositoryException {
564 // boolean writeRoles = false;
565 // if (userHome.hasProperty(ArgeoNames.ARGEO_REMOTE_ROLES)) {
566 // Value[] remoteRoles = userHome.getProperty(
567 // ArgeoNames.ARGEO_REMOTE_ROLES).getValues();
568 // if (remoteRoles.length != roles.length)
569 // writeRoles = true;
570 // else
571 // for (int i = 0; i < remoteRoles.length; i++)
572 // if (!remoteRoles[i].getString().equals(roles[i]))
573 // writeRoles = true;
574 // } else
575 // writeRoles = true;
576 //
577 // if (writeRoles) {
578 // userHome.getSession().getWorkspace().getVersionManager()
579 // .checkout(userHome.getPath());
580 // userHome.setProperty(ArgeoNames.ARGEO_REMOTE_ROLES, roles);
581 // JcrUtils.updateLastModified(userHome);
582 // userHome.getSession().save();
583 // userHome.getSession().getWorkspace().getVersionManager()
584 // .checkin(userHome.getPath());
585 // if (log.isDebugEnabled())
586 // log.debug("Wrote remote roles " + roles + " for "
587 // + userHome.getProperty(ArgeoNames.ARGEO_USER_ID));
588 // }
589 //
590 // }
591 }