3 import java
.security
.PrivilegedAction
;
4 import java
.util
.HashMap
;
7 import javax
.jcr
.NoSuchWorkspaceException
;
9 import javax
.jcr
.Repository
;
10 import javax
.jcr
.RepositoryException
;
11 import javax
.jcr
.RepositoryFactory
;
12 import javax
.jcr
.Session
;
13 import javax
.naming
.InvalidNameException
;
14 import javax
.naming
.ldap
.LdapName
;
15 import javax
.security
.auth
.AuthPermission
;
16 import javax
.security
.auth
.Subject
;
17 import javax
.security
.auth
.login
.LoginContext
;
18 import javax
.security
.auth
.login
.LoginException
;
20 /** Utilities related to Argeo model in JCR */
21 public class NodeUtils
{
23 * Wraps the call to the repository factory based on parameter
24 * {@link NodeConstants#CN} in order to simplify it and protect against future
27 public static Repository
getRepositoryByAlias(RepositoryFactory repositoryFactory
, String alias
) {
29 Map
<String
, String
> parameters
= new HashMap
<String
, String
>();
30 parameters
.put(NodeConstants
.CN
, alias
);
31 return repositoryFactory
.getRepository(parameters
);
32 } catch (RepositoryException e
) {
33 throw new RuntimeException("Unexpected exception when trying to retrieve repository with alias " + alias
,
39 * Wraps the call to the repository factory based on parameter
40 * {@link NodeConstants#LABELED_URI} in order to simplify it and protect against
43 public static Repository
getRepositoryByUri(RepositoryFactory repositoryFactory
, String uri
) {
44 return getRepositoryByUri(repositoryFactory
, uri
, null);
48 * Wraps the call to the repository factory based on parameter
49 * {@link NodeConstants#LABELED_URI} in order to simplify it and protect against
52 public static Repository
getRepositoryByUri(RepositoryFactory repositoryFactory
, String uri
, String alias
) {
54 Map
<String
, String
> parameters
= new HashMap
<String
, String
>();
55 parameters
.put(NodeConstants
.LABELED_URI
, uri
);
57 parameters
.put(NodeConstants
.CN
, alias
);
58 return repositoryFactory
.getRepository(parameters
);
59 } catch (RepositoryException e
) {
60 throw new RuntimeException("Unexpected exception when trying to retrieve repository with uri " + uri
, e
);
65 * Returns the home node of the user or null if none was found.
67 * @param session the session to use in order to perform the search, this can
68 * be a session with a different user ID than the one searched,
69 * typically when a system or admin session is used.
70 * @param username the username of the user
72 public static Node
getUserHome(Session session
, String username
) {
74 // QueryObjectModelFactory qomf = session.getWorkspace().getQueryManager().getQOMFactory();
75 // Selector sel = qomf.selector(NodeTypes.NODE_USER_HOME, "sel");
76 // DynamicOperand dop = qomf.propertyValue(sel.getSelectorName(), NodeNames.LDAP_UID);
77 // StaticOperand sop = qomf.literal(session.getValueFactory().createValue(username));
78 // Constraint constraint = qomf.comparison(dop, QueryObjectModelFactory.JCR_OPERATOR_EQUAL_TO, sop);
79 // Query query = qomf.createQuery(sel, constraint, null, null);
80 // return querySingleNode(query);
81 // } catch (RepositoryException e) {
82 // throw new RuntimeException("Cannot find home for user " + username, e);
86 checkUserWorkspace(session
, username
);
87 String homePath
= getHomePath(username
);
88 if (session
.itemExists(homePath
))
89 return session
.getNode(homePath
);
91 homePath
= "/home/" + username
;
92 if (session
.itemExists(homePath
))
93 return session
.getNode(homePath
);
95 } catch (RepositoryException e
) {
96 throw new RuntimeException("Cannot find home for user " + username
, e
);
100 private static String
getHomePath(String username
) {
103 dn
= new LdapName(username
);
104 } catch (InvalidNameException e
) {
105 throw new IllegalArgumentException("Invalid name " + username
, e
);
107 String userId
= dn
.getRdn(dn
.size() - 1).getValue().toString();
111 private static void checkUserWorkspace(Session session
, String username
) {
112 String workspaceName
= session
.getWorkspace().getName();
113 if (!NodeConstants
.HOME_WORKSPACE
.equals(workspaceName
))
114 throw new IllegalArgumentException(workspaceName
+ " is not the home workspace for user " + username
);
118 * Returns the home node of the user or null if none was found.
120 * @param session the session to use in order to perform the search, this can
121 * be a session with a different user ID than the one searched,
122 * typically when a system or admin session is used.
123 * @param groupname the name of the group
125 public static Node
getGroupHome(Session session
, String groupname
) {
127 // QueryObjectModelFactory qomf = session.getWorkspace().getQueryManager().getQOMFactory();
128 // Selector sel = qomf.selector(NodeTypes.NODE_GROUP_HOME, "sel");
129 // DynamicOperand dop = qomf.propertyValue(sel.getSelectorName(), NodeNames.LDAP_CN);
130 // StaticOperand sop = qomf.literal(session.getValueFactory().createValue(cn));
131 // Constraint constraint = qomf.comparison(dop, QueryObjectModelFactory.JCR_OPERATOR_EQUAL_TO, sop);
132 // Query query = qomf.createQuery(sel, constraint, null, null);
133 // return querySingleNode(query);
134 // } catch (RepositoryException e) {
135 // throw new RuntimeException("Cannot find home for group " + cn, e);
139 checkGroupWorkspace(session
, groupname
);
140 String homePath
= getGroupPath(groupname
);
141 if (session
.itemExists(homePath
))
142 return session
.getNode(homePath
);
144 homePath
= "/groups/" + groupname
;
145 if (session
.itemExists(homePath
))
146 return session
.getNode(homePath
);
148 } catch (RepositoryException e
) {
149 throw new RuntimeException("Cannot find home for group " + groupname
, e
);
154 private static String
getGroupPath(String groupname
) {
157 LdapName dn
= new LdapName(groupname
);
158 cn
= dn
.getRdn(dn
.size() - 1).getValue().toString();
159 } catch (InvalidNameException e
) {
165 private static void checkGroupWorkspace(Session session
, String groupname
) {
166 String workspaceName
= session
.getWorkspace().getName();
167 if (!NodeConstants
.SRV_WORKSPACE
.equals(workspaceName
))
168 throw new IllegalArgumentException(workspaceName
+ " is not the group workspace for group " + groupname
);
172 * Queries one single node.
174 * @return one single node or null if none was found
175 * @throws ArgeoJcrException if more than one node was found
177 // private static Node querySingleNode(Query query) {
178 // NodeIterator nodeIterator;
180 // QueryResult queryResult = query.execute();
181 // nodeIterator = queryResult.getNodes();
182 // } catch (RepositoryException e) {
183 // throw new RuntimeException("Cannot execute query " + query, e);
186 // if (nodeIterator.hasNext())
187 // node = nodeIterator.nextNode();
191 // if (nodeIterator.hasNext())
192 // throw new RuntimeException("Query returned more than one node.");
196 /** Returns the home node of the session user or null if none was found. */
197 public static Node
getUserHome(Session session
) {
198 String userID
= session
.getUserID();
199 return getUserHome(session
, userID
);
203 * Translate the path to this node into a path containing the name of the
204 * repository and the name of the workspace.
206 public static String
getDataPath(String cn
, Node node
) throws RepositoryException
{
208 StringBuilder buf
= new StringBuilder(NodeConstants
.PATH_DATA
);
209 return buf
.append('/').append(cn
).append('/').append(node
.getSession().getWorkspace().getName())
210 .append(node
.getPath()).toString();
214 * Open a JCR session with full read/write rights on the data, as
215 * {@link NodeConstants#ROLE_USER_ADMIN}, using the
216 * {@link NodeConstants#LOGIN_CONTEXT_DATA_ADMIN} login context. For security
217 * hardened deployement, use {@link AuthPermission} on this login context.
219 public static Session
openDataAdminSession(Repository repository
, String workspaceName
) {
220 ClassLoader currentCl
= Thread
.currentThread().getContextClassLoader();
221 LoginContext loginContext
;
223 loginContext
= new LoginContext(NodeConstants
.LOGIN_CONTEXT_DATA_ADMIN
);
224 loginContext
.login();
225 } catch (LoginException e1
) {
226 throw new RuntimeException("Could not login as data admin", e1
);
228 Thread
.currentThread().setContextClassLoader(currentCl
);
230 return Subject
.doAs(loginContext
.getSubject(), new PrivilegedAction
<Session
>() {
233 public Session
run() {
235 return repository
.login(workspaceName
);
236 } catch (NoSuchWorkspaceException e
) {
237 throw new IllegalArgumentException("No workspace " + workspaceName
+ " available", e
);
238 } catch (RepositoryException e
) {
239 throw new RuntimeException("Cannot open data admin session", e
);
247 private NodeUtils() {