[java-identity-provider] branch master updated: Final cleanup (I hope) on proxy computation.
Scott Cantor
cantor.2 at osu.edu
Fri Nov 22 12:27:09 EST 2019
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch master
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=63fba8d6c306deacc87d62919c8e118a810b6893
The following commit(s) were added to refs/heads/master by this push:
new 63fba8d Final cleanup (I hope) on proxy computation.
63fba8d is described below
commit 63fba8d6c306deacc87d62919c8e118a810b6893
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Fri Nov 22 12:27:05 2019 -0500
Final cleanup (I hope) on proxy computation.
Remove unused functions and move Proxy computation into SAML2 package.
Add unit test.
Fix bugs around empty audience intersections.
---
.../system/flows/saml/saml2/sso-abstract-beans.xml | 2 +-
.../ProxyAudienceRestrictionsLookupFunction.java | 59 ------
.../config/navigate/ProxyCountLookupFunction.java | 52 -----
.../navigate/ProxyRestrictionLookupFunction.java | 70 ++++---
.../ProxyRestrictionLookupFunctionTest.java | 232 +++++++++++++++++++++
5 files changed, 279 insertions(+), 136 deletions(-)
diff --git a/idp-conf/src/main/resources/system/flows/saml/saml2/sso-abstract-beans.xml b/idp-conf/src/main/resources/system/flows/saml/saml2/sso-abstract-beans.xml
index c3ebffe..7f2109a 100644
--- a/idp-conf/src/main/resources/system/flows/saml/saml2/sso-abstract-beans.xml
+++ b/idp-conf/src/main/resources/system/flows/saml/saml2/sso-abstract-beans.xml
@@ -92,7 +92,7 @@
<bean id="AddProxyRestrictionToAssertions"
class="org.opensaml.saml.saml2.profile.impl.AddProxyRestrictionToAssertions" scope="prototype">
<property name="proxyRestrictionLookupStrategy">
- <bean class="net.shibboleth.idp.saml.profile.config.navigate.ProxyRestrictionLookupFunction" />
+ <bean class="net.shibboleth.idp.saml.saml2.profile.config.navigate.ProxyRestrictionLookupFunction" />
</property>
</bean>
diff --git a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/ProxyAudienceRestrictionsLookupFunction.java b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/ProxyAudienceRestrictionsLookupFunction.java
deleted file mode 100644
index 2c9ae2d..0000000
--- a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/ProxyAudienceRestrictionsLookupFunction.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the University Corporation for Advanced Internet Development,
- * Inc. (UCAID) under one or more contributor license agreements. See the
- * NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The UCAID licenses this file to You under the Apache
- * License, Version 2.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.saml.profile.config.navigate;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import javax.annotation.Nullable;
-
-import net.shibboleth.idp.profile.config.ProfileConfiguration;
-import net.shibboleth.idp.profile.context.RelyingPartyContext;
-import net.shibboleth.idp.profile.context.navigate.AbstractRelyingPartyLookupFunction;
-import net.shibboleth.idp.saml.saml2.profile.config.SAML2ProfileConfiguration;
-import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
-import net.shibboleth.utilities.java.support.annotation.constraint.NotLive;
-import net.shibboleth.utilities.java.support.annotation.constraint.Unmodifiable;
-
-import org.opensaml.profile.context.ProfileRequestContext;
-
-/**
- * A function that returns the effective proxy audience restrictions to include in assertions,
- * based on the result of {@link SAML2ProfileConfiguration#getProxyAudiences(ProfileRequestContext)},
- * if such a profile is available from a {@link RelyingPartyContext} obtained via a lookup function,
- * by default a child of the {@link ProfileRequestContext}.
- *
- * <p>If a specific setting is unavailable, no values are returned.</p>
- */
-public class ProxyAudienceRestrictionsLookupFunction extends AbstractRelyingPartyLookupFunction<Collection<String>> {
-
- /** {@inheritDoc} */
- @Nullable @NonnullElements @NotLive @Unmodifiable public Collection<String> apply(
- @Nullable final ProfileRequestContext input) {
- final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
- if (rpc != null) {
- final ProfileConfiguration pc = rpc.getProfileConfig();
- if (pc != null && pc instanceof SAML2ProfileConfiguration) {
- return ((SAML2ProfileConfiguration) pc).getProxyAudiences(input);
- }
- }
-
- return Collections.emptyList();
- }
-
-}
\ No newline at end of file
diff --git a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/ProxyCountLookupFunction.java b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/ProxyCountLookupFunction.java
deleted file mode 100644
index 4091e68..0000000
--- a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/ProxyCountLookupFunction.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the University Corporation for Advanced Internet Development,
- * Inc. (UCAID) under one or more contributor license agreements. See the
- * NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The UCAID licenses this file to You under the Apache
- * License, Version 2.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.saml.profile.config.navigate;
-
-import javax.annotation.Nullable;
-
-import net.shibboleth.idp.profile.config.ProfileConfiguration;
-import net.shibboleth.idp.profile.context.RelyingPartyContext;
-import net.shibboleth.idp.profile.context.navigate.AbstractRelyingPartyLookupFunction;
-import net.shibboleth.idp.saml.saml2.profile.config.SAML2ProfileConfiguration;
-
-import org.opensaml.profile.context.ProfileRequestContext;
-
-/**
- * A function that returns the allowable proxy count to include in assertions,
- * based on the result of {@link SAML2ProfileConfiguration#getProxyCount(ProfileRequestContext)},
- * if such a profile is available from a {@link RelyingPartyContext} obtained via a lookup function,
- * by default a child of the {@link ProfileRequestContext}.
- *
- * <p>If a specific setting is unavailable, a null is returned.</p>
- */
-public class ProxyCountLookupFunction extends AbstractRelyingPartyLookupFunction<Integer> {
-
- /** {@inheritDoc} */
- @Nullable public Integer apply(@Nullable final ProfileRequestContext input) {
- final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
- if (rpc != null) {
- final ProfileConfiguration pc = rpc.getProfileConfig();
- if (pc != null && pc instanceof SAML2ProfileConfiguration) {
- return ((SAML2ProfileConfiguration) pc).getProxyCount(input);
- }
- }
-
- return null;
- }
-
-}
\ No newline at end of file
diff --git a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/ProxyRestrictionLookupFunction.java b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/navigate/ProxyRestrictionLookupFunction.java
similarity index 69%
rename from idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/ProxyRestrictionLookupFunction.java
rename to idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/navigate/ProxyRestrictionLookupFunction.java
index 456f616..c1592d0 100644
--- a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/ProxyRestrictionLookupFunction.java
+++ b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/navigate/ProxyRestrictionLookupFunction.java
@@ -15,8 +15,9 @@
* limitations under the License.
*/
-package net.shibboleth.idp.saml.profile.config.navigate;
+package net.shibboleth.idp.saml.saml2.profile.config.navigate;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Function;
@@ -62,11 +63,18 @@ public class ProxyRestrictionLookupFunction extends AbstractRelyingPartyLookupFu
subjectContextLookupStrategy = Constraint.isNotNull(strategy, "SubjectContext lookup strategy cannot be null");
}
-// Checkstyle: CyclomaticComplexity OFF
+// Checkstyle: CyclomaticComplexity|MethodLength OFF
/** {@inheritDoc} */
@Nullable public Pair<Integer,Set<String>> apply(@Nullable final ProfileRequestContext input) {
+
+ // The proxy count is normally set to the minimum of local policy and upstream - 1, but
+ // null values have to taken into account, and 0 is the minimum.
Integer proxyCount = null;
+
+ // The empty set signals no constraint on proxy, but a null value is used to track when
+ // the interaction of existing sets has resulted in the null set, which means no proxying.
+
final Set<String> audiences = new HashSet<>();
final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
@@ -75,34 +83,30 @@ public class ProxyRestrictionLookupFunction extends AbstractRelyingPartyLookupFu
if (pc != null && pc instanceof SAML2ProfileConfiguration) {
proxyCount = ((SAML2ProfileConfiguration) pc).getProxyCount(input);
final Set<String> configAudiences = ((SAML2ProfileConfiguration) pc).getProxyAudiences(input);
- if (configAudiences != null) {
+ if (configAudiences != null && !configAudiences.isEmpty()) {
audiences.addAll(configAudiences);
}
}
}
-
- final SubjectContext sc = subjectContextLookupStrategy.apply(input);
+
+ // At this point the local configuration applies, and lacking any upstream, that applies.
- if (sc == null) {
- if (proxyCount != null) {
- proxyCount = Integer.max(0, proxyCount - 1);
- }
- return new Pair<>(proxyCount, audiences);
+ final SubjectContext sc = subjectContextLookupStrategy.apply(input);
+ final Set<ProxyAuthenticationPrincipal> proxieds =
+ sc == null ? Collections.emptySet()
+ : sc.getSubjects().stream()
+ .map(s -> s.getPrincipals(ProxyAuthenticationPrincipal.class))
+ .flatMap(Set::stream)
+ .collect(Collectors.toUnmodifiableSet());
+
+ if (proxieds.isEmpty()) {
+ return new Pair<>(proxyCount, Set.copyOf(audiences));
}
- final Set<ProxyAuthenticationPrincipal> proxieds =
- sc.getSubjects().stream()
- .map(s -> s.getPrincipals(ProxyAuthenticationPrincipal.class))
- .flatMap(Set::stream)
- .collect(Collectors.toUnmodifiableSet());
for (final ProxyAuthenticationPrincipal p : proxieds) {
- if (p.getProxyCount() != null) {
- if (proxyCount != null) {
- proxyCount = Integer.min(proxyCount, Integer.max(0, p.getProxyCount() - 1));
- } else {
- proxyCount = Integer.max(0, p.getProxyCount() - 1);
- }
- }
+
+ // Given upstream audiences, we either initialize an empty local set to that set,
+ // or intersect the non-empty local set against upstream.
final Set<String> upstreamAudiences = p.getAudiences();
if (upstreamAudiences != null && !upstreamAudiences.isEmpty()) {
@@ -110,12 +114,30 @@ public class ProxyRestrictionLookupFunction extends AbstractRelyingPartyLookupFu
audiences.addAll(upstreamAudiences);
} else {
audiences.retainAll(upstreamAudiences);
+
+ // If the interaction is empty, we have disallowed proxying by finding no common
+ // audiences, and can immediately exit signaling no proxying.
+
+ if (audiences.isEmpty()) {
+ return new Pair<>(0, Collections.emptySet());
+ }
+ }
+ }
+
+ // Given a non-null upstream count, we reduce the local value if necessary, or possibly
+ // set it for the first time. The max expression just turns -1 back into 0.
+
+ if (p.getProxyCount() != null) {
+ if (proxyCount != null) {
+ proxyCount = Integer.min(proxyCount, Integer.max(0, p.getProxyCount() - 1));
+ } else {
+ proxyCount = Integer.max(0, p.getProxyCount() - 1);
}
}
}
- return new Pair<>(proxyCount, audiences);
+ return new Pair<>(proxyCount, Set.copyOf(audiences));
}
-// Checkstyle: CyclomaticComplexity ON
+// Checkstyle: CyclomaticComplexity|MethodLength ON
}
\ No newline at end of file
diff --git a/idp-saml-api/src/test/java/net/shibboleth/idp/saml/saml2/profile/config/navigate/ProxyRestrictionLookupFunctionTest.java b/idp-saml-api/src/test/java/net/shibboleth/idp/saml/saml2/profile/config/navigate/ProxyRestrictionLookupFunctionTest.java
new file mode 100644
index 0000000..a2ed5ee
--- /dev/null
+++ b/idp-saml-api/src/test/java/net/shibboleth/idp/saml/saml2/profile/config/navigate/ProxyRestrictionLookupFunctionTest.java
@@ -0,0 +1,232 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.saml.saml2.profile.config.navigate;
+
+import java.util.Collections;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+
+import net.shibboleth.idp.authn.AuthenticationResult;
+import net.shibboleth.idp.authn.context.SubjectContext;
+import net.shibboleth.idp.authn.principal.ProxyAuthenticationPrincipal;
+import net.shibboleth.idp.profile.RequestContextBuilder;
+import net.shibboleth.idp.profile.context.RelyingPartyContext;
+import net.shibboleth.idp.saml.saml2.profile.config.BrowserSSOProfileConfiguration;
+import net.shibboleth.utilities.java.support.collection.Pair;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+
+import org.opensaml.core.OpenSAMLInitBaseTestCase;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/** Unit test for {@link ProxyRestrictionLookupFunction}. */
+public class ProxyRestrictionLookupFunctionTest extends OpenSAMLInitBaseTestCase {
+
+ private ProfileRequestContext prc;
+ private SubjectContext sc;
+ private BrowserSSOProfileConfiguration config;
+ private ProxyRestrictionLookupFunction fn;
+ private Pair<Integer,Set<String>> result;
+
+ @BeforeMethod
+ public void setUp() throws ComponentInitializationException {
+ prc = new RequestContextBuilder()
+ .setRelyingPartyProfileConfigurations(Collections.singletonList(new BrowserSSOProfileConfiguration()))
+ .buildProfileRequestContext();
+ config = (BrowserSSOProfileConfiguration) prc.getSubcontext(RelyingPartyContext.class).getConfiguration().getProfileConfiguration(
+ prc, BrowserSSOProfileConfiguration.PROFILE_ID);
+ prc.getSubcontext(RelyingPartyContext.class).setProfileConfig(config);
+ sc = prc.getSubcontext(SubjectContext.class, true);
+ sc.getAuthenticationResults().put("test1", new AuthenticationResult("test1", new Subject()));
+ sc.getAuthenticationResults().put("test2", new AuthenticationResult("test2", new Subject()));
+ fn = new ProxyRestrictionLookupFunction();
+ }
+
+ @Test
+ public void testNoPrincipals() {
+ result = fn.apply(prc);
+ Assert.assertNull(result.getFirst());
+ Assert.assertTrue(result.getSecond().isEmpty());
+ }
+
+ @Test
+ public void testOneEmptyPrincipal() {
+ final ProxyAuthenticationPrincipal proxy = new ProxyAuthenticationPrincipal();
+ sc.getAuthenticationResults().get("test2").getSubject().getPrincipals().add(proxy);
+
+ result = fn.apply(prc);
+ Assert.assertNull(result.getFirst());
+ Assert.assertTrue(result.getSecond().isEmpty());
+ }
+
+ @Test
+ public void testOneCount() {
+ final ProxyAuthenticationPrincipal proxy = new ProxyAuthenticationPrincipal();
+ proxy.setProxyCount(10);
+ sc.getAuthenticationResults().get("test2").getSubject().getPrincipals().add(proxy);
+
+ result = fn.apply(prc);
+ Assert.assertEquals(result.getFirst(), Integer.valueOf(9));
+ Assert.assertTrue(result.getSecond().isEmpty());
+
+ proxy.setProxyCount(1);
+ result = fn.apply(prc);
+ Assert.assertEquals(result.getFirst(), Integer.valueOf(0));
+
+ proxy.setProxyCount(0);
+ result = fn.apply(prc);
+ Assert.assertEquals(result.getFirst(), Integer.valueOf(0));
+ }
+
+ @Test
+ public void testTwoCounts() {
+ final ProxyAuthenticationPrincipal proxy1 = new ProxyAuthenticationPrincipal();
+ proxy1.setProxyCount(10);
+ sc.getAuthenticationResults().get("test1").getSubject().getPrincipals().add(proxy1);
+
+ final ProxyAuthenticationPrincipal proxy2 = new ProxyAuthenticationPrincipal();
+ proxy1.setProxyCount(5);
+ sc.getAuthenticationResults().get("test2").getSubject().getPrincipals().add(proxy2);
+
+ result = fn.apply(prc);
+ Assert.assertEquals(result.getFirst(), Integer.valueOf(4));
+ Assert.assertTrue(result.getSecond().isEmpty());
+
+ proxy1.setProxyCount(1);
+ proxy2.setProxyCount(1);
+ result = fn.apply(prc);
+ Assert.assertEquals(result.getFirst(), Integer.valueOf(0));
+
+ proxy1.setProxyCount(0);
+ proxy1.setProxyCount(5);
+ result = fn.apply(prc);
+ Assert.assertEquals(result.getFirst(), Integer.valueOf(0));
+ }
+
+ @Test
+ public void testOneAudienceSet() {
+ final ProxyAuthenticationPrincipal proxy = new ProxyAuthenticationPrincipal();
+ proxy.setProxyCount(10);
+ proxy.getAudiences().addAll(Set.of("foo", "bar"));
+ sc.getAuthenticationResults().get("test2").getSubject().getPrincipals().add(proxy);
+
+ result = fn.apply(prc);
+ Assert.assertEquals(result.getFirst(), Integer.valueOf(9));
+ Assert.assertEquals(result.getSecond(), Set.of("foo", "bar"));
+ }
+
+ @Test
+ public void testTwoAudienceSets() {
+ final ProxyAuthenticationPrincipal proxy1 = new ProxyAuthenticationPrincipal();
+ proxy1.setProxyCount(10);
+ proxy1.getAudiences().addAll(Set.of("foo", "bar"));
+ sc.getAuthenticationResults().get("test1").getSubject().getPrincipals().add(proxy1);
+
+ final ProxyAuthenticationPrincipal proxy2 = new ProxyAuthenticationPrincipal();
+ proxy2.getAudiences().addAll(Set.of("foo", "bar"));
+ sc.getAuthenticationResults().get("test2").getSubject().getPrincipals().add(proxy2);
+
+ result = fn.apply(prc);
+ Assert.assertEquals(result.getFirst(), Integer.valueOf(9));
+ Assert.assertEquals(result.getSecond(), Set.of("foo", "bar"));
+
+ proxy1.getAudiences().clear();
+ proxy1.getAudiences().add("bar");
+ result = fn.apply(prc);
+ Assert.assertEquals(result.getSecond(), Set.of("bar"));
+
+ proxy2.getAudiences().clear();
+ proxy2.getAudiences().add("foo");
+ result = fn.apply(prc);
+ Assert.assertTrue(result.getSecond().isEmpty());
+ }
+
+ @Test
+ public void testConfigOnly() {
+ config.setProxyCount(5);
+ config.setProxyAudiences(Set.of("foo", "bar"));
+ prc.removeSubcontext(sc);
+
+ result = fn.apply(prc);
+ Assert.assertEquals(result.getFirst(), Integer.valueOf(5));
+ Assert.assertEquals(result.getSecond(), Set.of("foo", "bar"));
+ }
+
+ @Test
+ public void testJointCount() {
+ config.setProxyCount(5);
+
+ final ProxyAuthenticationPrincipal proxy1 = new ProxyAuthenticationPrincipal();
+ proxy1.setProxyCount(10);
+ sc.getAuthenticationResults().get("test1").getSubject().getPrincipals().add(proxy1);
+
+ final ProxyAuthenticationPrincipal proxy2 = new ProxyAuthenticationPrincipal();
+ proxy1.setProxyCount(5);
+ sc.getAuthenticationResults().get("test2").getSubject().getPrincipals().add(proxy2);
+
+ result = fn.apply(prc);
+ Assert.assertEquals(result.getFirst(), Integer.valueOf(4));
+ Assert.assertTrue(result.getSecond().isEmpty());
+
+ config.setProxyCount(1);
+ proxy1.setProxyCount(1);
+ result = fn.apply(prc);
+ Assert.assertEquals(result.getFirst(), Integer.valueOf(0));
+
+ config.setProxyCount(0);
+ proxy1.setProxyCount(3);
+ result = fn.apply(prc);
+ Assert.assertEquals(result.getFirst(), Integer.valueOf(0));
+ }
+
+ @Test
+ public void testJointAudiences() {
+ config.setProxyAudiences(Set.of("foo", "bar"));
+
+ final ProxyAuthenticationPrincipal proxy1 = new ProxyAuthenticationPrincipal();
+ proxy1.getAudiences().addAll(Set.of("foo", "bar"));
+ sc.getAuthenticationResults().get("test1").getSubject().getPrincipals().add(proxy1);
+
+ final ProxyAuthenticationPrincipal proxy2 = new ProxyAuthenticationPrincipal();
+ proxy2.getAudiences().addAll(Set.of("foo", "bar"));
+ sc.getAuthenticationResults().get("test2").getSubject().getPrincipals().add(proxy2);
+
+ result = fn.apply(prc);
+ Assert.assertNull(result.getFirst());
+ Assert.assertEquals(result.getSecond(), Set.of("foo", "bar"));
+
+ config.setProxyAudiences(Set.of("foo", "baz"));
+ result = fn.apply(prc);
+ Assert.assertEquals(result.getSecond(), Set.of("foo"));
+
+ proxy2.getAudiences().clear();
+ proxy2.getAudiences().addAll(Set.of("foo", "bar", "baz"));
+ result = fn.apply(prc);
+ Assert.assertEquals(result.getSecond(), Set.of("foo"));
+
+ proxy1.getAudiences().clear();
+ proxy1.getAudiences().add("bar");
+ result = fn.apply(prc);
+ Assert.assertTrue(result.getSecond().isEmpty());
+ Assert.assertEquals(result.getFirst(), Integer.valueOf(0));
+ }
+
+}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list