Add AuthorizationManager factory methods

Factory methods to create AuthorizationManager with a configurable default AuthorizationDecision.

Closes gh-13085
This commit is contained in:
Yuriy Savchenko 2023-12-07 22:48:22 +03:00 committed by Josh Cummings
parent ee8bc78cbc
commit e49ae096e6
2 changed files with 172 additions and 4 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2022 the original author or authors. * Copyright 2002-2023 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -37,6 +37,23 @@ public final class AuthorizationManagers {
*/ */
@SafeVarargs @SafeVarargs
public static <T> AuthorizationManager<T> anyOf(AuthorizationManager<T>... managers) { public static <T> AuthorizationManager<T> anyOf(AuthorizationManager<T>... managers) {
return anyOf(new AuthorizationDecision(false), managers);
}
/**
* Creates an {@link AuthorizationManager} that grants access if at least one
* {@link AuthorizationManager} granted, if <code>managers</code> are empty or
* abstained, a default {@link AuthorizationDecision} is returned.
* @param <T> the type of object that is being authorized
* @param allAbstainDefaultDecision the default decision if all
* {@link AuthorizationManager}s abstained
* @param managers the {@link AuthorizationManager}s to use
* @return the {@link AuthorizationManager} to use
* @since 6.3
*/
@SafeVarargs
public static <T> AuthorizationManager<T> anyOf(AuthorizationDecision allAbstainDefaultDecision,
AuthorizationManager<T>... managers) {
return (authentication, object) -> { return (authentication, object) -> {
List<AuthorizationDecision> decisions = new ArrayList<>(); List<AuthorizationDecision> decisions = new ArrayList<>();
for (AuthorizationManager<T> manager : managers) { for (AuthorizationManager<T> manager : managers) {
@ -50,7 +67,7 @@ public final class AuthorizationManagers {
decisions.add(decision); decisions.add(decision);
} }
if (decisions.isEmpty()) { if (decisions.isEmpty()) {
return new AuthorizationDecision(false); return allAbstainDefaultDecision;
} }
return new CompositeAuthorizationDecision(false, decisions); return new CompositeAuthorizationDecision(false, decisions);
}; };
@ -66,6 +83,23 @@ public final class AuthorizationManagers {
*/ */
@SafeVarargs @SafeVarargs
public static <T> AuthorizationManager<T> allOf(AuthorizationManager<T>... managers) { public static <T> AuthorizationManager<T> allOf(AuthorizationManager<T>... managers) {
return allOf(new AuthorizationDecision(true), managers);
}
/**
* Creates an {@link AuthorizationManager} that grants access if all
* {@link AuthorizationManager}s granted, if <code>managers</code> are empty or
* abstained, a default {@link AuthorizationDecision} is returned.
* @param <T> the type of object that is being authorized
* @param allAbstainDefaultDecision the default decision if all
* {@link AuthorizationManager}s abstained
* @param managers the {@link AuthorizationManager}s to use
* @return the {@link AuthorizationManager} to use
* @since 6.3
*/
@SafeVarargs
public static <T> AuthorizationManager<T> allOf(AuthorizationDecision allAbstainDefaultDecision,
AuthorizationManager<T>... managers) {
return (authentication, object) -> { return (authentication, object) -> {
List<AuthorizationDecision> decisions = new ArrayList<>(); List<AuthorizationDecision> decisions = new ArrayList<>();
for (AuthorizationManager<T> manager : managers) { for (AuthorizationManager<T> manager : managers) {
@ -79,7 +113,7 @@ public final class AuthorizationManagers {
decisions.add(decision); decisions.add(decision);
} }
if (decisions.isEmpty()) { if (decisions.isEmpty()) {
return new AuthorizationDecision(true); return allAbstainDefaultDecision;
} }
return new CompositeAuthorizationDecision(true, decisions); return new CompositeAuthorizationDecision(true, decisions);
}; };

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2022 the original author or authors. * Copyright 2002-2023 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -36,6 +36,16 @@ class AuthorizationManagersTests {
assertThat(decision.isGranted()).isTrue(); assertThat(decision.isGranted()).isTrue();
} }
@Test
void checkAnyOfWithAllAbstainDefaultDecisionWhenOneGrantedThenGrantedDecision() {
AuthorizationDecision allAbstainDefaultDecision = new AuthorizationDecision(false);
AuthorizationManager<?> composed = AuthorizationManagers.anyOf(allAbstainDefaultDecision,
(a, o) -> new AuthorizationDecision(false), (a, o) -> new AuthorizationDecision(true));
AuthorizationDecision decision = composed.check(null, null);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isTrue();
}
// gh-13069 // gh-13069
@Test @Test
void checkAnyOfWhenAllNonAbstainingDeniesThenDeniedDecision() { void checkAnyOfWhenAllNonAbstainingDeniesThenDeniedDecision() {
@ -54,6 +64,58 @@ class AuthorizationManagersTests {
assertThat(decision.isGranted()).isFalse(); assertThat(decision.isGranted()).isFalse();
} }
@Test
void checkAnyOfWithAllAbstainDefaultDecisionIsDeniedWhenEmptyThenDeniedDecision() {
AuthorizationDecision allAbstainDefaultDecision = new AuthorizationDecision(false);
AuthorizationManager<?> composed = AuthorizationManagers.anyOf(allAbstainDefaultDecision);
AuthorizationDecision decision = composed.check(null, null);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isFalse();
}
@Test
void checkAnyOfWithAllAbstainDefaultDecisionIsGrantedWhenEmptyThenGrantedDecision() {
AuthorizationDecision allAbstainDefaultDecision = new AuthorizationDecision(true);
AuthorizationManager<?> composed = AuthorizationManagers.anyOf(allAbstainDefaultDecision);
AuthorizationDecision decision = composed.check(null, null);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isTrue();
}
@Test
void checkAnyOfWithAllAbstainDefaultDecisionIsAbstainWhenEmptyThenAbstainDecision() {
AuthorizationDecision allAbstainDefaultDecision = null;
AuthorizationManager<?> composed = AuthorizationManagers.anyOf(allAbstainDefaultDecision);
AuthorizationDecision decision = composed.check(null, null);
assertThat(decision).isNull();
}
@Test
void checkAnyOfWhenAllAbstainDefaultDecisionIsGrantedAndAllManagersAbstainThenGrantedDecision() {
AuthorizationDecision allAbstainDefaultDecision = new AuthorizationDecision(true);
AuthorizationManager<?> composed = AuthorizationManagers.anyOf(allAbstainDefaultDecision, (a, o) -> null);
AuthorizationDecision decision = composed.check(null, null);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isTrue();
}
@Test
void checkAnyOfWhenAllAbstainDefaultDecisionIsDeniedAndAllManagersAbstainThenDeniedDecision() {
AuthorizationDecision allAbstainDefaultDecision = new AuthorizationDecision(false);
AuthorizationManager<?> composed = AuthorizationManagers.anyOf(allAbstainDefaultDecision, (a, o) -> null);
AuthorizationDecision decision = composed.check(null, null);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isFalse();
}
@Test
void checkAnyOfWhenAllAbstainDefaultDecisionIsAbstainAndAllManagersAbstainThenAbstainDecision() {
AuthorizationDecision allAbstainDefaultDecision = null;
AuthorizationManager<?> composed = AuthorizationManagers.anyOf(allAbstainDefaultDecision, (a, o) -> null);
AuthorizationDecision decision = composed.check(null, null);
assertThat(decision).isNull();
}
@Test @Test
void checkAllOfWhenAllGrantedThenGrantedDecision() { void checkAllOfWhenAllGrantedThenGrantedDecision() {
AuthorizationManager<?> composed = AuthorizationManagers.allOf((a, o) -> new AuthorizationDecision(true), AuthorizationManager<?> composed = AuthorizationManagers.allOf((a, o) -> new AuthorizationDecision(true),
@ -63,6 +125,16 @@ class AuthorizationManagersTests {
assertThat(decision.isGranted()).isTrue(); assertThat(decision.isGranted()).isTrue();
} }
@Test
void checkAllOfWithAllAbstainDefaultDecisionWhenAllGrantedThenGrantedDecision() {
AuthorizationDecision allAbstainDefaultDecision = new AuthorizationDecision(false);
AuthorizationManager<?> composed = AuthorizationManagers.allOf(allAbstainDefaultDecision,
(a, o) -> new AuthorizationDecision(true), (a, o) -> new AuthorizationDecision(true));
AuthorizationDecision decision = composed.check(null, null);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isTrue();
}
// gh-13069 // gh-13069
@Test @Test
void checkAllOfWhenAllNonAbstainingGrantsThenGrantedDecision() { void checkAllOfWhenAllNonAbstainingGrantsThenGrantedDecision() {
@ -82,6 +154,16 @@ class AuthorizationManagersTests {
assertThat(decision.isGranted()).isFalse(); assertThat(decision.isGranted()).isFalse();
} }
@Test
void checkAllOfWithAllAbstainDefaultDecisionWhenOneDeniedThenDeniedDecision() {
AuthorizationDecision allAbstainDefaultDecision = new AuthorizationDecision(true);
AuthorizationManager<?> composed = AuthorizationManagers.allOf(allAbstainDefaultDecision,
(a, o) -> new AuthorizationDecision(true), (a, o) -> new AuthorizationDecision(false));
AuthorizationDecision decision = composed.check(null, null);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isFalse();
}
@Test @Test
void checkAllOfWhenEmptyThenGrantedDecision() { void checkAllOfWhenEmptyThenGrantedDecision() {
AuthorizationManager<?> composed = AuthorizationManagers.allOf(); AuthorizationManager<?> composed = AuthorizationManagers.allOf();
@ -90,4 +172,56 @@ class AuthorizationManagersTests {
assertThat(decision.isGranted()).isTrue(); assertThat(decision.isGranted()).isTrue();
} }
@Test
void checkAllOfWithAllAbstainDefaultDecisionIsDeniedWhenEmptyThenDeniedDecision() {
AuthorizationDecision allAbstainDefaultDecision = new AuthorizationDecision(false);
AuthorizationManager<?> composed = AuthorizationManagers.allOf(allAbstainDefaultDecision);
AuthorizationDecision decision = composed.check(null, null);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isFalse();
}
@Test
void checkAllOfWithAllAbstainDefaultDecisionIsGrantedWhenEmptyThenGrantedDecision() {
AuthorizationDecision allAbstainDefaultDecision = new AuthorizationDecision(true);
AuthorizationManager<?> composed = AuthorizationManagers.allOf(allAbstainDefaultDecision);
AuthorizationDecision decision = composed.check(null, null);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isTrue();
}
@Test
void checkAllOfWithAllAbstainDefaultDecisionIsAbstainWhenEmptyThenAbstainDecision() {
AuthorizationDecision allAbstainDefaultDecision = null;
AuthorizationManager<?> composed = AuthorizationManagers.allOf(allAbstainDefaultDecision);
AuthorizationDecision decision = composed.check(null, null);
assertThat(decision).isNull();
}
@Test
void checkAllOfWhenAllAbstainDefaultDecisionIsDeniedAndAllManagersAbstainThenDeniedDecision() {
AuthorizationDecision allAbstainDefaultDecision = new AuthorizationDecision(false);
AuthorizationManager<?> composed = AuthorizationManagers.allOf(allAbstainDefaultDecision, (a, o) -> null);
AuthorizationDecision decision = composed.check(null, null);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isFalse();
}
@Test
void checkAllOfWhenAllAbstainDefaultDecisionIsGrantedAndAllManagersAbstainThenGrantedDecision() {
AuthorizationDecision allAbstainDefaultDecision = new AuthorizationDecision(true);
AuthorizationManager<?> composed = AuthorizationManagers.allOf(allAbstainDefaultDecision, (a, o) -> null);
AuthorizationDecision decision = composed.check(null, null);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isTrue();
}
@Test
void checkAllOfWhenAllAbstainDefaultDecisionIsAbstainAndAllManagersAbstainThenAbstainDecision() {
AuthorizationDecision allAbstainDefaultDecision = null;
AuthorizationManager<?> composed = AuthorizationManagers.allOf(allAbstainDefaultDecision, (a, o) -> null);
AuthorizationDecision decision = composed.check(null, null);
assertThat(decision).isNull();
}
} }