diff --git a/core/src/main/java/hudson/security/AuthorizationMatrixProperty.java b/core/src/main/java/hudson/security/AuthorizationMatrixProperty.java index e8068f8bf80933a11297fc19d3eef962417b06ec..154d7c741d8a92bf2f3c8b4e506c7dfabf7393c3 100644 --- a/core/src/main/java/hudson/security/AuthorizationMatrixProperty.java +++ b/core/src/main/java/hudson/security/AuthorizationMatrixProperty.java @@ -36,7 +36,7 @@ public class AuthorizationMatrixProperty extends JobProperty> { public static final JobPropertyDescriptor DESCRIPTOR = new DescriptorImpl(); - private transient ACL acl = new AclImpl(); + private transient SidACL acl = new AclImpl(); private boolean useProjectSecurity; @@ -178,7 +178,7 @@ public class AuthorizationMatrixProperty extends JobProperty> { return this; } - public ACL getACL() { + public SidACL getACL() { return acl; } diff --git a/core/src/main/java/hudson/security/GlobalMatrixAuthorizationStrategy.java b/core/src/main/java/hudson/security/GlobalMatrixAuthorizationStrategy.java index 6ceaa97579ab526f4bbe189ba6ec42a353f4f0eb..a31df543e70ff66c5843e6d5da0f099e074ec619 100644 --- a/core/src/main/java/hudson/security/GlobalMatrixAuthorizationStrategy.java +++ b/core/src/main/java/hudson/security/GlobalMatrixAuthorizationStrategy.java @@ -29,7 +29,7 @@ import java.util.Set; */ // TODO: think about the concurrency commitment of this class public class GlobalMatrixAuthorizationStrategy extends AuthorizationStrategy { - private transient ACL acl = new AclImpl(); + private transient SidACL acl = new AclImpl(); /** * List up all permissions that are granted. @@ -64,7 +64,7 @@ public class GlobalMatrixAuthorizationStrategy extends AuthorizationStrategy { } @Override - public ACL getRootACL() { + public SidACL getRootACL() { return acl; } diff --git a/core/src/main/java/hudson/security/ProjectMatrixAuthorizationStrategy.java b/core/src/main/java/hudson/security/ProjectMatrixAuthorizationStrategy.java index ca7da447f892e4080d6381f49843857357d166ff..6ff8c4f4208f8b5efc1bd5d7b52cfd10e599f264 100644 --- a/core/src/main/java/hudson/security/ProjectMatrixAuthorizationStrategy.java +++ b/core/src/main/java/hudson/security/ProjectMatrixAuthorizationStrategy.java @@ -22,7 +22,7 @@ public class ProjectMatrixAuthorizationStrategy extends GlobalMatrixAuthorizatio public ACL getACL(AbstractProject project) { AuthorizationMatrixProperty amp = project.getProperty(AuthorizationMatrixProperty.class); if (amp != null && amp.isUseProjectSecurity()) { - return amp.getACL(); + return amp.getACL().newInheritingACL(getRootACL()); } else { return getRootACL(); } diff --git a/core/src/main/java/hudson/security/SidACL.java b/core/src/main/java/hudson/security/SidACL.java index b87e0673913f568af0decd830497e370522d16d0..7d027836ce183ad1a7596e12f9b7a9cdea928edf 100644 --- a/core/src/main/java/hudson/security/SidACL.java +++ b/core/src/main/java/hudson/security/SidACL.java @@ -68,4 +68,20 @@ public abstract class SidACL extends ACL { * or denying the access (if the model is no-access-by-default.) */ protected abstract Boolean hasPermission(Sid p, Permission permission); + + /** + * 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. + */ + 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); + } + }; + } }