1 package org
.argeo
.app
.core
;
3 import java
.util
.HashSet
;
7 import javax
.jcr
.NodeIterator
;
8 import javax
.jcr
.RepositoryException
;
9 import javax
.jcr
.Session
;
10 import javax
.jcr
.nodetype
.NodeType
;
11 import javax
.jcr
.security
.Privilege
;
12 import javax
.security
.auth
.x500
.X500Principal
;
13 import javax
.xml
.namespace
.QName
;
15 import org
.argeo
.api
.acr
.Content
;
16 import org
.argeo
.api
.acr
.ldap
.LdapAttr
;
17 import org
.argeo
.api
.acr
.ldap
.LdapObj
;
18 import org
.argeo
.api
.cms
.CmsConstants
;
19 import org
.argeo
.api
.cms
.CmsSession
;
20 import org
.argeo
.app
.api
.EntityType
;
21 import org
.argeo
.cms
.RoleNameUtils
;
22 import org
.argeo
.jcr
.JcrException
;
23 import org
.argeo
.jcr
.JcrUtils
;
25 /** Utilities around the Argeo Suite APIs. */
26 public class SuiteUtils
{
27 public final static String USER_STATE_NODE_NAME
= "state";
28 public final static String USER_DEVICES_NODE_NAME
= "devices";
29 public final static String USER_SESSIONS_NODE_NAME
= "sessions";
31 public static String
getUserNodePath(String userDn
) {
32 String uid
= RoleNameUtils
.getLastRdnValue(userDn
);
33 return EntityType
.user
.basePath() + '/' + uid
;
36 public static Node
getOrCreateUserNode(Session adminSession
, String userDn
) {
38 Node usersBase
= adminSession
.getNode(EntityType
.user
.basePath());
39 String uid
= RoleNameUtils
.getLastRdnValue(userDn
);
41 if (!usersBase
.hasNode(uid
)) {
42 userNode
= usersBase
.addNode(uid
, NodeType
.NT_UNSTRUCTURED
);
43 userNode
.addMixin(EntityType
.user
.get());
44 userNode
.addMixin(NodeType
.MIX_CREATED
);
45 userNode
.setProperty(LdapAttr
.distinguishedName
.get(), userDn
.toString());
46 userNode
.setProperty(LdapAttr
.uid
.get(), uid
);
48 userNode
= usersBase
.getNode(uid
);
51 if (!userNode
.hasNode(USER_SESSIONS_NODE_NAME
)) {
52 // Migrate existing user node
53 Node sessionsNode
= userNode
.addNode(USER_SESSIONS_NODE_NAME
, NodeType
.NT_UNSTRUCTURED
);
54 oldSessions
: for (NodeIterator nit
= userNode
.getNodes(); nit
.hasNext();) {
55 Node child
= nit
.nextNode();
56 if (USER_SESSIONS_NODE_NAME
.equals(child
.getName()) || child
.getName().startsWith("rep:")
57 || child
.getName().startsWith("jcr:"))
59 Node target
= sessionsNode
.addNode(child
.getName());
60 JcrUtils
.copy(child
, target
);
63 Node userStateNode
= userNode
.addNode(USER_STATE_NODE_NAME
, NodeType
.NT_UNSTRUCTURED
);
64 Node userDevicesNode
= userNode
.addNode(USER_DEVICES_NODE_NAME
, NodeType
.NT_UNSTRUCTURED
);
67 // JackrabbitSecurityUtils.denyPrivilege(adminSession, userNode.getPath(), SuiteRole.coworker.dn(),
68 // Privilege.JCR_READ);
69 JcrUtils
.addPrivilege(adminSession
, userNode
.getPath(), new X500Principal(userDn
.toString()).getName(),
71 JcrUtils
.addPrivilege(adminSession
, userNode
.getPath(), CmsConstants
.ROLE_USER_ADMIN
,
74 JcrUtils
.addPrivilege(adminSession
, userStateNode
.getPath(), userDn
, Privilege
.JCR_ALL
);
75 JcrUtils
.addPrivilege(adminSession
, userDevicesNode
.getPath(), userDn
, Privilege
.JCR_ALL
);
78 } catch (RepositoryException e
) {
79 throw new JcrException("Cannot create user node for " + userDn
, e
);
83 public static Node
getCmsSessionNode(Session session
, CmsSession cmsSession
) {
85 return session
.getNode(getUserNodePath(cmsSession
.getUserDn()) + '/' + USER_SESSIONS_NODE_NAME
+ '/'
86 + cmsSession
.getUuid().toString());
87 } catch (RepositoryException e
) {
88 throw new JcrException("Cannot get session dir for " + cmsSession
, e
);
92 public static Node
getOrCreateCmsSessionNode(Session adminSession
, CmsSession cmsSession
) {
94 String userDn
= cmsSession
.getUserDn();
95 Node userNode
= getOrCreateUserNode(adminSession
, userDn
);
96 Node sessionsNode
= userNode
.getNode(USER_SESSIONS_NODE_NAME
);
97 String cmsSessionUuid
= cmsSession
.getUuid().toString();
99 if (!sessionsNode
.hasNode(cmsSessionUuid
)) {
100 cmsSessionNode
= sessionsNode
.addNode(cmsSessionUuid
, NodeType
.NT_UNSTRUCTURED
);
101 cmsSessionNode
.addMixin(NodeType
.MIX_CREATED
);
103 JcrUtils
.addPrivilege(adminSession
, cmsSessionNode
.getPath(), cmsSession
.getUserRole(),
106 cmsSessionNode
= sessionsNode
.getNode(cmsSessionUuid
);
108 return cmsSessionNode
;
109 } catch (RepositoryException e
) {
110 throw new JcrException("Cannot create session dir for " + cmsSession
, e
);
114 public static Set
<String
> extractRoles(String
[] semiColArr
) {
115 Set
<String
> res
= new HashSet
<>();
116 // TODO factorize and make it more robust
117 final String rolesPrefix
= "roles:=\"";
118 // first one is layer id
119 for (int i
= 1; i
< semiColArr
.length
; i
++) {
120 if (semiColArr
[i
].startsWith(rolesPrefix
)) {
121 String rolesStr
= semiColArr
[i
].substring(rolesPrefix
.length());
123 rolesStr
= rolesStr
.substring(0, rolesStr
.lastIndexOf('\"'));
124 // TODO support AND (&) as well
125 String
[] roles
= rolesStr
.split("\\|");// OR (|)
126 for (String role
: roles
) {
127 res
.add(role
.trim());
134 synchronized static public long findNextId(Content hierarchyUnit
, QName cclass
) {
135 if (!hierarchyUnit
.hasContentClass(LdapObj
.posixGroup
.qName()))
136 throw new IllegalArgumentException(hierarchyUnit
+ " is not a POSIX group");
138 long min
= hierarchyUnit
.get(LdapAttr
.gidNumber
.qName(), Long
.class).orElseThrow();
139 long currentMax
= 0l;
140 for (Content childHu
: hierarchyUnit
) {
141 if (!childHu
.hasContentClass(LdapObj
.organizationalUnit
.qName()))
143 // FIXME filter out functional hierarchy unit
144 for (Content role
: childHu
) {
145 if (role
.hasContentClass(cclass
)) {
147 if (LdapObj
.posixAccount
.qName().equals(cclass
)) {
148 Long id
= role
.get(LdapAttr
.uidNumber
.qName(), Long
.class).orElseThrow();
155 if (currentMax
== 0l)
157 return currentMax
+ 1;
161 private SuiteUtils() {