]> git.argeo.org Git - gpl/argeo-suite.git/blob - SuiteUtils.java
f225064158ac6728486de7805764070e04936c2b
[gpl/argeo-suite.git] / SuiteUtils.java
1 package org.argeo.app.core;
2
3 import java.util.HashSet;
4 import java.util.Set;
5
6 import javax.jcr.Node;
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;
14
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;
24
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";
30
31 public static String getUserNodePath(String userDn) {
32 String uid = RoleNameUtils.getLastRdnValue(userDn);
33 return EntityType.user.basePath() + '/' + uid;
34 }
35
36 public static Node getOrCreateUserNode(Session adminSession, String userDn) {
37 try {
38 Node usersBase = adminSession.getNode(EntityType.user.basePath());
39 String uid = RoleNameUtils.getLastRdnValue(userDn);
40 Node userNode;
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);
47 } else {
48 userNode = usersBase.getNode(uid);
49 }
50
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:"))
58 continue oldSessions;
59 Node target = sessionsNode.addNode(child.getName());
60 JcrUtils.copy(child, target);
61 }
62
63 Node userStateNode = userNode.addNode(USER_STATE_NODE_NAME, NodeType.NT_UNSTRUCTURED);
64 Node userDevicesNode = userNode.addNode(USER_DEVICES_NODE_NAME, NodeType.NT_UNSTRUCTURED);
65
66 adminSession.save();
67 // JackrabbitSecurityUtils.denyPrivilege(adminSession, userNode.getPath(), SuiteRole.coworker.dn(),
68 // Privilege.JCR_READ);
69 JcrUtils.addPrivilege(adminSession, userNode.getPath(), new X500Principal(userDn.toString()).getName(),
70 Privilege.JCR_READ);
71 JcrUtils.addPrivilege(adminSession, userNode.getPath(), CmsConstants.ROLE_USER_ADMIN,
72 Privilege.JCR_ALL);
73
74 JcrUtils.addPrivilege(adminSession, userStateNode.getPath(), userDn, Privilege.JCR_ALL);
75 JcrUtils.addPrivilege(adminSession, userDevicesNode.getPath(), userDn, Privilege.JCR_ALL);
76 }
77 return userNode;
78 } catch (RepositoryException e) {
79 throw new JcrException("Cannot create user node for " + userDn, e);
80 }
81 }
82
83 public static Node getCmsSessionNode(Session session, CmsSession cmsSession) {
84 try {
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);
89 }
90 }
91
92 public static Node getOrCreateCmsSessionNode(Session adminSession, CmsSession cmsSession) {
93 try {
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();
98 Node cmsSessionNode;
99 if (!sessionsNode.hasNode(cmsSessionUuid)) {
100 cmsSessionNode = sessionsNode.addNode(cmsSessionUuid, NodeType.NT_UNSTRUCTURED);
101 cmsSessionNode.addMixin(NodeType.MIX_CREATED);
102 adminSession.save();
103 JcrUtils.addPrivilege(adminSession, cmsSessionNode.getPath(), cmsSession.getUserRole(),
104 Privilege.JCR_ALL);
105 } else {
106 cmsSessionNode = sessionsNode.getNode(cmsSessionUuid);
107 }
108 return cmsSessionNode;
109 } catch (RepositoryException e) {
110 throw new JcrException("Cannot create session dir for " + cmsSession, e);
111 }
112 }
113
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());
122 // remove last "
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());
128 }
129 }
130 }
131 return res;
132 }
133
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");
137
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()))
142 continue;
143 // FIXME filter out functional hierarchy unit
144 for (Content role : childHu) {
145 if (role.hasContentClass(cclass)) {
146
147 if (LdapObj.posixAccount.qName().equals(cclass)) {
148 Long id = role.get(LdapAttr.uidNumber.qName(), Long.class).orElseThrow();
149 if (id > currentMax)
150 currentMax = id;
151 }
152 }
153 }
154 }
155 if (currentMax == 0l)
156 return min;
157 return currentMax + 1;
158 }
159
160 /** Singleton. */
161 private SuiteUtils() {
162 }
163 }