]> 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 utilities
[lgpl/argeo-commons.git] / server / runtime / org.argeo.server.jcr / src / main / java / org / argeo / jcr / security / JcrAuthorizations.java
1 /*
2 * Copyright (C) 2007-2012 Mathieu Baudier
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.jcr.security;
17
18 import java.security.Principal;
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23
24 import javax.jcr.Repository;
25 import javax.jcr.RepositoryException;
26 import javax.jcr.Session;
27 import javax.jcr.security.AccessControlList;
28 import javax.jcr.security.AccessControlManager;
29 import javax.jcr.security.AccessControlPolicy;
30 import javax.jcr.security.AccessControlPolicyIterator;
31 import javax.jcr.security.Privilege;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.argeo.ArgeoException;
36 import org.argeo.jcr.JcrUtils;
37 import org.argeo.util.security.SimplePrincipal;
38
39 /** Apply authorizations to a JCR repository. */
40 public class JcrAuthorizations implements Runnable {
41 private final static Log log = LogFactory.getLog(JcrAuthorizations.class);
42
43 private Repository repository;
44 private String workspace = null;
45
46 /**
47 * key := privilege1,privilege2/path/to/node<br/>
48 * value := group1,group2,user1
49 */
50 private Map<String, String> principalPrivileges = new HashMap<String, String>();
51
52 public void run() {
53 Session session = null;
54 try {
55 session = repository.login(workspace);
56 initAuthorizations(session);
57 } catch (Exception e) {
58 JcrUtils.discardQuietly(session);
59 } finally {
60 JcrUtils.logoutQuietly(session);
61 }
62 }
63
64 /** @deprecated call {@link #run()} instead. */
65 @Deprecated
66 public void init() {
67 run();
68 }
69
70 protected void initAuthorizations(Session session)
71 throws RepositoryException {
72 AccessControlManager acm = session.getAccessControlManager();
73
74 for (String privileges : principalPrivileges.keySet()) {
75 String path = null;
76 int slashIndex = privileges.indexOf('/');
77 if (slashIndex == 0) {
78 throw new ArgeoException("Privilege " + privileges
79 + " badly formatted it starts with /");
80 } else if (slashIndex > 0) {
81 path = privileges.substring(slashIndex);
82 privileges = privileges.substring(0, slashIndex);
83 }
84
85 if (path == null)
86 path = "/";
87
88 List<Privilege> privs = new ArrayList<Privilege>();
89 for (String priv : privileges.split(",")) {
90 privs.add(acm.privilegeFromName(priv));
91 }
92
93 String principalNames = principalPrivileges.get(privileges);
94 for (String principalName : principalNames.split(",")) {
95 Principal principal = getOrCreatePrincipal(session,
96 principalName);
97 addPrivileges(session, principal, path, privs);
98 }
99 }
100 session.save();
101 }
102
103 /**
104 * Returns a {@link SimplePrincipal}, does not check whether it exists since
105 * such capabilities is not provided by the standard JCR API. Can be
106 * overridden to provide smarter handling
107 */
108 protected Principal getOrCreatePrincipal(Session session,
109 String principalName) throws RepositoryException {
110 return new SimplePrincipal(principalName);
111 }
112
113 public static void addPrivileges(Session session, Principal principal,
114 String path, List<Privilege> privs) throws RepositoryException {
115 AccessControlManager acm = session.getAccessControlManager();
116 // search for an access control list
117 AccessControlList acl = null;
118 AccessControlPolicyIterator policyIterator = acm
119 .getApplicablePolicies(path);
120 if (policyIterator.hasNext()) {
121 while (policyIterator.hasNext()) {
122 AccessControlPolicy acp = policyIterator
123 .nextAccessControlPolicy();
124 if (acp instanceof AccessControlList)
125 acl = ((AccessControlList) acp);
126 }
127 } else {
128 AccessControlPolicy[] existingPolicies = acm.getPolicies(path);
129 for (AccessControlPolicy acp : existingPolicies) {
130 if (acp instanceof AccessControlList)
131 acl = ((AccessControlList) acp);
132 }
133 }
134
135 if (acl != null) {
136 acl.addAccessControlEntry(principal,
137 privs.toArray(new Privilege[privs.size()]));
138 acm.setPolicy(path, acl);
139 if (log.isDebugEnabled()) {
140 StringBuffer buf = new StringBuffer("");
141 for (int i = 0; i < privs.size(); i++) {
142 if (i != 0)
143 buf.append(',');
144 buf.append(privs.get(i).getName());
145 }
146 log.debug("Added privilege(s) '" + buf + "' to '"
147 + principal.getName() + "' on " + path
148 + " from workspace '"
149 + session.getWorkspace().getName() + "'");
150 }
151 } else {
152 throw new ArgeoException("Don't know how to apply privileges "
153 + privs + " to " + principal + " on " + path
154 + " from workspace '" + session.getWorkspace().getName()
155 + "'");
156 }
157 }
158
159 @Deprecated
160 public void setGroupPrivileges(Map<String, String> groupPrivileges) {
161 this.principalPrivileges = groupPrivileges;
162 }
163
164 public void setPrincipalPrivileges(Map<String, String> principalPrivileges) {
165 this.principalPrivileges = principalPrivileges;
166 }
167
168 public void setRepository(Repository repository) {
169 this.repository = repository;
170 }
171
172 public void setWorkspace(String workspace) {
173 this.workspace = workspace;
174 }
175
176 }