3 import java
.security
.PrivilegedAction
;
4 import java
.util
.HashMap
;
7 import javax
.jcr
.NoSuchWorkspaceException
;
9 import javax
.jcr
.Property
;
10 import javax
.jcr
.Repository
;
11 import javax
.jcr
.RepositoryException
;
12 import javax
.jcr
.RepositoryFactory
;
13 import javax
.jcr
.Session
;
14 import javax
.naming
.InvalidNameException
;
15 import javax
.naming
.ldap
.LdapName
;
16 import javax
.security
.auth
.AuthPermission
;
17 import javax
.security
.auth
.Subject
;
18 import javax
.security
.auth
.login
.LoginContext
;
19 import javax
.security
.auth
.login
.LoginException
;
21 /** Utilities related to Argeo model in JCR */
22 public class NodeUtils
{
24 * Wraps the call to the repository factory based on parameter
25 * {@link NodeConstants#CN} in order to simplify it and protect against future
28 public static Repository
getRepositoryByAlias(RepositoryFactory repositoryFactory
, String alias
) {
30 Map
<String
, String
> parameters
= new HashMap
<String
, String
>();
31 parameters
.put(NodeConstants
.CN
, alias
);
32 return repositoryFactory
.getRepository(parameters
);
33 } catch (RepositoryException e
) {
34 throw new RuntimeException("Unexpected exception when trying to retrieve repository with alias " + alias
,
40 * Wraps the call to the repository factory based on parameter
41 * {@link NodeConstants#LABELED_URI} in order to simplify it and protect against
44 public static Repository
getRepositoryByUri(RepositoryFactory repositoryFactory
, String uri
) {
45 return getRepositoryByUri(repositoryFactory
, uri
, null);
49 * Wraps the call to the repository factory based on parameter
50 * {@link NodeConstants#LABELED_URI} in order to simplify it and protect against
53 public static Repository
getRepositoryByUri(RepositoryFactory repositoryFactory
, String uri
, String alias
) {
55 Map
<String
, String
> parameters
= new HashMap
<String
, String
>();
56 parameters
.put(NodeConstants
.LABELED_URI
, uri
);
58 parameters
.put(NodeConstants
.CN
, alias
);
59 return repositoryFactory
.getRepository(parameters
);
60 } catch (RepositoryException e
) {
61 throw new RuntimeException("Unexpected exception when trying to retrieve repository with uri " + uri
, e
);
66 * Returns the home node of the user or null if none was found.
68 * @param session the session to use in order to perform the search, this can
69 * be a session with a different user ID than the one searched,
70 * typically when a system or admin session is used.
71 * @param username the username of the user
73 public static Node
getUserHome(Session session
, String username
) {
75 // QueryObjectModelFactory qomf = session.getWorkspace().getQueryManager().getQOMFactory();
76 // Selector sel = qomf.selector(NodeTypes.NODE_USER_HOME, "sel");
77 // DynamicOperand dop = qomf.propertyValue(sel.getSelectorName(), NodeNames.LDAP_UID);
78 // StaticOperand sop = qomf.literal(session.getValueFactory().createValue(username));
79 // Constraint constraint = qomf.comparison(dop, QueryObjectModelFactory.JCR_OPERATOR_EQUAL_TO, sop);
80 // Query query = qomf.createQuery(sel, constraint, null, null);
81 // return querySingleNode(query);
82 // } catch (RepositoryException e) {
83 // throw new RuntimeException("Cannot find home for user " + username, e);
87 checkUserWorkspace(session
, username
);
88 String homePath
= getHomePath(username
);
89 if (session
.itemExists(homePath
))
90 return session
.getNode(homePath
);
92 homePath
= "/home/" + username
;
93 if (session
.itemExists(homePath
))
94 return session
.getNode(homePath
);
96 } catch (RepositoryException e
) {
97 throw new RuntimeException("Cannot find home for user " + username
, e
);
101 private static String
getHomePath(String username
) {
104 dn
= new LdapName(username
);
105 } catch (InvalidNameException e
) {
106 throw new IllegalArgumentException("Invalid name " + username
, e
);
108 String userId
= dn
.getRdn(dn
.size() - 1).getValue().toString();
112 private static void checkUserWorkspace(Session session
, String username
) {
113 String workspaceName
= session
.getWorkspace().getName();
114 if (!NodeConstants
.HOME_WORKSPACE
.equals(workspaceName
))
115 throw new IllegalArgumentException(workspaceName
+ " is not the home workspace for user " + username
);
119 * Returns the home node of the user or null if none was found.
121 * @param session the session to use in order to perform the search, this can
122 * be a session with a different user ID than the one searched,
123 * typically when a system or admin session is used.
124 * @param groupname the name of the group
126 public static Node
getGroupHome(Session session
, String groupname
) {
128 // QueryObjectModelFactory qomf = session.getWorkspace().getQueryManager().getQOMFactory();
129 // Selector sel = qomf.selector(NodeTypes.NODE_GROUP_HOME, "sel");
130 // DynamicOperand dop = qomf.propertyValue(sel.getSelectorName(), NodeNames.LDAP_CN);
131 // StaticOperand sop = qomf.literal(session.getValueFactory().createValue(cn));
132 // Constraint constraint = qomf.comparison(dop, QueryObjectModelFactory.JCR_OPERATOR_EQUAL_TO, sop);
133 // Query query = qomf.createQuery(sel, constraint, null, null);
134 // return querySingleNode(query);
135 // } catch (RepositoryException e) {
136 // throw new RuntimeException("Cannot find home for group " + cn, e);
140 checkGroupWorkspace(session
, groupname
);
141 String homePath
= getGroupPath(groupname
);
142 if (session
.itemExists(homePath
))
143 return session
.getNode(homePath
);
145 homePath
= "/groups/" + groupname
;
146 if (session
.itemExists(homePath
))
147 return session
.getNode(homePath
);
149 } catch (RepositoryException e
) {
150 throw new RuntimeException("Cannot find home for group " + groupname
, e
);
155 private static String
getGroupPath(String groupname
) {
158 LdapName dn
= new LdapName(groupname
);
159 cn
= dn
.getRdn(dn
.size() - 1).getValue().toString();
160 } catch (InvalidNameException e
) {
166 private static void checkGroupWorkspace(Session session
, String groupname
) {
167 String workspaceName
= session
.getWorkspace().getName();
168 if (!NodeConstants
.SRV_WORKSPACE
.equals(workspaceName
))
169 throw new IllegalArgumentException(workspaceName
+ " is not the group workspace for group " + groupname
);
173 * Queries one single node.
175 * @return one single node or null if none was found
176 * @throws ArgeoJcrException if more than one node was found
178 // private static Node querySingleNode(Query query) {
179 // NodeIterator nodeIterator;
181 // QueryResult queryResult = query.execute();
182 // nodeIterator = queryResult.getNodes();
183 // } catch (RepositoryException e) {
184 // throw new RuntimeException("Cannot execute query " + query, e);
187 // if (nodeIterator.hasNext())
188 // node = nodeIterator.nextNode();
192 // if (nodeIterator.hasNext())
193 // throw new RuntimeException("Query returned more than one node.");
197 /** Returns the home node of the session user or null if none was found. */
198 public static Node
getUserHome(Session session
) {
199 String userID
= session
.getUserID();
200 return getUserHome(session
, userID
);
203 /** Whether this node is the home of the user of the underlying session. */
204 public static boolean isUserHome(Node node
) {
206 String userID
= node
.getSession().getUserID();
207 return node
.hasProperty(Property
.JCR_ID
) && node
.getProperty(Property
.JCR_ID
).getString().equals(userID
);
208 } catch (RepositoryException e
) {
209 throw new IllegalStateException(e
);
214 * Translate the path to this node into a path containing the name of the
215 * repository and the name of the workspace.
217 public static String
getDataPath(String cn
, Node node
) {
219 StringBuilder buf
= new StringBuilder(NodeConstants
.PATH_DATA
);
221 return buf
.append('/').append(cn
).append('/').append(node
.getSession().getWorkspace().getName())
222 .append(node
.getPath()).toString();
223 } catch (RepositoryException e
) {
224 throw new IllegalStateException("Cannot get data path for " + node
+ " in repository " + cn
, e
);
229 * Translate the path to this node into a path containing the name of the
230 * repository and the name of the workspace.
232 public static String
getDataPath(Node node
) {
233 return getDataPath(NodeConstants
.NODE
, node
);
237 * Open a JCR session with full read/write rights on the data, as
238 * {@link NodeConstants#ROLE_USER_ADMIN}, using the
239 * {@link NodeConstants#LOGIN_CONTEXT_DATA_ADMIN} login context. For security
240 * hardened deployement, use {@link AuthPermission} on this login context.
242 public static Session
openDataAdminSession(Repository repository
, String workspaceName
) {
243 ClassLoader currentCl
= Thread
.currentThread().getContextClassLoader();
244 LoginContext loginContext
;
246 loginContext
= new LoginContext(NodeConstants
.LOGIN_CONTEXT_DATA_ADMIN
);
247 loginContext
.login();
248 } catch (LoginException e1
) {
249 throw new RuntimeException("Could not login as data admin", e1
);
251 Thread
.currentThread().setContextClassLoader(currentCl
);
253 return Subject
.doAs(loginContext
.getSubject(), new PrivilegedAction
<Session
>() {
256 public Session
run() {
258 return repository
.login(workspaceName
);
259 } catch (NoSuchWorkspaceException e
) {
260 throw new IllegalArgumentException("No workspace " + workspaceName
+ " available", e
);
261 } catch (RepositoryException e
) {
262 throw new RuntimeException("Cannot open data admin session", e
);
270 private NodeUtils() {