2 * Copyright (C) 2007-2012 Mathieu Baudier
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org
.argeo
.jcr
.security
;
18 import java
.security
.Principal
;
19 import java
.util
.ArrayList
;
20 import java
.util
.HashMap
;
21 import java
.util
.List
;
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
;
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
;
39 /** Apply authorizations to a JCR repository. */
40 public class JcrAuthorizations
implements Runnable
{
41 private final static Log log
= LogFactory
.getLog(JcrAuthorizations
.class);
43 private Repository repository
;
44 private String workspace
= null;
47 * key := privilege1,privilege2/path/to/node<br/>
48 * value := group1,group2,user1
50 private Map
<String
, String
> principalPrivileges
= new HashMap
<String
, String
>();
53 Session session
= null;
55 session
= repository
.login(workspace
);
56 initAuthorizations(session
);
57 } catch (Exception e
) {
58 JcrUtils
.discardQuietly(session
);
60 JcrUtils
.logoutQuietly(session
);
64 /** @deprecated call {@link #run()} instead. */
70 protected void initAuthorizations(Session session
)
71 throws RepositoryException
{
72 AccessControlManager acm
= session
.getAccessControlManager();
74 for (String privileges
: principalPrivileges
.keySet()) {
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
);
88 List
<Privilege
> privs
= new ArrayList
<Privilege
>();
89 for (String priv
: privileges
.split(",")) {
90 privs
.add(acm
.privilegeFromName(priv
));
93 String principalNames
= principalPrivileges
.get(privileges
);
94 for (String principalName
: principalNames
.split(",")) {
95 Principal principal
= getOrCreatePrincipal(session
,
97 addPrivileges(session
, principal
, path
, privs
);
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
108 protected Principal
getOrCreatePrincipal(Session session
,
109 String principalName
) throws RepositoryException
{
110 return new SimplePrincipal(principalName
);
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
);
128 AccessControlPolicy
[] existingPolicies
= acm
.getPolicies(path
);
129 for (AccessControlPolicy acp
: existingPolicies
) {
130 if (acp
instanceof AccessControlList
)
131 acl
= ((AccessControlList
) acp
);
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
++) {
144 buf
.append(privs
.get(i
).getName());
146 log
.debug("Added privilege(s) '" + buf
+ "' to '"
147 + principal
.getName() + "' on " + path
148 + " from workspace '"
149 + session
.getWorkspace().getName() + "'");
152 throw new ArgeoException("Don't know how to apply privileges "
153 + privs
+ " to " + principal
+ " on " + path
154 + " from workspace '" + session
.getWorkspace().getName()
160 public void setGroupPrivileges(Map
<String
, String
> groupPrivileges
) {
161 this.principalPrivileges
= groupPrivileges
;
164 public void setPrincipalPrivileges(Map
<String
, String
> principalPrivileges
) {
165 this.principalPrivileges
= principalPrivileges
;
168 public void setRepository(Repository repository
) {
169 this.repository
= repository
;
172 public void setWorkspace(String workspace
) {
173 this.workspace
= workspace
;