All Downloads are FREE. Search and download functionalities are using the official Maven repository.

hudson.security.SidACL Maven / Gradle / Ivy

The newest version!
/**
 * *****************************************************************************
 *
 * Copyright (c) 2004-2009 Oracle Corporation.
 *
 * All rights reserved. This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *
 * Kohsuke Kawaguchi
 *
 *
 ******************************************************************************
 */
package hudson.security;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.acls.domain.GrantedAuthoritySid;
import org.springframework.security.acls.domain.PrincipalSid;
import org.springframework.security.acls.model.Sid;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;

/**
 * {@link ACL} that checks permissions based on {@link GrantedAuthority} of the
 * {@link Authentication}.
 *
 * @author Kohsuke Kawaguchi
 */
public abstract class SidACL extends ACL {

    private static final Logger LOGGER = LoggerFactory.getLogger(SidACL.class);

    @Override
    public boolean hasPermission(Authentication a, Permission permission) {
        if (a == SYSTEM) {
            LOGGER.debug("hasPermission({},{})=>SYSTEM user has full access", a, permission);
            return true;
        }
        Boolean b = _hasPermission(a, permission);

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("hasPermission(" + a + "," + permission + ")=>" + (b == null ? "null, thus false" : b));
        }
        
        if (b == null) {
            b = false;    // default to rejection
        }
        return b;
    }

    /**
     * Implementation that backs up
     * {@link #hasPermission(Authentication, Permission)}.
     *
     * @return true or false if {@link #hasPermission(Sid, Permission)} returns
     * it. Otherwise null, indicating that this ACL doesn't have any entry for
     * it.
     */
    protected Boolean _hasPermission(Authentication a, Permission permission) {
        // ACL entries for this principal takes precedence
        LOGGER.debug("Checking if principal {} has {}", a.getName(), permission);
        Boolean b = hasPermission(new PrincipalSid(a), permission);
        if (b != null) {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("hasPermission(PrincipalSID:" + a.getPrincipal() + "," + permission + ")=>" + b);
            }
            return b;
        }

        // after that, we check if the groups this principal belongs to
        // has any ACL entries.
        // here we are using GrantedAuthority as a group
        for (GrantedAuthority ga : a.getAuthorities()) {
            LOGGER.debug("Checking if principal's role {} has {}", ga.getAuthority(), permission);
            b = hasPermission(new GrantedAuthoritySid(ga), permission);
            if (b != null) {
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("hasPermission(GroupSID:" + ga.getAuthority() + "," + permission + ")=>" + b);
                }
                return b;
            }
        }

        // permissions granted to 'everyone' and 'anonymous' users are granted to everyone
        for (Sid sid : AUTOMATIC_SIDS) {
            b = hasPermission(sid, permission);
            if (b != null) {
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("hasPermission(" + sid + "," + permission + ")=>" + b);
                }
                return b;
            }
        }

        return null;
    }

    /**
     * Checks if the given {@link Sid} has the given {@link Permission}.
     *
     * 

{@link #hasPermission(Authentication, Permission)} is implemented by * checking authentication's {@link GrantedAuthority} by using this method. * *

It is the implementor's responsibility to recognize * {@link Permission#impliedBy} and take that into account. * * @return true if the access should be granted, false if it should be * denied. The null value indicates that the ACL does no rule for this * Sid/Permission combination. The caller can decide what to do &mash; such * as consulting the higher level ACL, or denying the access (if the model * is no-access-by-default.) */ protected abstract Boolean hasPermission(Sid p, Permission permission); protected String toString(Sid p) { if (p instanceof GrantedAuthoritySid) { return ((GrantedAuthoritySid) p).getGrantedAuthority(); } if (p instanceof PrincipalSid) { return ((PrincipalSid) p).getPrincipal(); } if (p == EVERYONE) { return "role_everyone"; } // hmm... return p.toString(); } /** * Creates a new {@link SidACL} that first consults 'this' {@link SidACL} * and then delegate to the given parent {@link SidACL}. By doing this at * the {@link SidACL} level and not at the {@link ACL} level, this allows * the child ACLs to have an explicit deny entry. Note that the combined ACL * calls hasPermission(Sid,Permission) in the child and parent SidACLs * directly, so if these override _hasPermission then this custom behavior * will not be applied. */ public final SidACL newInheritingACL(final SidACL parent) { final SidACL child = this; return new SidACL() { protected Boolean hasPermission(Sid p, Permission permission) { Boolean b = child.hasPermission(p, permission); if (b != null) { return b; } return parent.hasPermission(p, permission); } }; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy