[java-identity-provider] branch master updated: IDP-1266 - RFE to deployer-constructed RequestedPrincipalContext
Scott Cantor
cantor.2 at osu.edu
Tue Sep 4 17:47:09 EDT 2018
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=1850ece08f838d668b5fb2eeb4dd82aacca2114f
The following commit(s) were added to refs/heads/master by this push:
new 1850ece IDP-1266 - RFE to deployer-constructed RequestedPrincipalContext
1850ece is described below
commit 1850ece08f838d668b5fb2eeb4dd82aacca2114f
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Sep 4 17:47:07 2018 -0400
IDP-1266 - RFE to deployer-constructed RequestedPrincipalContext
https://issues.shibboleth.net/jira/browse/IDP-1266
---
.../idp/authn/context/AuthenticationContext.java | 132 ++++++++++++++++++---
.../authn/context/AuthenticationContextTest.java | 50 +++++++-
2 files changed, 161 insertions(+), 21 deletions(-)
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/AuthenticationContext.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/AuthenticationContext.java
index e6d1388..a88bbbc 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/AuthenticationContext.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/AuthenticationContext.java
@@ -17,10 +17,14 @@
package net.shibboleth.idp.authn.context;
+import java.lang.reflect.Constructor;
import java.security.Principal;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import javax.annotation.Nonnull;
@@ -45,6 +49,8 @@ import org.opensaml.profile.context.ProfileRequestContext;
import com.google.common.base.Function;
import com.google.common.base.MoreObjects;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Collections2;
/**
* A context representing the state of an authentication attempt, this is the primary
@@ -91,11 +97,7 @@ public final class AuthenticationContext extends BaseContext {
/** Previously attempted flows (could be failures or intermediate results). */
@Nonnull @NonnullElements private final Map<String,AuthenticationFlowDescriptor> intermediateFlows;
- /**
- * Old copy of registry, moved to {@link RequestedPrincipalContext}.
- *
- * @deprecated
- */
+ /** Instance of registry used for auto-creation of {@link RequestedPrincipalContext}. */
@Nullable private PrincipalEvalPredicateFactoryRegistry evalRegistry;
/** Authentication flow being attempted to authenticate the user. */
@@ -215,12 +217,11 @@ public final class AuthenticationContext extends BaseContext {
/**
* Get the registry of predicate factories for custom principal evaluation.
*
- * <p>This object is only needed when evaluating a {@link RequestedPrincipalContext}, so the
- * presence of it at this level of the tree is historical.</p>
+ * <p>This object is only needed when evaluating a {@link RequestedPrincipalContext}, so the presence of it at
+ * this level of the tree is solely for use by the {@link #addRequestedPrincipalContext(String, List, boolean)}
+ * helper method.</p>
*
* @return predicate factory registry
- *
- * @deprecated Use {@link RequestedPrincipalContext#getPrincipalEvalPredicateFactoryRegistry()} instead.
*/
@Nonnull public PrincipalEvalPredicateFactoryRegistry getPrincipalEvalPredicateFactoryRegistry() {
@@ -235,22 +236,27 @@ public final class AuthenticationContext extends BaseContext {
}
/**
- * Set the registry of predicate factories for custom principal evaluation.
+ * Set the registry of predicate factories for custom principal evaluation to inject into instances of
+ * {@link RequestedPrincipalContext} created via the {@link #addRequestedPrincipalContext(String, List, boolean)}
+ * helper method.
+ *
+ * <p>It also propagates this object into any existing {@link RequestedPrincipalContext} subcontext.</p>
*
* @param registry predicate factory registry
*
- * @deprecated Use {@link RequestedPrincipalContext#setPrincipalEvalPredicateFactoryRegistry(
- * PrincipalEvalPredicateFactoryRegistry)} instead.
+ * @return this context
*/
- public void setPrincipalEvalPredicateFactoryRegistry(
+ @Nonnull public AuthenticationContext setPrincipalEvalPredicateFactoryRegistry(
@Nullable final PrincipalEvalPredicateFactoryRegistry registry) {
+ evalRegistry = registry;
+
final RequestedPrincipalContext rpCtx = getSubcontext(RequestedPrincipalContext.class);
if (rpCtx != null) {
rpCtx.setPrincipalEvalPredicateFactoryRegistry(registry);
- } else {
- evalRegistry = registry;
}
+
+ return this;
}
/**
@@ -601,6 +607,102 @@ public final class AuthenticationContext extends BaseContext {
return true;
}
}
+
+ /**
+ * Add (or replace) a {@link RequestedPrincipalContext} as a child of this context using the
+ * supplied parameters and the previously established {@link PrincipalEvalPredicateFactoryRegistry}
+ * for comparison handling.
+ *
+ * @param operator matching operator
+ * @param className name of class to wrap principal names
+ * @param principal name of principal to request
+ * @param replace whether to replace an existing context or simply return false
+ *
+ * @return true iff a new context was created
+ *
+ * @throws Exception if the principal class can't be loaded or instantiated as required
+ */
+ public boolean addRequestedPrincipalContext(@Nonnull @NotEmpty final String operator,
+ @Nonnull @NotEmpty final String className, @Nonnull @NotEmpty final String principal,
+ final boolean replace) throws Exception {
+
+ return addRequestedPrincipalContext(operator, className, Collections.singletonList(principal), replace);
+ }
+
+ /**
+ * Add (or replace) a {@link RequestedPrincipalContext} as a child of this context using the
+ * supplied parameters and the previously established {@link PrincipalEvalPredicateFactoryRegistry}
+ * for comparison handling.
+ *
+ * @param operator matching operator
+ * @param className name of class to wrap principal names
+ * @param principals names of principals to request
+ * @param replace whether to replace an existing context or simply return false
+ *
+ * @return true iff a new context was created
+ *
+ * @throws Exception if the principal class can't be loaded or instantiated as required
+ */
+ public boolean addRequestedPrincipalContext(@Nonnull @NotEmpty final String operator,
+ @Nonnull @NotEmpty final String className, @Nonnull final Collection<String> principals,
+ final boolean replace) throws Exception {
+
+ final Class<? extends Principal> claz = Class.forName(className).asSubclass(Principal.class);
+ final Constructor<? extends Principal> ctor = claz.getConstructor(String.class);
+
+ final List<Principal> prins = new ArrayList<>(principals.size());
+ for (final String prin : Collections2.filter(principals, Predicates.notNull())) {
+ prins.add(ctor.newInstance(prin));
+ }
+
+ return addRequestedPrincipalContext(operator, prins, replace);
+ }
+
+ /**
+ * Add (or replace) a {@link RequestedPrincipalContext} as a child of this context using the
+ * supplied parameters and the previously established {@link PrincipalEvalPredicateFactoryRegistry}
+ * for comparison handling.
+ *
+ * @param operator matching operator
+ * @param principal principal to request
+ * @param replace whether to replace an existing context or simply return false
+ *
+ * @return true iff a new context was created
+ */
+ public boolean addRequestedPrincipalContext(@Nonnull @NotEmpty final String operator,
+ @Nonnull final Principal principal, final boolean replace) {
+
+ return addRequestedPrincipalContext(operator, Collections.singletonList(principal), replace);
+ }
+
+ /**
+ * Add (or replace) a {@link RequestedPrincipalContext} as a child of this context using the
+ * supplied parameters and the previously established {@link PrincipalEvalPredicateFactoryRegistry}
+ * for comparison handling.
+ *
+ * @param operator matching operator
+ * @param principals principals to request
+ * @param replace whether to replace an existing context or simply return false
+ *
+ * @return true iff a new context was created
+ */
+ public boolean addRequestedPrincipalContext(@Nonnull @NotEmpty final String operator,
+ @Nonnull @NonnullElements final List<Principal> principals, final boolean replace) {
+
+ RequestedPrincipalContext rpCtx = getSubcontext(RequestedPrincipalContext.class);
+ if (rpCtx != null && !replace) {
+ return false;
+ }
+
+ rpCtx = new RequestedPrincipalContext();
+ rpCtx.setOperator(operator)
+ .setPrincipalEvalPredicateFactoryRegistry(evalRegistry)
+ .setRequestedPrincipals(principals);
+
+ addSubcontext(rpCtx, true);
+
+ return true;
+ }
/** {@inheritDoc} */
@Override
diff --git a/idp-authn-api/src/test/java/net/shibboleth/idp/authn/context/AuthenticationContextTest.java b/idp-authn-api/src/test/java/net/shibboleth/idp/authn/context/AuthenticationContextTest.java
index 60405fd..e7cb816 100644
--- a/idp-authn-api/src/test/java/net/shibboleth/idp/authn/context/AuthenticationContextTest.java
+++ b/idp-authn-api/src/test/java/net/shibboleth/idp/authn/context/AuthenticationContextTest.java
@@ -18,20 +18,24 @@
package net.shibboleth.idp.authn.context;
import java.util.Arrays;
+import java.util.Collections;
import javax.security.auth.Subject;
import net.shibboleth.idp.authn.AuthenticationFlowDescriptor;
import net.shibboleth.idp.authn.AuthenticationResult;
+import net.shibboleth.idp.authn.principal.PrincipalEvalPredicateFactoryRegistry;
+import net.shibboleth.idp.authn.principal.TestPrincipal;
import org.testng.Assert;
import org.testng.annotations.Test;
/** {@link AuthenticationContext} unit test. */
+ at Test
public class AuthenticationContextTest {
/** Tests initiation instant instantiation. */
- @Test public void testInitiationInstant() throws Exception {
+ public void testInitiationInstant() throws Exception {
long start = System.currentTimeMillis();
// this is here to allow the event's creation time to deviate from the 'start' time
Thread.sleep(50);
@@ -41,7 +45,7 @@ public class AuthenticationContextTest {
}
/** Tests mutating forcing authentication. */
- @Test public void testForcingAuthentication() throws Exception {
+ public void testForcingAuthentication() throws Exception {
AuthenticationContext ctx = new AuthenticationContext();
Assert.assertFalse(ctx.isForceAuthn());
@@ -50,7 +54,7 @@ public class AuthenticationContextTest {
}
/** Tests active results. */
- @Test public void testActiveResults() throws Exception {
+ public void testActiveResults() throws Exception {
final AuthenticationResult result = new AuthenticationResult("test", new Subject());
final AuthenticationContext ctx = new AuthenticationContext();
@@ -63,7 +67,7 @@ public class AuthenticationContextTest {
}
/** Tests potential flow instantiation. */
- @Test public void testPotentialFlows() throws Exception {
+ public void testPotentialFlows() throws Exception {
AuthenticationContext ctx = new AuthenticationContext();
Assert.assertTrue(ctx.getPotentialFlows().isEmpty());
@@ -76,7 +80,7 @@ public class AuthenticationContextTest {
}
/** Tests mutating attempted flow. */
- @Test public void testAttemptedFlow() throws Exception {
+ public void testAttemptedFlow() throws Exception {
final AuthenticationContext ctx = new AuthenticationContext();
Assert.assertNull(ctx.getAttemptedFlow());
@@ -87,7 +91,7 @@ public class AuthenticationContextTest {
}
/** Tests setting completion instant. */
- @Test public void testCompletionInstant() throws Exception {
+ public void testCompletionInstant() throws Exception {
final AuthenticationContext ctx = new AuthenticationContext();
Assert.assertEquals(ctx.getCompletionInstant(), 0);
@@ -99,4 +103,38 @@ public class AuthenticationContextTest {
Assert.assertTrue(ctx.getCompletionInstant() > now);
}
+ /** Tests RequestedPrincipalContext helpers. */
+ public void testRequestedPrincipalContextHelpers() throws Exception {
+ final AuthenticationContext ctx = new AuthenticationContext();
+ ctx.setPrincipalEvalPredicateFactoryRegistry(new PrincipalEvalPredicateFactoryRegistry());
+
+ ctx.addRequestedPrincipalContext("foo", new TestPrincipal("bar"), false);
+ RequestedPrincipalContext rpCtx = ctx.getSubcontext(RequestedPrincipalContext.class);
+ Assert.assertNotNull(rpCtx);
+ Assert.assertEquals(rpCtx.getOperator(), "foo");
+ Assert.assertEquals(rpCtx.getRequestedPrincipals(), Collections.singletonList(new TestPrincipal("bar")));
+
+ Assert.assertFalse(ctx.addRequestedPrincipalContext("foo", new TestPrincipal("bar"), false));
+
+ ctx.addRequestedPrincipalContext("fob", TestPrincipal.class.getName(), "baz", true);
+ rpCtx = ctx.getSubcontext(RequestedPrincipalContext.class);
+ Assert.assertNotNull(rpCtx);
+ Assert.assertEquals(rpCtx.getOperator(), "fob");
+ Assert.assertEquals(rpCtx.getRequestedPrincipals(), Collections.singletonList(new TestPrincipal("baz")));
+
+ ctx.addRequestedPrincipalContext("fog", TestPrincipal.class.getName(), Arrays.asList("baf", "bag"), true);
+ rpCtx = ctx.getSubcontext(RequestedPrincipalContext.class);
+ Assert.assertNotNull(rpCtx);
+ Assert.assertEquals(rpCtx.getOperator(), "fog");
+ Assert.assertEquals(rpCtx.getRequestedPrincipals().size(), 2);
+ }
+
+ @Test(expectedExceptions = ClassCastException.class)
+ public void testRequestedPrincipalContextHelperBadType() throws Exception {
+ final AuthenticationContext ctx = new AuthenticationContext();
+ ctx.setPrincipalEvalPredicateFactoryRegistry(new PrincipalEvalPredicateFactoryRegistry());
+
+ ctx.addRequestedPrincipalContext("fob", AuthenticationContext.class.getName(), "baz", false);
+ }
+
}
\ 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