--- /dev/null
+/*****************************************************************************
+* Copyright Igor Barma, Eric Brun, Alexandre Desoubeaux, Christian Martel,
+* (2 décembre 2008)
+*
+* Ce logiciel est un programme informatique servant à l'évaluation des
+* compétences.
+*
+* Ce logiciel est régi par la licence CeCILL soumise au droit français et
+* respectant les principes de diffusion des logiciels libres. Vous pouvez
+* utiliser, modifier et/ou redistribuer ce programme sous les conditions
+* de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
+* sur le site "http://www.cecill.info".
+*
+* En contrepartie de l'accessibilité au code source et des droits de copie,
+* de modification et de redistribution accordés par cette licence, il n'est
+* offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
+* seule une responsabilité restreinte pèse sur l'auteur du programme, le
+* titulaire des droits patrimoniaux et les concédants successifs.
+*
+* A cet égard l'attention de l'utilisateur est attirée sur les risques
+* associés au chargement, à l'utilisation, à la modification et/ou au
+* développement et à la reproduction du logiciel par l'utilisateur étant
+* donné sa spécificité de logiciel libre, qui peut le rendre complexe à
+* manipuler et qui le réserve donc à des développeurs et des professionnels
+* avertis possédant des connaissances informatiques approfondies. Les
+* utilisateurs sont donc invités à charger et tester l'adéquation du
+* logiciel à leurs besoins dans des conditions permettant d'assurer la
+* sécurité de leurs systèmes et ou de leurs données et, plus généralement,
+* à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
+*
+* Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
+* pris connaissance de la licence CeCILL, et que vous en avez accepté les
+* termes.
+*******************************************************************************/
+package com.pentila.jackrabbit.auth;
+
+import java.security.Principal;
+
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+
+import javax.jcr.Value;
+
+import javax.security.auth.Subject;
+
+
+
+import org.apache.jackrabbit.api.JackrabbitWorkspace;
+
+import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
+
+import org.apache.jackrabbit.core.HierarchyManager;
+import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.core.id.ItemId;
+import org.apache.jackrabbit.core.security.AMContext;
+import org.apache.jackrabbit.core.security.AccessManager;
+import org.apache.jackrabbit.core.security.authorization.AccessControlProvider;
+import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager;
+
+import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.Path;
+import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
+
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+/*
+ * CasAccessManager pour l'intégration de l'authentification CAS pour Jackrabbit 2.3.3
+ */
+
+public class CASAccessManager implements AccessManager{
+
+ private boolean initialized;
+ private Subject subject;
+ private HierarchyManager hierMgr;
+ private WorkspaceAccessManager wspAccessMgr;
+ private NamePathResolver resolver;
+ private PrivilegeManager privilegeManager;
+ private boolean system;
+ private static String access = "anonymous";
+ private AMContext context;
+ private int echo;
+
+
+ public void init(AMContext context) throws AccessDeniedException, Exception {
+ init(context, null, null);
+ }
+
+ public void init(AMContext context, AccessControlProvider acProvider,
+ WorkspaceAccessManager wspAccessMgr) throws AccessDeniedException,
+ Exception {
+ if (initialized) {
+ throw new IllegalStateException("already initialized");
+ }
+
+ this.context = context;
+
+ subject = context.getSubject();
+ hierMgr = context.getHierarchyManager();
+ resolver = context.getNamePathResolver();
+ privilegeManager = ((JackrabbitWorkspace) context.getSession().getWorkspace()).getPrivilegeManager();
+ this.wspAccessMgr = wspAccessMgr;
+
+ system = false;
+
+
+ // System.out.println("INIT : Subject Princiapl Numlber " + subject.getPrincipals().size());
+
+ for (Principal p : subject.getPrincipals()){
+
+ // System.out.println("Princial name : " + p.getName());
+
+ if (p.getName().equals("system")){
+ system = true;
+ break;
+ }
+ }
+
+ // @todo check permission to access given workspace based on principals
+ initialized = true;
+
+ if (!canAccess(context.getWorkspaceName())) {
+ throw new AccessDeniedException("Not allowed to access Workspace " + context.getWorkspaceName());
+ }
+
+
+ }
+
+ public synchronized void close() throws Exception {
+ checkInitialized();
+ initialized = false;
+
+ }
+
+
+ public void checkPermission(ItemId id, int permissions)
+ throws AccessDeniedException, ItemNotFoundException,
+ RepositoryException {
+
+ if (!isGranted(id, permissions)) {
+ throw new AccessDeniedException("Access denied");
+ }
+ }
+
+ public void checkPermission(Path absPath, int permissions)
+ throws AccessDeniedException, RepositoryException {
+ if (!isGranted(absPath, permissions)) {
+ throw new AccessDeniedException("Access denied");
+ }
+
+ }
+
+ public void checkRepositoryPermission(int permissions)
+ throws AccessDeniedException, RepositoryException {
+ if (!isGranted((ItemId) null, permissions)) {
+ throw new AccessDeniedException("Access denied");
+ }
+
+ }
+
+ public boolean isGranted(ItemId id, int permissions)
+ throws ItemNotFoundException, RepositoryException {
+
+ checkInitialized();
+ if (system || isAccessAnonymous()){
+ return true;
+ }
+ return false;
+ }
+
+ public boolean isGranted(Path absPath, int permissions)
+ throws RepositoryException {
+
+ if (!absPath.isAbsolute()) {
+ throw new RepositoryException("Absolute path expected");
+ }
+ checkInitialized();
+ if (system|| isAccessAnonymous()){
+ return true;
+ }
+ String uid = context.getSubject().getPrincipals().iterator().next().getName();
+ return check(absPath, permissions, uid);
+ }
+
+ public boolean isGranted(Path parentPath, Name childName, int permissions)
+ throws RepositoryException {
+
+ checkInitialized();
+ if (system|| isAccessAnonymous()){
+ return true;
+ }
+ String uid = context.getSubject().getPrincipals().iterator().next().getName();
+ return check(parentPath, permissions, uid);
+ }
+
+ public boolean canRead(Path itemPath, ItemId itemId)
+ throws RepositoryException {
+ if (echo==0){
+ String uid = context.getSubject().getPrincipals().iterator().next().getName();
+ if (itemPath != null){
+ return check(itemPath, 0, uid);
+ }else if (itemId != null){
+ return check(hierMgr.getPath(itemId), 0, uid);
+
+
+ }else{
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean canAccess(String workspaceName) throws RepositoryException {
+
+ if (system || isAccessAnonymous()|| wspAccessMgr == null) {
+ //System.out.println("system || isAccessAnonymous()|| wspAccessMgr == null");
+ return true;
+ }
+ try{
+ UserDetails ud = CasAuth.getCurrentUser();
+
+ if (ud != null && ud.getAuthorities() != null){
+ for(GrantedAuthority auth : ud.getAuthorities()){
+ if (auth.equals(CasAuth.role)){
+ return true;
+ }
+ }
+ }
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ //System.out.println("Bye !");
+
+ return true;
+ //return wspAccessMgr.grants(subject.getPrincipals(), workspaceName);
+ }
+
+
+ protected void checkInitialized() throws IllegalStateException {
+ if (!initialized) {
+ throw new IllegalStateException("not initialized");
+ }
+ }
+
+ protected void checkValidNodePath(String absPath) throws PathNotFoundException, RepositoryException {
+ if (absPath != null) {
+ Path path = resolver.getQPath(absPath);
+ if (!path.isAbsolute()) {
+ throw new RepositoryException("Absolute path expected. Found: " + absPath);
+ }
+
+ if (hierMgr.resolveNodePath(path) == null) {
+ throw new PathNotFoundException(absPath);
+ }
+ }
+ }
+
+
+ public boolean check(Path path, int permissions, String uid){
+
+ if (system || path == null || isAccessAnonymous()){
+ return true;
+ }
+
+ echo = 1;
+
+
+ //System.out.println("******* ENTER in check with path : " + path);
+
+ boolean retVal = false;
+
+
+ try {
+ Node n;
+ if (hierMgr.resolveNodePath(path) == null){
+
+ //System.out.println("Path " + path.getString() + " in check is not found AND RETURN TRUE");
+ echo =0;
+ return true;
+ }else{
+
+ //System.out.println("RESOLVED PATH is : " + hierMgr.resolveNodePath(path));
+
+ }
+
+ SessionImpl it = ((SessionImpl)context.getSession());
+
+
+
+ n = it.getItemManager().getNode(path);
+
+
+ boolean isContentNode = n.getName().equals("jcr:content");
+ boolean isSystemNode = n.getName().equals("jcr:system");
+
+ if (isContentNode){
+ n = n.getParent();
+ }
+
+ boolean isFileNodeType = n.isNodeType("nt:file");
+ boolean isFolderNodeType = n.isNodeType("nt:folder");
+ boolean isRootFolder = n.getPath().equals("/");
+ //String path2 = n.getPath();
+
+ boolean isOwner = this.isOwner(n, uid);
+ boolean isShared = this.isShared(n, uid);
+
+ //Node parent = getFolder(n);
+ boolean foundInHierarchy = false;
+
+ /*while (parent != null && !foundInHierarchy) {
+
+ foundInHierarchy = this.isOwner(parent, uid) || this.isShared(parent, uid);
+ if (foundInHierarchy){
+ break;
+ }
+ parent = this.getFolder(parent);
+ }*/
+
+ /*boolean isParentOwner = (foundInHierarchy)
+ || ((parent != null) && (this.isOwner(parent, uid)));*/
+
+ boolean isParentOwner = false;
+ boolean isRootParent = false;
+ /*try {
+ isRootParent = n.getParent().getPath().equals("/");
+ } catch (Exception e) {
+ }*/
+ boolean isWorkspaceName = n.getName().equals(uid)
+ || n.getName().equals(uid + "_eval");
+
+
+ retVal = this.hasAccess(isFileNodeType, isFolderNodeType,
+ isRootFolder, isContentNode, isSystemNode, isParentOwner,
+ isWorkspaceName, isOwner, isRootParent, isShared);
+
+
+ //System.out.println("retVal of chech is : " + retVal);
+
+ } catch (AccessDeniedException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ } catch (PathNotFoundException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ } catch (RepositoryException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
+ echo = 0;
+ return retVal;
+ }
+
+
+
+ public void setAccess(String access) {
+ CASAccessManager.access = access;
+ }
+
+ private boolean isAccessAnonymous(){
+ return access.equals("anonymous");
+ }
+
+ private Node getFolder(Node start) {
+ Node pp;
+ try {
+ pp = start.getParent();
+ if (pp.isNodeType("nt:folder")) {
+ return pp;
+ } else {
+ getFolder(pp);
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ return pp;
+ }
+
+
+
+ public boolean isOwner(Node node, String userName) {
+ boolean retVal = false;
+ String type = "jcr:owner";
+ if (node != null) {
+ try {
+
+ Value ownersList[] = node.getProperty(type).getValues();
+ // System.out.println("numar values found:" +
+ // ownersList.length);
+ for (Value i : ownersList) {
+ /*System.out.println(node.getName() + " >> "
+ + i.getString() + ".");*/
+ if (i.getString().equals(userName)) {
+ retVal = true;
+ break;
+ }
+ }
+
+ } catch (PathNotFoundException e) {
+
+ //e.printStackTrace();
+ } catch (RepositoryException e) {
+
+ //e.printStackTrace();
+ }
+ }
+ return retVal;
+ }
+
+ /**
+ * Checks if the node has the user in access list.
+ *
+ * @param node the node
+ * @param userName the user name
+ *
+ * @return true if found
+ */
+
+ public boolean isShared(Node node, String userName) {
+ boolean retVal = false;
+ String type = "jcr:shared";
+ if (node != null) {
+ try {
+ Value ownersList[] = node.getProperty(type).getValues();
+ // System.out.println("shared list size:" +
+ // ownersList.length);
+ for (Value i : ownersList) {
+ // System.out.println(" >> " + i.getString() + ".");
+ if (i.getString().equals(userName)) {
+ retVal = true;
+ break;
+ }
+ }
+
+ } catch (PathNotFoundException e) {
+
+ //e.printStackTrace();
+ } catch (RepositoryException e) {
+
+ //e.printStackTrace();
+ }
+ }
+ return retVal;
+ }
+
+ private boolean hasAccess(boolean isFileNodeType, boolean isFolderNodeType,
+ boolean isRootFolder, boolean isContentNode, boolean isSystemNode,
+ boolean isParentOwner, boolean isWorkspaceName, boolean isOwner,
+ boolean isRootParent, boolean isShared) {
+
+ //TODO : Seriouly must be perform !!!
+ // FIXME : SOON !!
+
+ boolean localHasAccess = isOwner || isShared;
+
+ if (localHasAccess){
+ return localHasAccess;
+ }
+
+
+ if (isFileNodeType || isFolderNodeType || isRootFolder || isContentNode
+ || isSystemNode) {
+
+ if (!localHasAccess && isContentNode && isParentOwner) {
+
+ localHasAccess = true;
+ } else {
+
+ if (!localHasAccess && (isRootFolder || isSystemNode)) {
+
+ localHasAccess = true;
+ } else {
+
+ if (!localHasAccess && isWorkspaceName && isRootParent) // in
+ // in
+ // root
+ // path
+ {
+
+ localHasAccess = true;
+ } else {
+
+ if (isParentOwner) {
+
+ localHasAccess = true;
+ }
+ }
+ }
+ }
+ } else {
+
+ if (!localHasAccess && isWorkspaceName && isRootParent) // in in
+ // root path
+ {
+
+ localHasAccess = true;
+ }
+ }
+
+ return localHasAccess;
+ }
+
+
+}