--- /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.util.Properties;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.jcr.Value;
+import javax.naming.InitialContext;
+
+import org.apache.jackrabbit.core.ItemId;
+import org.apache.jackrabbit.core.NodeId;
+import org.apache.jackrabbit.core.PropertyId;
+import org.apache.jackrabbit.core.RepositoryImpl;
+import org.apache.jackrabbit.core.security.AMContext;
+import org.apache.jackrabbit.core.security.AccessManager;
+import org.apache.jackrabbit.uuid.UUID;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class SimpleCASAccessManager.
+ */
+public class SimpleCASAccessManager implements AccessManager {
+
+ /** The am context. */
+ AMContext amContext;
+
+ /** The is content node. */
+ boolean isContentNode = false;// = n.getName().equals("jcr:content");
+
+ /** The is file node type. */
+ boolean isFileNodeType = false;// = n.isNodeType("nt:file");
+
+ /** The is folder node type. */
+ boolean isFolderNodeType = false;// = n.isNodeType("nt:folder");
+
+ /** The is owner. */
+ boolean isOwner = false;// = this.isOwner(n, user);
+
+ /** The is parent owner. */
+ boolean isParentOwner = false;// = (parent != null) && (this.isOwner(parent,
+ // user));
+
+ /** The is root folder. */
+ boolean isRootFolder = false;// = n.getPath().equals("/");
+
+ /** The is root parent. */
+ boolean isRootParent = false;// = n.getParent().getPath().equals("/");
+
+ /** The is shared. */
+ boolean isShared = false;// = this.isOwner(n, user);
+
+ /** The is system node. */
+ boolean isSystemNode = false;// = n.getName().equals("jcr:system");
+
+ /** The is workspace name. */
+ boolean isWorkspaceName = false;
+
+ /** The path. */
+ String path = null;// = n.getPath();
+
+ /** The rep. */
+ RepositoryImpl rep;
+
+ /** The user. */
+ String user = null;
+
+ /** The access. */
+ private static String access = "anonymous";
+
+ /** The superuser. */
+ private static boolean superuser = false;
+
+ /**
+ * Instantiates a new simple cas access manager.
+ */
+ public SimpleCASAccessManager() {
+ super();
+ try {
+ if (rep == null) {
+ Properties props = new Properties();
+ props
+ .put("java.naming.factory.initial",
+ "org.apache.jackrabbit.core.jndi.provider.DummyInitialContextFactory");
+ props.put("java.naming.provider.url",
+ "http://www.apache.org/jackrabbit");
+
+ InitialContext ic = new InitialContext(props);
+ rep = (RepositoryImpl) ic.lookup("jackrabbit.repository");
+ }
+ } catch (Exception e) {
+ //e.printStackTrace();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.jackrabbit.core.security.AccessManager#canAccess(java.lang.String)
+ */
+ public boolean canAccess(String arg0) throws NoSuchWorkspaceException,
+ RepositoryException {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.jackrabbit.core.security.AccessManager#checkPermission(org.apache.jackrabbit.core.ItemId, int)
+ */
+ public void checkPermission(ItemId arg0, int arg1)
+ throws AccessDeniedException, ItemNotFoundException,
+ RepositoryException {
+ return;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.jackrabbit.core.security.AccessManager#close()
+ */
+ public void close() throws Exception {
+ user = null;
+ }
+
+ /**
+ * Gets the access.
+ *
+ * @return access : anonimus or restricted
+ */
+ public String getAccess() {
+ return access;
+ }
+
+ /**
+ * Used tu get the folder of the current node. if this node is of
+ * "jcr:content" type, which is a child node of "nt:file" which can be in a
+ * "nt:folder" node, it will return the "nt:folder" node.
+ *
+ * @param start the node from where the search is made. No matter if the node
+ * it is a folder, it will start looking in the parent node.
+ *
+ * @return the first "nt:folder" found
+ */
+ 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;
+ }
+
+ /**
+ * Retreives the node found in requestNode item.
+ *
+ * @param requestNode ItemId ( can be NodeId or PropertyId )
+ * @param jcrSession a open session object
+ *
+ * @return the Node located in requestNode item
+ *
+ * @throws ItemNotFoundException the item not found exception
+ * @throws RepositoryException the repository exception
+ */
+ private Node getNode(ItemId requestNode, Session jcrSession)
+ throws ItemNotFoundException, RepositoryException {
+ NodeId nid = null;
+ UUID uuid = null;
+
+ if (requestNode.denotesNode()) {
+ nid = (NodeId) requestNode;
+ } else {
+ PropertyId pid = (PropertyId) requestNode;
+ nid = pid.getParentId();
+ }
+ uuid = nid.getUUID();
+ String u = uuid.toString();
+
+ return jcrSession.getNodeByUUID(u);
+ }
+
+ /**
+ * Will test if the following parameters will grant or not the current user.
+ *
+ * @param isFileNodeType the is file node type
+ * @param isFolderNodeType the is folder node type
+ * @param isRootFolder the is root folder
+ * @param isContentNode the is content node
+ * @param isSystemNode the is system node
+ * @param isParentOwner the is parent owner
+ * @param isWorkspaceName the is workspace name
+ * @param isOwner the is owner
+ * @param isRootParent the is root parent
+ * @param isShared the is shared
+ *
+ * @return true, if checks for access
+ */
+ 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;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.jackrabbit.core.security.AccessManager#init(org.apache.jackrabbit.core.security.AMContext)
+ */
+ public void init(AMContext amContext) throws AccessDeniedException,
+ Exception {
+ superuser = false;
+ user = amContext.getSubject().getPrincipals().iterator().next()
+ .getName().trim();
+ if (user.equals("system")){
+ superuser = true;
+ }
+ this.amContext = amContext;
+ }
+
+ /**
+ * Main method called by the cas. In permissionLevel will be the action: 1
+ * is read 2 is add 0 is delete
+ *
+ * @param arg0 the arg0
+ * @param permissionLevel the permission level
+ *
+ * @return true, if checks if is granted
+ *
+ * @throws ItemNotFoundException the item not found exception
+ * @throws RepositoryException the repository exception
+ */
+ public boolean isGranted(ItemId arg0, int permissionLevel)
+ throws ItemNotFoundException, RepositoryException {
+
+ // TODO : must be perform
+
+ if (access.equals("anonymous")) {
+ return true;
+ } else if (access.equals("restricted")) {
+ if (superuser) {
+ return true;
+ }
+ Session jcrSession = rep.login(new SimpleCredentials(user, user
+ .toCharArray()));
+
+ superuser = true;
+ // j =1
+ Node n = this.getNode(arg0, jcrSession);
+
+ isContentNode = n.getName().equals("jcr:content");
+ isSystemNode = n.getName().equals("jcr:system");
+
+ if (isContentNode){
+ n = n.getParent();
+ }
+
+ isFileNodeType = n.isNodeType("nt:file");
+ isFolderNodeType = n.isNodeType("nt:folder");
+ isRootFolder = n.getPath().equals("/");
+ path = n.getPath();
+
+ isOwner = this.isOwner(n, user);
+ isShared = this.isShared(n, user);
+
+ Node parent = getFolder(n);
+ boolean foundInHierarchy = false;
+
+ while (parent != null && !foundInHierarchy) {
+
+ foundInHierarchy = this.isOwner(parent, user) || this.isShared(parent, user);
+ if (foundInHierarchy){
+ break;
+ }
+ parent = this.getFolder(parent);
+ }
+
+ isParentOwner = (foundInHierarchy)
+ || ((parent != null) && (this.isOwner(parent, user)));
+
+ try {
+ isRootParent = n.getParent().getPath().equals("/");
+ } catch (Exception e) {
+ }
+ isWorkspaceName = n.getName().equals(user)
+ || n.getName().equals(user + "_eval");
+ superuser = false;
+ jcrSession.logout();
+ boolean retVal = this.hasAccess(isFileNodeType, isFolderNodeType,
+ isRootFolder, isContentNode, isSystemNode, isParentOwner,
+ isWorkspaceName, isOwner, isRootParent, isShared);
+
+ return retVal;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Tests if the node has the userName in access list.
+ *
+ * @param node node
+ * @param userName user
+ *
+ * @return true if found
+ */
+ private 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
+ */
+ private 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;
+ }
+
+ /**
+ * Set the access parameter which can be modified in the repository.xml
+ * file.
+ *
+ * @param access the access
+ */
+ public void setAccess(String access) {
+ SimpleCASAccessManager.access = access;
+ }
+}