1 /*****************************************************************************
2 * Copyright Igor Barma, Eric Brun, Alexandre Desoubeaux, Christian Martel,
5 * Ce logiciel est un programme informatique servant à l'évaluation des
8 * Ce logiciel est régi par la licence CeCILL soumise au droit français et
9 * respectant les principes de diffusion des logiciels libres. Vous pouvez
10 * utiliser, modifier et/ou redistribuer ce programme sous les conditions
11 * de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
12 * sur le site "http://www.cecill.info".
14 * En contrepartie de l'accessibilité au code source et des droits de copie,
15 * de modification et de redistribution accordés par cette licence, il n'est
16 * offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
17 * seule une responsabilité restreinte pèse sur l'auteur du programme, le
18 * titulaire des droits patrimoniaux et les concédants successifs.
20 * A cet égard l'attention de l'utilisateur est attirée sur les risques
21 * associés au chargement, à l'utilisation, à la modification et/ou au
22 * développement et à la reproduction du logiciel par l'utilisateur étant
23 * donné sa spécificité de logiciel libre, qui peut le rendre complexe à
24 * manipuler et qui le réserve donc à des développeurs et des professionnels
25 * avertis possédant des connaissances informatiques approfondies. Les
26 * utilisateurs sont donc invités à charger et tester l'adéquation du
27 * logiciel à leurs besoins dans des conditions permettant d'assurer la
28 * sécurité de leurs systèmes et ou de leurs données et, plus généralement,
29 * à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
31 * Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
32 * pris connaissance de la licence CeCILL, et que vous en avez accepté les
34 *******************************************************************************/
35 package com.pentila.jackrabbit.auth;
37 import java.security.Principal;
40 import javax.jcr.AccessDeniedException;
41 import javax.jcr.ItemNotFoundException;
42 import javax.jcr.Node;
43 import javax.jcr.PathNotFoundException;
44 import javax.jcr.RepositoryException;
46 import javax.jcr.Value;
48 import javax.security.auth.Subject;
52 import org.apache.jackrabbit.api.JackrabbitWorkspace;
54 import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
56 import org.apache.jackrabbit.core.HierarchyManager;
57 import org.apache.jackrabbit.core.SessionImpl;
58 import org.apache.jackrabbit.core.id.ItemId;
59 import org.apache.jackrabbit.core.security.AMContext;
60 import org.apache.jackrabbit.core.security.AccessManager;
61 import org.apache.jackrabbit.core.security.authorization.AccessControlProvider;
62 import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager;
64 import org.apache.jackrabbit.spi.Name;
65 import org.apache.jackrabbit.spi.Path;
66 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
68 import org.springframework.security.core.GrantedAuthority;
69 import org.springframework.security.core.userdetails.UserDetails;
72 * CasAccessManager pour l'intégration de l'authentification CAS pour Jackrabbit 2.3.3
75 public class CASAccessManager implements AccessManager{
77 private boolean initialized;
78 private Subject subject;
79 private HierarchyManager hierMgr;
80 private WorkspaceAccessManager wspAccessMgr;
81 private NamePathResolver resolver;
82 private PrivilegeManager privilegeManager;
83 private boolean system;
84 private static String access = "anonymous";
85 private AMContext context;
89 public void init(AMContext context) throws AccessDeniedException, Exception {
90 init(context, null, null);
93 public void init(AMContext context, AccessControlProvider acProvider,
94 WorkspaceAccessManager wspAccessMgr) throws AccessDeniedException,
97 throw new IllegalStateException("already initialized");
100 this.context = context;
102 subject = context.getSubject();
103 hierMgr = context.getHierarchyManager();
104 resolver = context.getNamePathResolver();
105 privilegeManager = ((JackrabbitWorkspace) context.getSession().getWorkspace()).getPrivilegeManager();
106 this.wspAccessMgr = wspAccessMgr;
111 // System.out.println("INIT : Subject Princiapl Numlber " + subject.getPrincipals().size());
113 for (Principal p : subject.getPrincipals()){
115 // System.out.println("Princial name : " + p.getName());
117 if (p.getName().equals("system")){
123 // @todo check permission to access given workspace based on principals
126 if (!canAccess(context.getWorkspaceName())) {
127 throw new AccessDeniedException("Not allowed to access Workspace " + context.getWorkspaceName());
133 public synchronized void close() throws Exception {
140 public void checkPermission(ItemId id, int permissions)
141 throws AccessDeniedException, ItemNotFoundException,
142 RepositoryException {
144 if (!isGranted(id, permissions)) {
145 throw new AccessDeniedException("Access denied");
149 public void checkPermission(Path absPath, int permissions)
150 throws AccessDeniedException, RepositoryException {
151 if (!isGranted(absPath, permissions)) {
152 throw new AccessDeniedException("Access denied");
157 public void checkRepositoryPermission(int permissions)
158 throws AccessDeniedException, RepositoryException {
159 if (!isGranted((ItemId) null, permissions)) {
160 throw new AccessDeniedException("Access denied");
165 public boolean isGranted(ItemId id, int permissions)
166 throws ItemNotFoundException, RepositoryException {
169 if (system || isAccessAnonymous()){
175 public boolean isGranted(Path absPath, int permissions)
176 throws RepositoryException {
178 if (!absPath.isAbsolute()) {
179 throw new RepositoryException("Absolute path expected");
182 if (system|| isAccessAnonymous()){
185 String uid = context.getSubject().getPrincipals().iterator().next().getName();
186 return check(absPath, permissions, uid);
189 public boolean isGranted(Path parentPath, Name childName, int permissions)
190 throws RepositoryException {
193 if (system|| isAccessAnonymous()){
196 String uid = context.getSubject().getPrincipals().iterator().next().getName();
197 return check(parentPath, permissions, uid);
200 public boolean canRead(Path itemPath, ItemId itemId)
201 throws RepositoryException {
203 String uid = context.getSubject().getPrincipals().iterator().next().getName();
204 if (itemPath != null){
205 return check(itemPath, 0, uid);
206 }else if (itemId != null){
207 return check(hierMgr.getPath(itemId), 0, uid);
217 public boolean canAccess(String workspaceName) throws RepositoryException {
219 if (system || isAccessAnonymous()|| wspAccessMgr == null) {
220 //System.out.println("system || isAccessAnonymous()|| wspAccessMgr == null");
224 UserDetails ud = CasAuth.getCurrentUser();
226 if (ud != null && ud.getAuthorities() != null){
227 for(GrantedAuthority auth : ud.getAuthorities()){
228 if (auth.equals(CasAuth.role)){
236 //System.out.println("Bye !");
239 //return wspAccessMgr.grants(subject.getPrincipals(), workspaceName);
243 protected void checkInitialized() throws IllegalStateException {
245 throw new IllegalStateException("not initialized");
249 protected void checkValidNodePath(String absPath) throws PathNotFoundException, RepositoryException {
250 if (absPath != null) {
251 Path path = resolver.getQPath(absPath);
252 if (!path.isAbsolute()) {
253 throw new RepositoryException("Absolute path expected. Found: " + absPath);
256 if (hierMgr.resolveNodePath(path) == null) {
257 throw new PathNotFoundException(absPath);
263 public boolean check(Path path, int permissions, String uid){
265 if (system || path == null || isAccessAnonymous()){
272 //System.out.println("******* ENTER in check with path : " + path);
274 boolean retVal = false;
279 if (hierMgr.resolveNodePath(path) == null){
281 //System.out.println("Path " + path.getString() + " in check is not found AND RETURN TRUE");
286 //System.out.println("RESOLVED PATH is : " + hierMgr.resolveNodePath(path));
290 SessionImpl it = ((SessionImpl)context.getSession());
294 n = it.getItemManager().getNode(path);
297 boolean isContentNode = n.getName().equals("jcr:content");
298 boolean isSystemNode = n.getName().equals("jcr:system");
304 boolean isFileNodeType = n.isNodeType("nt:file");
305 boolean isFolderNodeType = n.isNodeType("nt:folder");
306 boolean isRootFolder = n.getPath().equals("/");
307 //String path2 = n.getPath();
309 boolean isOwner = this.isOwner(n, uid);
310 boolean isShared = this.isShared(n, uid);
312 //Node parent = getFolder(n);
313 boolean foundInHierarchy = false;
315 /*while (parent != null && !foundInHierarchy) {
317 foundInHierarchy = this.isOwner(parent, uid) || this.isShared(parent, uid);
318 if (foundInHierarchy){
321 parent = this.getFolder(parent);
324 /*boolean isParentOwner = (foundInHierarchy)
325 || ((parent != null) && (this.isOwner(parent, uid)));*/
327 boolean isParentOwner = false;
328 boolean isRootParent = false;
330 isRootParent = n.getParent().getPath().equals("/");
331 } catch (Exception e) {
333 boolean isWorkspaceName = n.getName().equals(uid)
334 || n.getName().equals(uid + "_eval");
337 retVal = this.hasAccess(isFileNodeType, isFolderNodeType,
338 isRootFolder, isContentNode, isSystemNode, isParentOwner,
339 isWorkspaceName, isOwner, isRootParent, isShared);
342 //System.out.println("retVal of chech is : " + retVal);
344 } catch (AccessDeniedException e1) {
345 // TODO Auto-generated catch block
346 e1.printStackTrace();
347 } catch (PathNotFoundException e1) {
348 // TODO Auto-generated catch block
349 e1.printStackTrace();
350 } catch (RepositoryException e1) {
351 // TODO Auto-generated catch block
352 e1.printStackTrace();
360 public void setAccess(String access) {
361 CASAccessManager.access = access;
364 private boolean isAccessAnonymous(){
365 return access.equals("anonymous");
368 private Node getFolder(Node start) {
371 pp = start.getParent();
372 if (pp.isNodeType("nt:folder")) {
377 } catch (Exception e) {
385 public boolean isOwner(Node node, String userName) {
386 boolean retVal = false;
387 String type = "jcr:owner";
391 Value ownersList[] = node.getProperty(type).getValues();
392 // System.out.println("numar values found:" +
393 // ownersList.length);
394 for (Value i : ownersList) {
395 /*System.out.println(node.getName() + " >> "
396 + i.getString() + ".");*/
397 if (i.getString().equals(userName)) {
403 } catch (PathNotFoundException e) {
405 //e.printStackTrace();
406 } catch (RepositoryException e) {
408 //e.printStackTrace();
415 * Checks if the node has the user in access list.
417 * @param node the node
418 * @param userName the user name
420 * @return true if found
423 public boolean isShared(Node node, String userName) {
424 boolean retVal = false;
425 String type = "jcr:shared";
428 Value ownersList[] = node.getProperty(type).getValues();
429 // System.out.println("shared list size:" +
430 // ownersList.length);
431 for (Value i : ownersList) {
432 // System.out.println(" >> " + i.getString() + ".");
433 if (i.getString().equals(userName)) {
439 } catch (PathNotFoundException e) {
441 //e.printStackTrace();
442 } catch (RepositoryException e) {
444 //e.printStackTrace();
450 private boolean hasAccess(boolean isFileNodeType, boolean isFolderNodeType,
451 boolean isRootFolder, boolean isContentNode, boolean isSystemNode,
452 boolean isParentOwner, boolean isWorkspaceName, boolean isOwner,
453 boolean isRootParent, boolean isShared) {
455 //TODO : Seriouly must be perform !!!
458 boolean localHasAccess = isOwner || isShared;
461 return localHasAccess;
465 if (isFileNodeType || isFolderNodeType || isRootFolder || isContentNode
468 if (!localHasAccess && isContentNode && isParentOwner) {
470 localHasAccess = true;
473 if (!localHasAccess && (isRootFolder || isSystemNode)) {
475 localHasAccess = true;
478 if (!localHasAccess && isWorkspaceName && isRootParent) // in
484 localHasAccess = true;
489 localHasAccess = true;
496 if (!localHasAccess && isWorkspaceName && isRootParent) // in in
500 localHasAccess = true;
504 return localHasAccess;