diff --git a/binder/src/main/java/io/grpc/binder/SecurityPolicies.java b/binder/src/main/java/io/grpc/binder/SecurityPolicies.java index d89e173822e..61aaf97eb13 100644 --- a/binder/src/main/java/io/grpc/binder/SecurityPolicies.java +++ b/binder/src/main/java/io/grpc/binder/SecurityPolicies.java @@ -187,4 +187,35 @@ private static boolean checkPackageSignature( } return false; } + + /** + * Creates a {@link SecurityPolicy} that allows access if and only if *all* of the specified + * {@code securityPolicies} allow access. + * + * @param securityPolicies the security policies that all must allow access. + * @throws NullPointerException if any of the inputs are {@code null}. + * @throws IllegalArgumentException if {@code securityPolicies} is empty. + */ + public static SecurityPolicy allOf(SecurityPolicy... securityPolicies) { + Preconditions.checkNotNull(securityPolicies, "securityPolicies"); + Preconditions.checkArgument(securityPolicies.length > 0, "securityPolicies must not be empty"); + + return allOfSecurityPolicy(securityPolicies); + } + + private static SecurityPolicy allOfSecurityPolicy(SecurityPolicy... securityPolicies) { + return new SecurityPolicy() { + @Override + public Status checkAuthorization(int uid) { + for (SecurityPolicy policy : securityPolicies) { + Status checkAuth = policy.checkAuthorization(uid); + if (!checkAuth.isOk()) { + return checkAuth; + } + } + + return Status.OK; + } + }; + } } diff --git a/binder/src/test/java/io/grpc/binder/SecurityPoliciesTest.java b/binder/src/test/java/io/grpc/binder/SecurityPoliciesTest.java index 86edb5ad7df..dbac29681b9 100644 --- a/binder/src/test/java/io/grpc/binder/SecurityPoliciesTest.java +++ b/binder/src/test/java/io/grpc/binder/SecurityPoliciesTest.java @@ -171,4 +171,24 @@ public void testHasSignature_failsIfUidUnknown() throws Exception { assertThat(policy.checkAuthorization(OTHER_UID_UNKNOWN).getCode()) .isEqualTo(Status.UNAUTHENTICATED.getCode()); } + + @Test + public void testAllOf_succeedsIfAllSecurityPoliciesAllowed() throws Exception { + policy = SecurityPolicies.allOf(SecurityPolicies.internalOnly()); + + assertThat(policy.checkAuthorization(MY_UID).getCode()).isEqualTo(Status.OK.getCode()); + } + + @Test + public void testAllOf_failsIfOneSecurityPoliciesNotAllowed() throws Exception { + policy = + SecurityPolicies.allOf( + SecurityPolicies.internalOnly(), + SecurityPolicies.permissionDenied("Not allowed SecurityPolicy")); + + assertThat(policy.checkAuthorization(MY_UID).getCode()) + .isEqualTo(Status.PERMISSION_DENIED.getCode()); + assertThat(policy.checkAuthorization(MY_UID).getDescription()) + .contains("Not allowed SecurityPolicy"); + } }