1 package org
.argeo
.app
.core
;
3 import java
.util
.HashSet
;
7 import javax
.jcr
.RepositoryException
;
8 import javax
.jcr
.Session
;
9 import javax
.jcr
.nodetype
.NodeType
;
10 import javax
.jcr
.security
.Privilege
;
11 import javax
.security
.auth
.x500
.X500Principal
;
12 import javax
.xml
.namespace
.QName
;
14 import org
.argeo
.api
.acr
.Content
;
15 import org
.argeo
.api
.acr
.ldap
.LdapAttr
;
16 import org
.argeo
.api
.acr
.ldap
.LdapObj
;
17 import org
.argeo
.api
.cms
.CmsConstants
;
18 import org
.argeo
.api
.cms
.CmsSession
;
19 import org
.argeo
.app
.api
.EntityType
;
20 import org
.argeo
.cms
.RoleNameUtils
;
21 import org
.argeo
.jcr
.JcrException
;
22 import org
.argeo
.jcr
.JcrUtils
;
24 /** Utilities around the Argeo Suite APIs. */
25 public class SuiteUtils
{
26 public final static String USER_STATE_NODE_NAME
= "state";
27 public final static String USER_DEVICES_NODE_NAME
= "devices";
28 public final static String USER_SESSIONS_NODE_NAME
= "sessions";
30 public static String
getUserNodePath(String userDn
) {
31 String uid
= RoleNameUtils
.getLastRdnValue(userDn
);
32 return EntityType
.user
.basePath() + '/' + uid
;
35 public static Node
getOrCreateUserNode(Session adminSession
, String userDn
) {
37 Node usersBase
= adminSession
.getNode(EntityType
.user
.basePath());
38 String uid
= RoleNameUtils
.getLastRdnValue(userDn
);
40 if (!usersBase
.hasNode(uid
)) {
41 userNode
= usersBase
.addNode(uid
, NodeType
.NT_UNSTRUCTURED
);
42 userNode
.addMixin(EntityType
.user
.get());
43 userNode
.addMixin(NodeType
.MIX_CREATED
);
44 userNode
.setProperty(LdapAttr
.distinguishedName
.get(), userDn
.toString());
45 userNode
.setProperty(LdapAttr
.uid
.get(), uid
);
47 userNode
.addNode(USER_SESSIONS_NODE_NAME
, NodeType
.NT_UNSTRUCTURED
);
48 Node userStateNode
= userNode
.addNode(USER_STATE_NODE_NAME
, NodeType
.NT_UNSTRUCTURED
);
49 Node userDevicesNode
= userNode
.addNode(USER_DEVICES_NODE_NAME
, NodeType
.NT_UNSTRUCTURED
);
52 // JackrabbitSecurityUtils.denyPrivilege(adminSession, userNode.getPath(), SuiteRole.coworker.dn(),
53 // Privilege.JCR_READ);
54 JcrUtils
.addPrivilege(adminSession
, userNode
.getPath(), new X500Principal(userDn
.toString()).getName(),
56 JcrUtils
.addPrivilege(adminSession
, userNode
.getPath(), CmsConstants
.ROLE_USER_ADMIN
,
59 JcrUtils
.addPrivilege(adminSession
, userStateNode
.getPath(), userDn
, Privilege
.JCR_ALL
);
60 JcrUtils
.addPrivilege(adminSession
, userDevicesNode
.getPath(), userDn
, Privilege
.JCR_ALL
);
63 userNode
= usersBase
.getNode(uid
);
66 } catch (RepositoryException e
) {
67 throw new JcrException("Cannot create user node for " + userDn
, e
);
71 public static Node
getCmsSessionNode(Session session
, CmsSession cmsSession
) {
73 return session
.getNode(getUserNodePath(cmsSession
.getUserDn()) + '/' + USER_SESSIONS_NODE_NAME
+ '/'
74 + cmsSession
.getUuid().toString());
75 } catch (RepositoryException e
) {
76 throw new JcrException("Cannot get session dir for " + cmsSession
, e
);
80 public static Node
getOrCreateCmsSessionNode(Session adminSession
, CmsSession cmsSession
) {
82 String userDn
= cmsSession
.getUserDn();
83 Node userNode
= getOrCreateUserNode(adminSession
, userDn
);
84 Node sessionsNode
= userNode
.getNode(USER_SESSIONS_NODE_NAME
);
85 String cmsSessionUuid
= cmsSession
.getUuid().toString();
87 if (!sessionsNode
.hasNode(cmsSessionUuid
)) {
88 cmsSessionNode
= sessionsNode
.addNode(cmsSessionUuid
, NodeType
.NT_UNSTRUCTURED
);
89 cmsSessionNode
.addMixin(NodeType
.MIX_CREATED
);
91 JcrUtils
.addPrivilege(adminSession
, cmsSessionNode
.getPath(), cmsSession
.getUserRole(),
94 cmsSessionNode
= sessionsNode
.getNode(cmsSessionUuid
);
96 return cmsSessionNode
;
97 } catch (RepositoryException e
) {
98 throw new JcrException("Cannot create session dir for " + cmsSession
, e
);
102 public static Set
<String
> extractRoles(String
[] semiColArr
) {
103 Set
<String
> res
= new HashSet
<>();
104 // TODO factorize and make it more robust
105 final String rolesPrefix
= "roles:=\"";
106 // first one is layer id
107 for (int i
= 1; i
< semiColArr
.length
; i
++) {
108 if (semiColArr
[i
].startsWith(rolesPrefix
)) {
109 String rolesStr
= semiColArr
[i
].substring(rolesPrefix
.length());
111 rolesStr
= rolesStr
.substring(0, rolesStr
.lastIndexOf('\"'));
112 // TODO support AND (&) as well
113 String
[] roles
= rolesStr
.split("\\|");// OR (|)
114 for (String role
: roles
) {
115 res
.add(role
.trim());
122 synchronized static public long findNextId(Content hierarchyUnit
, QName cclass
) {
123 if (!hierarchyUnit
.hasContentClass(LdapObj
.posixGroup
.qName()))
124 throw new IllegalArgumentException(hierarchyUnit
+ " is not a POSIX group");
126 long min
= hierarchyUnit
.get(LdapAttr
.gidNumber
.qName(), Long
.class).orElseThrow();
127 long currentMax
= 0l;
128 for (Content childHu
: hierarchyUnit
) {
129 if (!childHu
.hasContentClass(LdapObj
.organizationalUnit
.qName()))
131 // FIXME filter out functional hierarchy unit
132 for (Content role
: childHu
) {
133 if (role
.hasContentClass(cclass
)) {
135 if (LdapObj
.posixAccount
.qName().equals(cclass
)) {
136 Long id
= role
.get(LdapAttr
.uidNumber
.qName(), Long
.class).orElseThrow();
143 if (currentMax
== 0l)
145 return currentMax
+ 1;
149 private SuiteUtils() {