]> git.argeo.org Git - lgpl/argeo-commons.git/blob - server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/security/JcrAuthorizations.java
Improve JCR authorizations
[lgpl/argeo-commons.git] / server / runtime / org.argeo.server.jcr / src / main / java / org / argeo / jcr / security / JcrAuthorizations.java
1 package org.argeo.jcr.security;
2
3 import java.security.Principal;
4 import java.util.ArrayList;
5 import java.util.HashMap;
6 import java.util.List;
7 import java.util.Map;
8
9 import javax.jcr.Repository;
10 import javax.jcr.RepositoryException;
11 import javax.jcr.Session;
12 import javax.jcr.security.AccessControlList;
13 import javax.jcr.security.AccessControlManager;
14 import javax.jcr.security.AccessControlPolicy;
15 import javax.jcr.security.AccessControlPolicyIterator;
16 import javax.jcr.security.Privilege;
17
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20 import org.argeo.ArgeoException;
21 import org.argeo.jcr.JcrUtils;
22 import org.argeo.util.security.SimplePrincipal;
23
24 /** Apply authorizations to a JCR repository. */
25 public class JcrAuthorizations implements Runnable {
26 private final static Log log = LogFactory.getLog(JcrAuthorizations.class);
27
28 private Repository repository;
29
30 /**
31 * key := privilege1,privilege2/path/to/node<br/>
32 * value := group1,group2,user1
33 */
34 private Map<String, String> principalPrivileges = new HashMap<String, String>();
35
36 public void run() {
37 Session session = null;
38 try {
39 session = repository.login();
40 initAuthorizations(session);
41 } catch (Exception e) {
42 JcrUtils.discardQuietly(session);
43 } finally {
44 JcrUtils.logoutQuietly(session);
45 }
46 }
47
48 /** @deprecated call {@link #run()} instead. */
49 @Deprecated
50 public void init() {
51 run();
52 }
53
54 protected void initAuthorizations(Session session)
55 throws RepositoryException {
56 AccessControlManager acm = session.getAccessControlManager();
57
58 for (String privileges : principalPrivileges.keySet()) {
59 String path = null;
60 int slashIndex = privileges.indexOf('/');
61 if (slashIndex == 0) {
62 throw new ArgeoException("Privilege " + privileges
63 + " badly formatted it starts with /");
64 } else if (slashIndex > 0) {
65 path = privileges.substring(slashIndex);
66 privileges = privileges.substring(0, slashIndex);
67 }
68
69 if (path == null)
70 path = "/";
71
72 List<Privilege> privs = new ArrayList<Privilege>();
73 for (String priv : privileges.split(",")) {
74 privs.add(acm.privilegeFromName(priv));
75 }
76
77 String principalNames = principalPrivileges.get(privileges);
78 for (String principalName : principalNames.split(",")) {
79 Principal principal = getOrCreatePrincipal(session,
80 principalName);
81 addPrivileges(session, principal, path, privs);
82 }
83 }
84 session.save();
85 }
86
87 /**
88 * Returns a {@link SimplePrincipal}, does not check whether it exists since
89 * such capabilities is not provided by the standard JCR API. Can be
90 * overridden to provide smarter handling
91 */
92 protected Principal getOrCreatePrincipal(Session session,
93 String principalName) throws RepositoryException {
94 return new SimplePrincipal(principalName);
95 }
96
97 public static void addPrivileges(Session session, Principal principal,
98 String path, List<Privilege> privs) throws RepositoryException {
99 AccessControlManager acm = session.getAccessControlManager();
100 // search for an access control list
101 AccessControlList acl = null;
102 AccessControlPolicyIterator policyIterator = acm
103 .getApplicablePolicies(path);
104 if (policyIterator.hasNext()) {
105 while (policyIterator.hasNext()) {
106 AccessControlPolicy acp = policyIterator
107 .nextAccessControlPolicy();
108 if (acp instanceof AccessControlList)
109 acl = ((AccessControlList) acp);
110 }
111 } else {
112 AccessControlPolicy[] existingPolicies = acm.getPolicies(path);
113 for (AccessControlPolicy acp : existingPolicies) {
114 if (acp instanceof AccessControlList)
115 acl = ((AccessControlList) acp);
116 }
117 }
118
119 if (acl != null) {
120 acl.addAccessControlEntry(principal,
121 privs.toArray(new Privilege[privs.size()]));
122 acm.setPolicy(path, acl);
123 if (log.isDebugEnabled())
124 log.debug("Added privileges " + privs + " to " + principal
125 + " on " + path);
126 } else {
127 throw new ArgeoException("Don't know how to apply privileges "
128 + privs + " to " + principal + " on " + path);
129 }
130 }
131
132 @Deprecated
133 public void setGroupPrivileges(Map<String, String> groupPrivileges) {
134 this.principalPrivileges = groupPrivileges;
135 }
136
137 public void setPrincipalPrivileges(Map<String, String> principalPrivileges) {
138 this.principalPrivileges = principalPrivileges;
139 }
140
141 public void setRepository(Repository repository) {
142 this.repository = repository;
143 }
144
145 }