Package org.apache.jackrabbit.core.security

Source Code of org.apache.jackrabbit.core.security.JahiaAccessManager$CompiledAce

/**
* This file is part of Jahia, next-generation open source CMS:
* Jahia's next-generation, open source CMS stems from a widely acknowledged vision
* of enterprise application convergence - web, search, document, social and portal -
* unified by the simplicity of web content management.
*
* For more information, please visit http://www.jahia.com.
*
* Copyright (C) 2002-2011 Jahia Solutions Group SA. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* As a special exception to the terms and conditions of version 2.0 of
* the GPL (or any later version), you may redistribute this Program in connection
* with Free/Libre and Open Source Software ("FLOSS") applications as described
* in Jahia's FLOSS exception. You should have received a copy of the text
* describing the FLOSS exception, and it is also available here:
* http://www.jahia.com/license
*
* Commercial and Supported Versions of the program (dual licensing):
* alternatively, commercial and supported versions of the program may be used
* in accordance with the terms and conditions contained in a separate
* written agreement between you and Jahia Solutions Group SA.
*
* If you are unsure which license is appropriate for your use,
* please contact the sales department at sales@jahia.com.
*/

package org.apache.jackrabbit.core.security;

import org.apache.commons.lang.StringUtils;
import org.apache.jackrabbit.core.HierarchyManager;
import org.apache.jackrabbit.core.RepositoryContext;
import org.apache.jackrabbit.core.config.WorkspaceConfig;
import org.apache.jackrabbit.core.id.ItemId;
import org.apache.jackrabbit.core.security.authorization.*;
import org.apache.jackrabbit.spi.Name;
import org.apache.jackrabbit.spi.Path;
import org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver;
import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
import org.apache.jackrabbit.spi.commons.conversion.PathResolver;
import org.apache.jackrabbit.spi.commons.namespace.NamespaceResolver;
import org.apache.jackrabbit.spi.commons.namespace.SessionNamespaceResolver;
import org.jahia.services.sites.JahiaSitesBaseService;
import org.jahia.services.usermanager.JahiaGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.jahia.api.Constants;
import org.jahia.exceptions.JahiaException;
import org.jahia.jaas.JahiaPrincipal;
import org.jahia.registries.ServicesRegistry;
import org.jahia.services.sites.JahiaSite;
import org.jahia.services.sites.JahiaSitesService;
import org.jahia.services.usermanager.JahiaGroupManagerService;
import org.jahia.services.usermanager.JahiaUser;
import org.jahia.services.usermanager.JahiaUserManagerService;

import javax.jcr.*;
import javax.jcr.security.*;
import javax.jcr.version.Version;
import javax.jcr.version.VersionHistory;
import javax.security.auth.Subject;
import java.security.Principal;
import java.util.*;

/**
* Current ACL policy :
* <p/>
* - If there is a grant ACE defined for the user matching the permission, grant access
* - If there is a deny ACE defined for the user matching the permission, deny access
* - Go to parent node, repeat
* - Then, start again from the leaf
* - If there are at least one grant ACEs defined for groups the user belongs to, grant access
* - Go to the parent node, repeat
* - Deny access
* <p/>
*
* @author toto
*/
public class JahiaAccessManager extends AbstractAccessControlManager implements AccessManager, AccessControlManager {
    private static final Logger logger = LoggerFactory.getLogger(JahiaAccessManager.class);
   
    private static final Map<String, Map<String, String>> PRIVILEGE_NAMES = new HashMap<String, Map<String,String>>(2);
   
    /**
     * Subject whose access rights this AccessManager should reflect
     */
    protected Subject subject;

    /**
     * hierarchy manager used for ACL-based access control model
     */
    protected HierarchyManager hierMgr;
    protected NamePathResolver resolver;
    private JahiaPrivilegeRegistry privilegeRegistry;
    private boolean initialized;
    protected String workspaceName;

    private JahiaUserManagerService userService;
    private JahiaGroupManagerService groupService;
    private JahiaSitesService sitesService;

    protected JahiaPrincipal jahiaPrincipal;

    private Session securitySession;
    private RepositoryContext repositoryContext;
    private WorkspaceConfig workspaceConfig;

    private Map<String, Set<Privilege>> privilegesInRole = new HashMap<String, Set<Privilege>>();
    private Map<String, Boolean> cache = new HashMap<String, Boolean>();
    private Map<String, CompiledAcl> compiledAcls = new HashMap<String, CompiledAcl>();
    private Boolean isAdmin = null;

    private static ThreadLocal<Collection<String>> deniedPathes = new ThreadLocal<Collection<String>>();

    private boolean isAliased = false;
    private Set<String> userMembership;
    private JahiaUser jahiaUser;

    public static String getPrivilegeName(String privilegeName, String workspace) {
        if (workspace ==  null) {
            return privilegeName;
        }
       
        Map<String, String> wsp = PRIVILEGE_NAMES.get(workspace);
        if (wsp == null) {
            wsp = new HashMap<String, String>();
            PRIVILEGE_NAMES.put(workspace, wsp);
        }
        String name = wsp.get(privilegeName);
        if (name == null) {
            name = privilegeName + "_" + workspace;
            wsp.put(privilegeName, name);
        }
       
        return name;
    }
   
    public static void setDeniedPaths(Collection<String> denied) {
        JahiaAccessManager.deniedPathes.set(denied);
    }

    /**
     * Empty constructor
     */
    public JahiaAccessManager() {
        initialized = false;
        jahiaPrincipal = null;
    }

    public void init(AMContext amContext) throws AccessDeniedException, Exception {
        init(amContext, null, null, null, null);
    }

    public void init(AMContext amContext, AccessControlProvider acProvider, WorkspaceAccessManager wspAccessManager) throws AccessDeniedException, Exception {
        init(amContext, null, null, null, null);
    }

    public Session getSecuritySession() throws RepositoryException {
        if (securitySession != null) {
            return securitySession;
        }

        // create subject with SystemPrincipal
        Set<SystemPrincipal> principals = new HashSet<SystemPrincipal>();
        principals.add(new SystemPrincipal());
        Subject systemSubject = new Subject(true, principals, Collections.EMPTY_SET, Collections.EMPTY_SET);

        securitySession = new JahiaSystemSession(repositoryContext, systemSubject,
                workspaceConfig);
        return securitySession;
    }

    public boolean isSystemPrincipal() {
        return jahiaPrincipal != null && jahiaPrincipal.isSystem();
    }

    /**
     * {@inheritDoc}
     */
    public void init(AMContext context, AccessControlProvider acProvider, WorkspaceAccessManager wspAccessManager, RepositoryContext repositoryContext, WorkspaceConfig workspaceConfig) throws AccessDeniedException, Exception {
        if (initialized) {
            throw new IllegalStateException("already initialized");
        }
//        super.init(context, acProvider, wspAccessManager);
        subject = context.getSubject();
        resolver = context.getNamePathResolver();
        hierMgr = context.getHierarchyManager();
        workspaceName = context.getWorkspaceName();
        this.repositoryContext = repositoryContext;
        this.workspaceConfig = workspaceConfig;
        privilegeRegistry = new JahiaPrivilegeRegistry(context.getSession().getWorkspace().getNamespaceRegistry());

        Set<JahiaPrincipal> principals = subject.getPrincipals(JahiaPrincipal.class);
        if (!principals.isEmpty()) {
            jahiaPrincipal = (JahiaPrincipal) principals.iterator().next();
        }

        userService = ServicesRegistry.getInstance().getJahiaUserManagerService();
        groupService = ServicesRegistry.getInstance().getJahiaGroupManagerService();
        sitesService = ServicesRegistry.getInstance().getJahiaSitesService();

        if (!jahiaPrincipal.isSystem()) {
            if (!JahiaLoginModule.GUEST.equals(jahiaPrincipal.getName())) {
                jahiaUser = userService.lookupUser(jahiaPrincipal.getName());
                if (jahiaUser != null) {
                    userMembership = new HashSet<String>(groupService.getUserMembership(jahiaUser));
                }
            }
        } else {
            userMembership = new HashSet<String>();
        }

        initialized = true;
    }

    public void close() throws Exception {
        if (securitySession != null) {
            securitySession.logout();
        }
    }

    /**
     * @deprecated
     */
    public void checkPermission(ItemId id, int actions) throws AccessDeniedException, ItemNotFoundException, RepositoryException {
        if (!isGranted(id, actions)) {
            throw new AccessDeniedException("Not sufficient privileges for permissions : " + actions + " on " + id);
        }
    }

    public void checkPermission(Path path, int permissions) throws AccessDeniedException, RepositoryException {
        if (!isGranted(path, permissions)) {
            throw new AccessDeniedException("Not sufficient privileges for permissions : " + permissions + " on " + path + " [" + deniedPathes.get() + "]");
        }
    }

    protected void checkPermission(String absPath, int permission)
            throws AccessDeniedException, PathNotFoundException, RepositoryException {
        checkValidNodePath(absPath);
        checkPermission(resolver.getQPath(absPath), permission);
    }


    public boolean hasPrivileges(String absPath, Set<Principal> principals, Privilege[] privileges)
            throws PathNotFoundException, AccessDeniedException, RepositoryException {
        checkInitialized();
        checkValidNodePath(absPath);
        checkPermission(absPath, Permission.READ_AC);

        if (privileges == null || privileges.length == 0) {
            // null or empty privilege array -> return true
            if (logger.isDebugEnabled()) {
                logger.debug("No privileges passed -> allowed.");
            }
            return true;
        } else {
            int privs = PrivilegeRegistry.getBits(privileges);
            Path p = resolver.getQPath(absPath);
            return isGranted(p, privs);
        }
    }

    @Override
    protected void checkInitialized() throws IllegalStateException {
        if (!initialized) {
            throw new IllegalStateException("not initialized");
        }
    }


    @Override
    public Privilege privilegeFromName(String privilegeName) throws AccessControlException, RepositoryException {
        checkInitialized();

        return privilegeRegistry.getPrivilege(privilegeName, workspaceName);
    }

    @Override
    public Privilege[] getSupportedPrivileges(String absPath) throws PathNotFoundException, RepositoryException {
        checkInitialized();
        checkValidNodePath(absPath);

        // return all known privileges everywhere.
        return privilegeRegistry.getRegisteredPrivileges();
    }


    /**
     * @see AbstractAccessControlManager#getPrivilegeRegistry()
     */
    @Override
    protected PrivilegeRegistry getPrivilegeRegistry() throws RepositoryException {
        // Do not use jackrabbit privileges registry
        return null;
    }


    /**
     * @see AbstractAccessControlManager#checkValidNodePath(String)
     */
    @Override
    protected void checkValidNodePath(String absPath) throws PathNotFoundException, RepositoryException {
        Path p = resolver.getQPath(absPath);
        if (!p.isAbsolute()) {
            throw new RepositoryException("Absolute path expected.");
        }
        if (hierMgr.resolveNodePath(p) == null) {
            throw new PathNotFoundException("No such node " + absPath);
        }
    }

    public AccessControlPolicy[] getEffectivePolicies(Set<Principal> principals)
            throws AccessDeniedException, AccessControlException, UnsupportedRepositoryOperationException,
            RepositoryException {
        return new AccessControlPolicy[0];
    }

    public Privilege[] getPrivileges(String absPath, Set<Principal> principals)
            throws PathNotFoundException, AccessDeniedException, RepositoryException {
        return new Privilege[0];
    }

    /*
    * @deprecated
    */
    public boolean isGranted(ItemId id, int actions) throws ItemNotFoundException, RepositoryException {
        Set<String> perm = new HashSet<String>();
        if ((actions & READ) == READ) {
            perm.add(getPrivilegeName(Privilege.JCR_READ, workspaceName));
        }
        if ((actions & WRITE) == WRITE) {
            if (id.denotesNode()) {
                // TODO: check again if correct
                perm.add(getPrivilegeName(Privilege.JCR_ADD_CHILD_NODES, workspaceName));
                perm.add(getPrivilegeName(Privilege.JCR_MODIFY_PROPERTIES, workspaceName));
            } else {
                perm.add(getPrivilegeName(Privilege.JCR_MODIFY_PROPERTIES, workspaceName));
            }
        }
        if ((actions & REMOVE) == REMOVE) {
            perm.add((id.denotesNode()) ? getPrivilegeName(Privilege.JCR_REMOVE_CHILD_NODES, workspaceName) : getPrivilegeName(Privilege.JCR_REMOVE_NODE, workspaceName));
        }
        Path path = hierMgr.getPath(id);
        return isGranted(path, perm);
    }

    public boolean isGranted(Path absPath, int permissions) throws RepositoryException {
        Set<String> privs = new HashSet<String>();

        if (isSystemPrincipal() && deniedPathes.get() == null) {
            return true;
        }

        for (Privilege privilege : privilegeRegistry.getPrivileges(permissions, workspaceName)) {
            privs.add(privilege.getName());
        }

        return isGranted(absPath, privs);
    }

    public boolean isGranted(Path absPath, Set<String> permissions) throws RepositoryException {
        String absPathStr = absPath.toString();
        if (isSystemPrincipal() && deniedPathes.get() == null) {
            return true;
        }

        if (permissions.size() == 1 && absPathStr.equals("{}") && permissions.contains(getPrivilegeName(Privilege.JCR_READ,  workspaceName))) {
            return true;
        }

        boolean res = false;

        String cacheKey = absPathStr + " : " + permissions;
        if (cache.containsKey(cacheKey)) {
            return cache.get(cacheKey);
        }

        try {
            NamespaceResolver nr = new SessionNamespaceResolver(getSecuritySession());

            PathResolver pr = new DefaultNamePathResolver(nr);
            String jcrPath = pr.getJCRPath(absPath);

            if (deniedPathes.get() != null && deniedPathes.get().contains(jcrPath)) {
                cache.put(cacheKey, false);
                return false;
            }

            if (isSystemPrincipal()) {
                cache.put(cacheKey, true);
                return true;
            }

            Item i = null;
            Boolean itemExists = null;

            // Always deny write access on system folders
            if (permissions.contains(getPrivilegeName(Privilege.JCR_WRITE, workspaceName)) ||
                    permissions.contains(getPrivilegeName(Privilege.JCR_MODIFY_PROPERTIES, workspaceName)) ||
                    permissions.contains(getPrivilegeName(Privilege.JCR_REMOVE_NODE, workspaceName))) {
                itemExists = getSecuritySession().itemExists(jcrPath);
                if (itemExists.booleanValue()) {
                    i = getSecuritySession().getItem(jcrPath);
                    if (i.isNode()) {
                        if (((Node) i).isNodeType(Constants.JAHIAMIX_SYSTEMNODE)) {
                            cache.put(cacheKey, false);
                            return false;
                        }
                    }
                }
            }

            if (permissions.size() != 1 || !permissions.contains(getPrivilegeName(Privilege.JCR_ADD_CHILD_NODES, workspaceName))) {
                if (itemExists == null) {
                    itemExists = getSecuritySession().itemExists(jcrPath);
                }
                boolean newItem = !itemExists.booleanValue(); // Jackrabbit checks the ADD_NODE permission on non-existing nodes
                if (newItem) {
                    // If node is new (local to the session), always grant permission
                    cache.put(cacheKey, true);
                    return true;
                }
            }

            // Administrators are always granted
            if (jahiaPrincipal != null) {
                if (isAdmin(jahiaPrincipal.getName(), 0)) {
                    cache.put(cacheKey, true);
                    return true;
                }
            }

            int depth = 1;
            if (itemExists == null) {
                itemExists = getSecuritySession().itemExists(jcrPath);
            }
            while (!itemExists.booleanValue()) {
                jcrPath = pr.getJCRPath(absPath.getAncestor(depth++));
                itemExists = getSecuritySession().itemExists(jcrPath);
            }

            if (i == null) {
                i = getSecuritySession().getItem(jcrPath);
            }

            if (i instanceof Version) {
                i = ((Version) i).getContainingHistory();
            }
            if (i instanceof VersionHistory) {
                PropertyIterator pi = ((VersionHistory) i).getReferences();
                if (pi.hasNext()) {
                    Property p = pi.nextProperty();
                    i = p.getParent();
                    jcrPath = i.getPath();
                }
            }

            Node n;

            if (i.isNode()) {
                n = (Node) i;
            } else {
                n = i.getParent();
                jcrPath = StringUtils.substringBeforeLast(jcrPath, "/");
            }

            // Translation permissions
            String name = StringUtils.substringAfterLast(jcrPath, "/");
            if (name.startsWith("j:translation_")) {
                String language = StringUtils.substringAfter(name, "j:translation_");
                if (permissions.contains(getPrivilegeName(Privilege.JCR_MODIFY_PROPERTIES, workspaceName))) {
                    permissions.remove(getPrivilegeName(Privilege.JCR_MODIFY_PROPERTIES, workspaceName));
                    permissions.add(getPrivilegeName(Privilege.JCR_MODIFY_PROPERTIES, workspaceName) + "_" + language);
                }
            }

            String ntName = n.getPrimaryNodeType().getName();
            if (ntName.equals("jnt:acl") || ntName.equals("jnt:ace")) {
                if (permissions.contains(getPrivilegeName(Privilege.JCR_READ, workspaceName))) {
                    permissions.add(getPrivilegeName(Privilege.JCR_READ_ACCESS_CONTROL, workspaceName));
                }
                if (permissions.contains(getPrivilegeName(Privilege.JCR_MODIFY_PROPERTIES, workspaceName))) {
                    permissions.add(getPrivilegeName(Privilege.JCR_MODIFY_ACCESS_CONTROL, workspaceName));
                }
            }

            // Todo : optimize site resolution
//            int siteId = 0;
            String site = null;
            if (jcrPath.startsWith(JahiaSitesBaseService.SITES_JCR_PATH)) {
                if (jcrPath.length() > JahiaSitesBaseService.SITES_JCR_PATH.length() + 1) {
                    site = StringUtils.substringBefore(jcrPath.substring(JahiaSitesBaseService.SITES_JCR_PATH.length() + 1), "/");
                }
            } else {
                Node s = n;
                try {
                    while (!s.isNodeType("jnt:virtualsite")) {
                        s = s.getParent();
                    }
                    site = s.getName();
                    //                siteId = (int) s.getProperty("j:siteId").getLong();
                } catch (ItemNotFoundException e) {
                } catch (PathNotFoundException e) {
                }
            }

//            if (jahiaPrincipal != null) {
//                if (isAdmin(jahiaPrincipal.getName(), siteId)) {
//                    cache.put(absPathStr + " : " + permissions, true);
//                    return true;
//                }
//            }


            res = recurseOnACPs(jcrPath, getSecuritySession(), permissions, site);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        cache.put(absPathStr + " : " + permissions, res);
        return res;
    }

    public boolean isGranted(Path parentPath, Name childName, int permissions) throws RepositoryException {
//        Path p = PathFactoryImpl.getInstance().create(parentPath, childName, true);
        // check on parent
        return isGranted(parentPath, permissions);
    }

    public boolean canRead(Path path, ItemId itemId) throws RepositoryException {
        if (path != null) {
            return isGranted(path, Permission.READ);
        } else if (itemId != null) {
            return isGranted(itemId, JahiaAccessManager.READ);
        }
        return false;
    }

    /**
     * @see AccessManager#canAccess(String)
     */
    public boolean canAccess(String workspaceName) throws RepositoryException {
        return true;
    }


    private boolean recurseOnACPs(String jcrPath, Session s, Set<String> permissions, String site) throws RepositoryException {
        Set<String> foundRoles = new HashSet<String>();
        permissions = new HashSet<String>(permissions);
        while (jcrPath.length() > 0) {
            Map<String, Boolean> roles;

            CompiledAcl acl = compiledAcls.get(jcrPath);

            if (acl == null) {
                acl = new CompiledAcl();
                compiledAcls.put(jcrPath, acl);

                Item i = s.getItem(jcrPath);
                if (i.isNode()) {
                    Node node = (Node) i;
                    if (node.hasNode("j:acl")) {
                        // Jahia specific ACL
                        Node aclNode = node.getNode("j:acl");
                        NodeIterator aces = aclNode.getNodes();

                        while (aces.hasNext()) {
                            Node aceNode = aces.nextNode();
                            String principal = aceNode.getProperty("j:principal").getString();

                            if (matchUser(principal, site)) {
                                CompiledAce ace = new CompiledAce();
                                acl.aces.add(ace);
                                ace.principal = principal;
                                ace.granted = !aceNode.getProperty("j:aceType").getString().equals("DENY");
                                Value[] roleValues = aceNode.getProperty("j:roles").getValues();
                                for (Value role1 : roleValues) {
                                    String role = role1.getString();
                                    ace.roles.add(role);
                                }
                            }
                        }
                        acl.broken = aclNode.hasProperty("j:inherit") && !aclNode.getProperty("j:inherit").getBoolean();
                    }
                }
            }

            for (CompiledAce perm : acl.aces) {
                for (String role : perm.roles) {
                    String key = perm.principal + ":" + role;
                    if (foundRoles.contains(key)) {
                        continue;
                    }
                    foundRoles.add(key);

                    if (!perm.granted) {
                        continue;
                    }
                    if (matchPermission(permissions, role, s)) {
                        return true;
                    }
                }
            }
            if (acl.broken) {
                return false;
            }

            if ("/".equals(jcrPath)) {
                return false;
            } else if (jcrPath.lastIndexOf('/') > 0) {
                jcrPath = jcrPath.substring(0, jcrPath.lastIndexOf('/'));
            } else {
                jcrPath = "/";
            }
        }
        return false;
    }


    public Set<Privilege> getPermissionsInRole(String role, Session s) throws RepositoryException {
        if (privilegesInRole.containsKey(role)) {
            return privilegesInRole.get(role);
        } else {
            Set<Privilege> list = new HashSet<Privilege>();
            try {
                Node roleNode = securitySession.getNode("/roles/" + role);
                if (roleNode.hasProperty("j:permissions")) {
                    Value[] perms = roleNode.getProperty("j:permissions").getValues();
                    for (Value value : perms) {
                        Node p = s.getNodeByIdentifier(value.getString());
                        Privilege privilege = privilegeRegistry.getPrivilege(p);
                        list.add(privilege);
                    }
                }
                privilegesInRole.put(roleNode.getName(), list);
            } catch (PathNotFoundException e) {
            }
            return list;
        }
    }

    public boolean matchPermission(Set<String> permissions, String role, Session s) throws RepositoryException {
        Set<Privilege> permsInRole = getPermissionsInRole(role, s);
        logger.debug("Checking role " +role);

        for (Privilege privilege : permsInRole) {
            String privilegeName = privilege.getName();
            if (checkPrivilege(permissions, privilegeName)) {
                return true;
            }
            if (isAliased && privilegeName.contains("_" + Constants.LIVE_WORKSPACE)) {
                if (checkPrivilege(permissions, privilegeName.replaceAll("_" + Constants.LIVE_WORKSPACE, "_" + workspaceName))) {
                    return true;
                }
            }

            for (Privilege sub : privilege.getAggregatePrivileges()) {
                if (checkPrivilege(permissions, sub.getName())) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean checkPrivilege(Set<String> permissions, String privilegeName) {
        if (permissions.contains(privilegeName)) {
            logger.debug("Found privilege " +privilegeName);
            permissions.remove(privilegeName);
            if (permissions.isEmpty()) {
                return true;
            }
        }
        return false;
    }

    private boolean matchUser(String principal, String site) {
        final String principalName = principal.substring(2);
        if (principal.charAt(0) == 'u') {
            if ((jahiaPrincipal.isGuest() && principalName.equals("guest")) || (principalName.equals(jahiaPrincipal.getName()))) {
                return true;
            }
        } else if (principal.charAt(0) == 'g') {
            if (principalName.equals("guest") || (!jahiaPrincipal.isGuest() &&
                    (isUserMemberOf(principalName, site) || isUserMemberOf(principalName, null)))) {
                return true;
            }
        }
        return false;
    }


    public boolean hasPrivileges(String absPath, Privilege[] privileges) throws PathNotFoundException, RepositoryException {
        checkInitialized();
        checkValidNodePath(absPath);
        if (privileges == null || privileges.length == 0) {
            // null or empty privilege array -> return true
            if (logger.isDebugEnabled()) {
                logger.debug("No privileges passed -> allowed.");
            }
            return true;
        } else {
            Set<String> privs = new HashSet<String>();

            for (Privilege privilege : privileges) {
                privs.add(privilege.getName());
            }

            Path p = resolver.getQPath(absPath);

            return isGranted(p, privs);
        }
    }

    public Privilege[] getPrivileges(String absPath) throws PathNotFoundException, RepositoryException {
        Set<Privilege> results = new HashSet<Privilege>();
        if (isAdmin(jahiaPrincipal.getName(), 0)) {
            return getSupportedPrivileges(absPath);
        }
        Session s = getSecuritySession();
        Set<String> grantedRoles = getRoles(absPath);

        for (String role : grantedRoles) {
            Node node = securitySession.getNode("/roles/" + role);
            if (node.hasProperty("j:permissions")) {
                Value[] perms = node.getProperty("j:permissions").getValues();

                for (Value value : perms) {
                    Node p = s.getNodeByIdentifier(value.getString());
                    try {
                        Privilege privilege = privilegeRegistry.getPrivilege(p);
                        results.add(privilege);
                    } catch (AccessControlException e) {
                        logger.debug("Permission not available : " + p, e);
                    }
                }
            }
        }

        return results.toArray(new Privilege[results.size()]);
    }

    public AccessControlPolicy[] getEffectivePolicies(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
        return new AccessControlPolicy[0];
    }

    public void setAliased(boolean aliased) {
        isAliased = aliased;
    }

    public boolean isAdmin(String username, int siteId) {
        if (isAdmin == null) {
            // optimize away guest, we assume he can never be site administrator.
            if (JahiaLoginModule.GUEST.equals(username)) {
                return false;
            }
            JahiaUser user = userService.lookupUser(username);
            if (user != null) {
                return isAdmin = user.isAdminMember(siteId);
            }
            return isAdmin = false;
        }
        return isAdmin;
    }


    private boolean isUserMemberOf(String groupname, String site) {
        JahiaSite s = null;
        if (JahiaGroupManagerService.GUEST_GROUPNAME.equals(groupname)) {
            return true;
        }
        if (JahiaGroupManagerService.USERS_GROUPNAME.equals(groupname) && site == null && !JahiaUserManagerService.GUEST_USERNAME.equals(jahiaPrincipal.getName())) {
            return true;
        }
        int siteId = 0;
        if (site != null) {
            try {
                s = sitesService.getSiteByKey(site);
                if (s != null) {
                    siteId = s.getID();
                }
            } catch (JahiaException e) {
                logger.error("Error while retrieving site key" + site, e);
            }
        }

        JahiaGroup group = groupService.lookupGroup(siteId, groupname);
        if (group == null) {
            group = groupService.lookupGroup(0, groupname);
        }
        return (jahiaUser != null) && (group != null) && group.isMember(jahiaUser);
    }

    public Set<String> getRoles(String absPath) throws PathNotFoundException, RepositoryException {
        Set<String> grantedRoles = new HashSet<String>();
        Set<String> foundRoles = new HashSet<String>();
        Session s = getSecuritySession();
        Node n = s.getNode(absPath);

        String site = null;
        Node c = n;
        try {
            while (!c.isNodeType("jnt:virtualsite")) {
                c = c.getParent();
            }
            site = c.getName();
        } catch (ItemNotFoundException e) {
        } catch (PathNotFoundException e) {
        }

        try {
            while (true) {
                if (n.hasNode("j:acl")) {
                    Node acl = n.getNode("j:acl");
                    NodeIterator aces = acl.getNodes();
                    while (aces.hasNext()) {
                        Node ace = aces.nextNode();
                        if (ace.isNodeType("jnt:ace")) {
                            String principal = ace.getProperty("j:principal").getString();

                            if (matchUser(principal, site)) {
                                boolean granted = ace.getProperty("j:aceType").getString().equals("GRANT");

                                Value[] roles = ace.getProperty(Constants.J_ROLES).getValues();
                                for (Value r : roles) {
                                    String role = r.getString();
                                    if (!foundRoles.contains(principal + ":" + role)) {
                                        if (granted) {
                                            grantedRoles.add(role);
                                        }
                                        foundRoles.add(principal + ":" + role);
                                    }
                                }
                            }
                        }
                    }
                    if (acl.hasProperty("j:inherit") && !acl.getProperty("j:inherit").getBoolean()) {
                        return grantedRoles;
                    }
                }
                n = n.getParent();
            }
        } catch (ItemNotFoundException e) {
            logger.debug(e.getMessage(), e);
        }
        return grantedRoles;
    }


    class CompiledAcl {
        boolean broken = false;
        Set<CompiledAce> aces = new HashSet<CompiledAce>();
    }

    class CompiledAce {
        String principal;
        Set<String> roles = new HashSet<String>();
        boolean granted;
    }
}
TOP

Related Classes of org.apache.jackrabbit.core.security.JahiaAccessManager$CompiledAce

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.