I'm programming my own AccessManager and I have two issues. The first is
with actual jacrabbit version 1.0.1. In attached file Dummy.java line 70
there is a comment about this. In the development version this bug is
gone.

But a have another bug in the development version of Jackrabbit. This is
a weir error because I can't reproduce it always. But with this code it
raises very often:

for (int i=0; i<100; i++) {
   Node n1 = myRoot.addNode("pepe "+i, "nt:hierarchyNode");
}

The exception is thrown in line 93 of MyAccessManager.java. There is a
comment on it. The exception says me that HierarchyManager can't build a
path.

-- 
Paco Avila <[EMAIL PROTECTED]>

Attachment: repository2.xml
Description: application/xml

/**
 * 
 */
package es.git.openkm.test;

import javax.jcr.AccessDeniedException;
import javax.jcr.ItemNotFoundException;
import javax.jcr.NoSuchWorkspaceException;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.security.auth.Subject;

import org.apache.jackrabbit.core.HierarchyManager;
import org.apache.jackrabbit.core.ItemId;
import org.apache.jackrabbit.core.NodeId;
import org.apache.jackrabbit.core.PropertyId;
import org.apache.jackrabbit.core.SessionImpl;
import org.apache.jackrabbit.core.security.AMContext;
import org.apache.jackrabbit.core.security.AccessManager;
import org.apache.jackrabbit.core.security.UserPrincipal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Paco Avila
 * 
 */
public class MyAccessManager implements AccessManager {
	private static Logger log = LoggerFactory.getLogger(MyAccessManager.class);
	private Subject subject = null;
	private HierarchyManager hierMgr = null;
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.jackrabbit.core.security.AccessManager#init(org.apache.jackrabbit.core.security.AMContext)
	 */
	public void init(AMContext context) throws AccessDeniedException, Exception {
		log.debug("init(" + context + ")");
		subject = context.getSubject();
		log.debug("##### "+subject.getPrincipals());
		hierMgr = context.getHierarchyManager();
		log.debug("init: void");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.jackrabbit.core.security.AccessManager#close()
	 */
	public void close() throws Exception {
		log.debug("close()");
		log.debug("close: void");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.jackrabbit.core.security.AccessManager#checkPermission(org.apache.jackrabbit.core.ItemId,
	 *      int)
	 */
	public void checkPermission(ItemId id, int permissions)
			throws AccessDeniedException, ItemNotFoundException,
			RepositoryException {
		log.debug("checkPermission()");
		log.debug("checkPermission: void");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.jackrabbit.core.security.AccessManager#isGranted(org.apache.jackrabbit.core.ItemId,
	 *      int)
	 */
	public boolean isGranted(ItemId id, int permissions)
			throws ItemNotFoundException, RepositoryException {
		log.debug("isGranted(" + subject.getPrincipals() + ", " + id + ", "
				+ (permissions == AccessManager.READ ? "READ"
						: (permissions == AccessManager.WRITE ? "WRITE"
								: (permissions == AccessManager.REMOVE ? "REMOVE"
										: "NONE"))) + ")");
		boolean access = false;
		Session systemSession = Dummy.getSystemSession();
		NodeId nodeId = null;
		
		log.debug(subject.getPrincipals()+" Item Id: "+id);

		// Sometimes I have this error in the next line: 
		// java.jcr.ItemNotFoundException: failed to build path of ....
		log.debug(subject.getPrincipals()+" Item Path: "+hierMgr.getPath(id));
		
		if (subject.getPrincipals().contains(new UserPrincipal(systemSession.getUserID()))) {
			// If user is System access is always TRUE to avoid infinite access check loop
			access = true;
		} else {
			if (id instanceof NodeId) {
				nodeId = (NodeId) id;
				log.debug(subject.getPrincipals()+" This is a NODE");
			} else {
				PropertyId propertyId = (PropertyId) id;
				nodeId = propertyId.getParentId();
				log.debug(subject.getPrincipals()+" This is a PROPERTY");
			}
		
			Node node = ((SessionImpl) systemSession).getNodeById(nodeId);
			log.debug(subject.getPrincipals()+" Node Name: " + node.getPath());
			log.debug(subject.getPrincipals()+" Node Type: " + node.getPrimaryNodeType().getName());
		
			if (hierMgr.getPath(nodeId).denotesRoot()) {
				// Root node has full access
				access = true;
			} else {
				// Check for user node access
				if (permissions == AccessManager.READ) {
					for (PropertyIterator pi = node.getProperties(); pi.hasNext(); ) {
						Property property = (Property) pi.nextProperty();
						log.debug("Property: " + property.getName());
						//try { Thread.sleep(250); } catch (Exception e) { e.printStackTrace(); }
					}
					access = true;
				} else if (permissions == AccessManager.WRITE) {
					for (PropertyIterator pi = node.getProperties(); pi.hasNext(); ) {
						Property property = (Property) pi.nextProperty();
						log.debug("Property: " + property.getName());
						//try { Thread.sleep(250); } catch (Exception e) { e.printStackTrace(); }
					}
					access = true;
				} else if (permissions == AccessManager.REMOVE) {
					for (PropertyIterator pi = node.getProperties(); pi.hasNext(); ) {
						Property property = (Property) pi.nextProperty();
						log.debug("Property: " + property.getName());
						//try { Thread.sleep(250); } catch (Exception e) { e.printStackTrace(); }
					}
				}
			}
		}
		
		log.debug(subject.getPrincipals()+" Path: " + hierMgr.getPath(id));
		log.debug(subject.getPrincipals()+" isGranted: " + access);
		log.debug("--------------------------");
		return access;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.jackrabbit.core.security.AccessManager#canAccess(java.lang.String)
	 */
	public boolean canAccess(String workspaceName)
			throws NoSuchWorkspaceException, RepositoryException {
		boolean access = true;
		log.debug("canAccess(" + workspaceName + ")");
		log.debug("canAccess: " + access);
		return access;
	}
}
package es.git.openkm.test;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Calendar;
import javax.jcr.AccessDeniedException;
import javax.jcr.InvalidItemStateException;
import javax.jcr.ItemExistsException;
import javax.jcr.ItemNotFoundException;
import javax.jcr.LoginException;
import javax.jcr.NamespaceException;
import javax.jcr.NoSuchWorkspaceException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.ValueFormatException;
import javax.jcr.Workspace;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.query.InvalidQueryException;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.jcr.version.VersionException;

import javax.naming.NamingException;

import org.apache.commons.io.FileUtils;
import org.apache.jackrabbit.core.RepositoryImpl;
import org.apache.jackrabbit.core.config.RepositoryConfig;
import org.apache.jackrabbit.core.jndi.RegistryHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Dummy {
	private static Logger log = LoggerFactory.getLogger(Dummy.class);
	private static String repHomeDir = "repotest2";
	private static Session systemSession = null;
	private static Repository repository = null;
	
	public static void main(String[] args) throws NamingException,
			RepositoryException, FileNotFoundException {
		log.debug("*** DESTROY REPOSITORY ***");
		removeRepository();
		
		log.debug("*** CREATE REPOSITORY ***");
		createRepository();
		
		log.debug("*** USER LOGIN ***");
		Session userSession = login("paco", "pepe");
		
		log.debug("*** GET MY ROOT NODE ***");
		Node rootNode = userSession.getRootNode();
		Node myRoot = rootNode.getNode("my:root");
				
		log.debug("*** ADD A DOCUMENT NODE ***");
		Node fileNode = myRoot.addNode("perico", "nt:file");
		
		// With Jackrabbot 1.0.1 I have always a bug in the next line:
		// javax.jcr.PathNotFoundException: /my:root/perico
		Node contentNode = fileNode.addNode("jcr:content", "nt:resource");
		
		log.debug("*** ADD DOCUMENT NODE PROPERTIES ***");
		log.debug("*** PROPERTIES #1 ***");
		contentNode.setProperty("jcr:data", new ByteArrayInputStream("Texto de pruebas".getBytes()));
		log.debug("*** PROPERTIES #2 ***");
		contentNode.setProperty("jcr:mimeType", "text/plain");
		log.debug("*** PROPERTIES #3 ***");
		contentNode.setProperty("jcr:lastModified", Calendar.getInstance());
		log.debug("*** SERIALIZE THE ADDED NODE ***");
		myRoot.save();
		
		for (int i=0; i<100; i++) {
			Node n1 = myRoot.addNode("pepe "+i, "nt:hierarchyNode");
		}
		myRoot.save();
/*		
		addDocument(session, okmRoot, "documentos/Orden del Temple.txt");
		addDocument(session, okmRoot, "documentos/Orden del Temple.pdf");
		addDocument(session, okmRoot, "documentos/Orden del Temple.doc");
		addDocument(session, okmRoot, "documentos/Orden del Temple.odt");
		search(session, "temple");
*/
		log.debug("*** SAY BYE ***");
		userSession.logout();
		getSystemSession().logout();
	}

	/**
	 * 
	 */
	private static void removeRepository() {
		try {
			FileUtils.deleteDirectory(new File(repHomeDir));
		} catch (IOException e) {
			System.err.println("No previous repo");
		}
	}

	/**
	 * @return
	 * @throws NamingException
	 * @throws RepositoryException
	 * @throws LoginException
	 * @throws NoSuchWorkspaceException
	 */
	public static Session login(String user, String pass) throws NamingException,
		RepositoryException, LoginException, NoSuchWorkspaceException {
		Repository repository = getRepository();
		Session session = repository.login(new SimpleCredentials(user, pass.toCharArray()), null);
		log.debug("Session: "+session);
		return session;
	}

	/**
	 * @return
	 * @throws RepositoryException
	 */
	public static Repository getRepository() throws RepositoryException {
		if (repository == null) {
			// Repository config
			String repositoryConfig = "repository2.xml";
			String repositoryHome = "repotest2";
			
			RepositoryConfig config = RepositoryConfig.create(repositoryConfig, repositoryHome);
			repository = RepositoryImpl.create(config);
			log.debug("*** System repository created "+repository);
		}
		
		return repository;
	}
	
	/**
	 * @return
	 * @throws LoginException
	 * @throws NoSuchWorkspaceException
	 * @throws RepositoryException
	 */
	public static Session getSystemSession() throws LoginException, NoSuchWorkspaceException, RepositoryException {
		if (systemSession == null) {
			// System User Session
			systemSession = repository.login(new SimpleCredentials("system", "".toCharArray()), null);
			log.debug("*** System user created "+systemSession.getUserID());				
		}
		
		return systemSession;
	}
	
	/**
	 * @param session
	 * @return
	 * @throws NamespaceException
	 * @throws UnsupportedRepositoryOperationException
	 * @throws AccessDeniedException
	 * @throws RepositoryException
	 * @throws ItemExistsException
	 * @throws PathNotFoundException
	 * @throws NoSuchNodeTypeException
	 * @throws LockException
	 * @throws VersionException
	 * @throws ConstraintViolationException
	 * @throws InvalidItemStateException
	 */
	public static Node createRepository()
			throws NamespaceException, UnsupportedRepositoryOperationException,
			AccessDeniedException, RepositoryException, ItemExistsException,
			PathNotFoundException, NoSuchNodeTypeException, LockException,
			VersionException, ConstraintViolationException,
			InvalidItemStateException {
		// Initialize repository
		Repository repository = getRepository();
		Session systemSession = getSystemSession();
		
		// Namespace registration
		Workspace ws = systemSession.getWorkspace();
		ws.getNamespaceRegistry().registerNamespace("my", "http://www.guia-ubuntu.org/1.0";);

		// Node creation
		Node root = systemSession.getRootNode();
		Node okmRoot = root.addNode("my:root", "nt:folder");
		okmRoot.addMixin("mix:referenceable");
		systemSession.save();
		log.info("****** Repository created *******");
		return okmRoot;
	}

	/**
	 * @param session
	 * @param okmRoot
	 * @param fileName
	 * @throws ItemExistsException
	 * @throws PathNotFoundException
	 * @throws NoSuchNodeTypeException
	 * @throws LockException
	 * @throws VersionException
	 * @throws ConstraintViolationException
	 * @throws RepositoryException
	 * @throws ValueFormatException
	 * @throws FileNotFoundException
	 * @throws AccessDeniedException
	 * @throws InvalidItemStateException
	 */
	public static void addDocument(Session session, Node okmRoot,
			String fileName) throws ItemExistsException, PathNotFoundException,
			NoSuchNodeTypeException, LockException, VersionException,
			ConstraintViolationException, RepositoryException,
			ValueFormatException, FileNotFoundException, AccessDeniedException,
			InvalidItemStateException {
		// Add document
		Node fileNode = okmRoot.addNode(new File(fileName).getName(), "nt:file");
		fileNode.addMixin("mix:referenceable");
		fileNode.addMixin("mix:lockable");
		fileNode.addMixin("mix:versionable");
		Node resNode = fileNode.addNode("jcr:content", "nt:resource");
		resNode.setProperty("jcr:mimeType", getMime(fileName));
		resNode.setProperty("jcr:data", new FileInputStream(fileName));
		resNode.setProperty("jcr:lastModified", Calendar.getInstance());
		session.save();
		log.info("File '"+fileName+"' added.");
	}

	/**
	 * @param fileName
	 * @return
	 */
	public static String getMime(String fileName) {
		if (fileName.endsWith(".doc")) {
			return "application/msword";
		} else if (fileName.endsWith(".odt")) {
			return "application/vnd.oasis.opendocument.text";
		} else if (fileName.endsWith(".pdf")) {
			return "application/pdf";
		} else if (fileName.endsWith(".txt")) {
			return "text/plain";
		}

		return "application/octect-stream";
	}

	/**
	 * @param session
	 * @param words
	 * @throws RepositoryException
	 * @throws InvalidQueryException
	 * @throws UnsupportedRepositoryOperationException
	 * @throws ItemNotFoundException
	 * @throws AccessDeniedException
	 */
	public static void search(Session session, String words)
			throws RepositoryException, InvalidQueryException,
			UnsupportedRepositoryOperationException, ItemNotFoundException,
			AccessDeniedException {
		// Search
		String statement = "/jcr:root/my:root//element(*,nt:resource)[jcr:contains(.,'" + words + "')]";
		Workspace workspace = session.getWorkspace();
		QueryManager queryManager = workspace.getQueryManager();
		Query query = queryManager.createQuery(statement, javax.jcr.query.Query.XPATH);
		QueryResult result = query.execute();

		log.info("Search results:");
		for (NodeIterator it = result.getNodes(); it.hasNext();) {
			Node sNode = (Node) it.next();
			log.info(" * "+sNode.getParent().getName());
		}
	}
}

Reply via email to