1 package org
.argeo
.security
.jcr
;
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
;
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
;
22 * Manages data expected by the Argeo security model, such as user home and
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
31 /** The home base path. */
32 private String homeBasePath
= "/home";
34 public Node
sync(Session session
, String username
, List
<String
> roles
) {
35 // TODO check user name validity (e.g. should not start by ROLE_)
38 Node userHome
= UserJcrUtils
.getUserHome(session
, username
);
39 if (userHome
== null) {
40 String homePath
= generateUserPath(homeBasePath
, username
);
41 userHome
= JcrUtils
.mkdirs(session
, homePath
);
42 // userHome = JcrUtils.mkfolders(session, homePath);
43 userHome
.addMixin(ArgeoTypes
.ARGEO_USER_HOME
);
44 userHome
.setProperty(ArgeoNames
.ARGEO_USER_ID
, username
);
47 JcrUtils
.clearAccessControList(session
, homePath
, username
);
48 JcrUtils
.addPrivilege(session
, homePath
, username
,
51 // for backward compatibility with pre 1.0 security model
52 if (userHome
.hasNode(ArgeoNames
.ARGEO_PROFILE
)) {
53 userHome
.getNode(ArgeoNames
.ARGEO_PROFILE
).remove();
54 userHome
.getSession().save();
60 //writeRemoteRoles(userHome, roles);
63 Node userProfile
= UserJcrUtils
.getUserProfile(session
, username
);
64 if (userProfile
== null) {
65 String personPath
= generateUserPath(
66 ArgeoJcrConstants
.PEOPLE_BASE_PATH
, username
);
67 Node personBase
= JcrUtils
.mkdirs(session
, personPath
);
68 userProfile
= personBase
.addNode(ArgeoNames
.ARGEO_PROFILE
);
69 userProfile
.addMixin(ArgeoTypes
.ARGEO_USER_PROFILE
);
70 userProfile
.setProperty(ArgeoNames
.ARGEO_USER_ID
, username
);
71 userProfile
.setProperty(ArgeoNames
.ARGEO_ENABLED
, true);
72 userProfile
.setProperty(ArgeoNames
.ARGEO_ACCOUNT_NON_EXPIRED
,
74 userProfile
.setProperty(ArgeoNames
.ARGEO_ACCOUNT_NON_LOCKED
,
76 userProfile
.setProperty(
77 ArgeoNames
.ARGEO_CREDENTIALS_NON_EXPIRED
, true);
80 JcrUtils
.clearAccessControList(session
, userProfile
.getPath(),
82 JcrUtils
.addPrivilege(session
, userProfile
.getPath(), username
,
85 VersionManager versionManager
= session
.getWorkspace()
87 if (versionManager
.isCheckedOut(userProfile
.getPath()))
88 versionManager
.checkin(userProfile
.getPath());
91 } catch (RepositoryException e
) {
92 JcrUtils
.discardQuietly(session
);
93 throw new ArgeoException("Cannot sync node security model for "
98 /** Generate path for a new user home */
99 protected String
generateUserPath(String base
, String username
) {
100 int atIndex
= username
.indexOf('@');
102 String domain
= username
.substring(0, atIndex
);
103 String name
= username
.substring(atIndex
+ 1);
104 return base
+ '/' + JcrUtils
.firstCharsToPath(domain
, 2) + '/'
105 + domain
+ '/' + JcrUtils
.firstCharsToPath(name
, 2) + '/'
107 } else if (atIndex
== 0 || atIndex
== (username
.length() - 1)) {
108 throw new ArgeoException("Unsupported username " + username
);
110 return base
+ '/' + JcrUtils
.firstCharsToPath(username
, 2) + '/'
115 /** Write remote roles used by remote access in the home directory */
116 protected void writeRemoteRoles(Node userHome
, List
<String
> roles
)
117 throws RepositoryException
{
118 boolean writeRoles
= false;
119 if (userHome
.hasProperty(ArgeoNames
.ARGEO_REMOTE_ROLES
)) {
120 Value
[] remoteRoles
= userHome
.getProperty(
121 ArgeoNames
.ARGEO_REMOTE_ROLES
).getValues();
122 if (remoteRoles
.length
!= roles
.size())
125 for (int i
= 0; i
< remoteRoles
.length
; i
++)
126 if (!remoteRoles
[i
].getString().equals(roles
.get(i
)))
132 userHome
.getSession().getWorkspace().getVersionManager()
133 .checkout(userHome
.getPath());
134 String
[] roleIds
= roles
.toArray(new String
[roles
.size()]);
135 userHome
.setProperty(ArgeoNames
.ARGEO_REMOTE_ROLES
, roleIds
);
136 JcrUtils
.updateLastModified(userHome
);
137 userHome
.getSession().save();
138 userHome
.getSession().getWorkspace().getVersionManager()
139 .checkin(userHome
.getPath());
140 if (log
.isDebugEnabled())
141 log
.debug("Wrote remote roles " + roles
+ " for "
142 + userHome
.getProperty(ArgeoNames
.ARGEO_USER_ID
));
147 public void setHomeBasePath(String homeBasePath
) {
148 this.homeBasePath
= homeBasePath
;