[java-idp-plugin-webauthn] branch main updated: Convert registration options to functions

Phil Smart philip.smart at jisc.ac.uk
Wed Nov 13 16:58:11 UTC 2024


This is an automated email from the git hooks/post-receive script.

philsmart pushed a commit to branch main
in repository java-idp-plugin-webauthn.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-plugin-webauthn.git;a=commit;h=115cfde3384f1839d3bc43b9241ee0506e35c4e4

The following commit(s) were added to refs/heads/main by this push:
     new 115cfde  Convert registration options to functions
115cfde is described below

commit 115cfde3384f1839d3bc43b9241ee0506e35c4e4
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Wed Nov 13 16:58:07 2024 +0000

    Convert registration options to functions
    
     - in case somebody wants to supply a dynamic function for those.
---
 .../impl/AddAttestationConveyancePreference.java   | 40 ++++++++++++++------
 .../AddAuthenticatorAttachmentRequirement.java     | 43 +++++++++++++++-------
 .../admin/impl/AddResidentKeyRequirement.java      | 40 ++++++++++++++------
 .../webauthn-registration-beans.xml                |  9 +++--
 4 files changed, 93 insertions(+), 39 deletions(-)

diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/AddAttestationConveyancePreference.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/AddAttestationConveyancePreference.java
index 58b0005..97d6d4c 100644
--- a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/AddAttestationConveyancePreference.java
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/AddAttestationConveyancePreference.java
@@ -14,9 +14,11 @@
 
 package net.shibboleth.idp.plugin.authn.webauthn.admin.impl;
 
+import java.util.function.Function;
 import java.util.stream.Stream;
 
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 
 import org.opensaml.messaging.context.navigate.ChildContextLookup;
 import org.opensaml.profile.context.ProfileRequestContext;
@@ -27,9 +29,8 @@ import com.yubico.webauthn.data.AttestationConveyancePreference;
 import net.shibboleth.idp.plugin.authn.webauthn.context.WebAuthnAuthenticationContext;
 import net.shibboleth.idp.plugin.authn.webauthn.context.WebAuthnRegistrationContext;
 import net.shibboleth.idp.plugin.authn.webauthn.impl.AbstractWebAuthnAction;
-import net.shibboleth.shared.annotation.constraint.NotEmpty;
-import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.logic.FunctionSupport;
 import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
@@ -45,13 +46,14 @@ public class AddAttestationConveyancePreference extends AbstractWebAuthnAction<W
     /** Class logger. */
     @Nonnull private final Logger log = LoggerFactory.getLogger(AddAttestationConveyancePreference.class);
     
-    /** The attestation conveyance preference. Default is 'none'. */
-    @Nonnull private AttestationConveyancePreference attestationConveyancePreference;
+    /** A strategy to lookup the attestation conveyance preference. Default is 'none'. */
+    @Nonnull private 
+    Function<ProfileRequestContext, AttestationConveyancePreference> attestationConveyancePreferenceLookupStrategy;
     
     /** Constructor.*/
     public AddAttestationConveyancePreference() {
         super(new ChildContextLookup<>(WebAuthnRegistrationContext.class));
-        attestationConveyancePreference = AttestationConveyancePreference.NONE;
+        attestationConveyancePreferenceLookupStrategy = FunctionSupport.constant(AttestationConveyancePreference.NONE);
     }
     
     /**
@@ -59,10 +61,11 @@ public class AddAttestationConveyancePreference extends AbstractWebAuthnAction<W
      * 
      * @param preference the attestation conveyance preference to set.
      */
-    public void setAttestationConveyancePreference(@Nonnull @NotEmpty final String preference) {
+    public void setAttestationConveyancePreference(@Nullable final String preference) {
         checkSetterPreconditions();
-        Constraint.isNotEmpty(preference, "AttestationConveyancePreference can not be null or empty");
-        
+        if (preference == null) {
+            return;
+        }        
         final AttestationConveyancePreference attestationPreference = 
                 Stream.of(AttestationConveyancePreference.values())
                 .filter(uv -> uv.getValue().equals(preference))
@@ -70,7 +73,20 @@ public class AddAttestationConveyancePreference extends AbstractWebAuthnAction<W
                 .orElseThrow(() -> 
                 new ConstraintViolationException("Attestation conveyance preference '"+preference+"' unknown"));
         assert attestationPreference != null;
-        attestationConveyancePreference = attestationPreference;
+        attestationConveyancePreferenceLookupStrategy = FunctionSupport.constant(attestationPreference);
+    }
+    
+    /**
+     * Set the strategy used to lookup the attestation conveyance preference. 
+     * 
+     * @param strategy The attestation conveyance preference lookup strategy to set.
+     */
+    public void setAttestationConveyancePreferenceLookupStrategy(
+            @Nullable final Function<ProfileRequestContext, AttestationConveyancePreference> strategy) {        
+        checkSetterPreconditions();
+        if (strategy != null) {
+            attestationConveyancePreferenceLookupStrategy = strategy;
+        }
     }
     
     /** {@inheritDoc} */
@@ -78,8 +94,10 @@ public class AddAttestationConveyancePreference extends AbstractWebAuthnAction<W
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext,
             @Nonnull final WebAuthnRegistrationContext context) {
 
-        log.trace("{} Attestation conveyance preference is '{}'",getLogPrefix(), attestationConveyancePreference);
-        context.setAttestationConveyancePreference(attestationConveyancePreference);
+        final AttestationConveyancePreference preference = 
+                attestationConveyancePreferenceLookupStrategy.apply(profileRequestContext);
+        log.trace("{} Attestation conveyance preference is '{}'",getLogPrefix(), preference);
+        context.setAttestationConveyancePreference(preference);
         
     }
 
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/AddAuthenticatorAttachmentRequirement.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/AddAuthenticatorAttachmentRequirement.java
index bba98a8..410f5e1 100644
--- a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/AddAuthenticatorAttachmentRequirement.java
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/AddAuthenticatorAttachmentRequirement.java
@@ -14,6 +14,7 @@
 
 package net.shibboleth.idp.plugin.authn.webauthn.admin.impl;
 
+import java.util.function.Function;
 import java.util.stream.Stream;
 
 import javax.annotation.Nonnull;
@@ -27,9 +28,8 @@ import com.yubico.webauthn.data.AuthenticatorAttachment;
 
 import net.shibboleth.idp.plugin.authn.webauthn.context.WebAuthnRegistrationContext;
 import net.shibboleth.idp.plugin.authn.webauthn.impl.AbstractWebAuthnAction;
-import net.shibboleth.shared.annotation.constraint.NotEmpty;
-import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.logic.FunctionSupport;
 import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
@@ -44,13 +44,14 @@ public class AddAuthenticatorAttachmentRequirement extends AbstractWebAuthnActio
     /** Class logger. */
     @Nonnull private final Logger log = LoggerFactory.getLogger(AddAuthenticatorAttachmentRequirement.class);
     
-    /** Set the AuthenticatorAttachment requirement. Default is null, so 'any'.*/
-    @Nullable private AuthenticatorAttachment authenticatorAttachmentRequirement;
+    /** A strategy to lookup the AuthenticatorAttachment requirement. Default is null, so 'any'. */
+    @Nonnull private 
+    Function<ProfileRequestContext, AuthenticatorAttachment> authenticatorAttachmentRequirementLookupStrategy;
     
     /** Constructor.*/
     public AddAuthenticatorAttachmentRequirement() {
         super(new ChildContextLookup<>(WebAuthnRegistrationContext.class));
-        authenticatorAttachmentRequirement = null;
+        authenticatorAttachmentRequirementLookupStrategy = FunctionSupport.constant(null);
     }
     
     /**
@@ -58,12 +59,13 @@ public class AddAuthenticatorAttachmentRequirement extends AbstractWebAuthnActio
      * 
      * @param requirement The authenticator attachment requirement to set.
      */
-    public void setAuthenticatorAttachmentRequirement(@Nonnull @NotEmpty final String requirement) {
+    public void setAuthenticatorAttachmentRequirement(@Nullable final String requirement) {
         checkSetterPreconditions();
-        Constraint.isNotEmpty(requirement, "AuthenticatorAttachment requirement can not be null or empty");
-        
+        if (requirement == null) {
+            return;
+        }        
         if ("any".equals(requirement)) {
-            authenticatorAttachmentRequirement = null;
+            authenticatorAttachmentRequirementLookupStrategy = FunctionSupport.constant(null);
         } else {        
             final AuthenticatorAttachment aaRequirement = 
                     Stream.of(AuthenticatorAttachment.values())
@@ -72,7 +74,20 @@ public class AddAuthenticatorAttachmentRequirement extends AbstractWebAuthnActio
                     .orElseThrow(() -> 
                     new ConstraintViolationException("AuthenticatorAttachment requirement "+requirement+" unknown"));
             assert aaRequirement != null;
-            authenticatorAttachmentRequirement = aaRequirement;
+            authenticatorAttachmentRequirementLookupStrategy = FunctionSupport.constant(aaRequirement);
+        }
+    }
+    
+    /**
+     * Set the lookup strategy to find the authenticator attachment requirement. 
+     * 
+     * @param strategy The authenticator attachment requirement lookup strategy to set.
+     */
+    public void setAuthenticatorAttachmentRequirementLookupStrategy(
+            @Nullable final Function<ProfileRequestContext, AuthenticatorAttachment> strategy) {
+        checkSetterPreconditions();
+        if (strategy != null) {
+            authenticatorAttachmentRequirementLookupStrategy = strategy;
         }
     }
     
@@ -81,9 +96,11 @@ public class AddAuthenticatorAttachmentRequirement extends AbstractWebAuthnActio
     protected void doExecute(final ProfileRequestContext profileRequestContext, 
             final WebAuthnRegistrationContext context) {
 
-        log.trace("{} AuthenticatorAttachment is '{}'",getLogPrefix(), authenticatorAttachmentRequirement != null ?
-                authenticatorAttachmentRequirement : "ANY");
-        context.setAuthenticatorAttachmentRequirement(authenticatorAttachmentRequirement);
+        final AuthenticatorAttachment attachment = 
+                authenticatorAttachmentRequirementLookupStrategy.apply(profileRequestContext);
+        log.trace("{} AuthenticatorAttachment is '{}'",getLogPrefix(), 
+                attachment != null ? attachment : "ANY");
+        context.setAuthenticatorAttachmentRequirement(attachment);
         
     }
 
diff --git a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/AddResidentKeyRequirement.java b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/AddResidentKeyRequirement.java
index 9c202a8..22514e4 100644
--- a/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/AddResidentKeyRequirement.java
+++ b/webauthn-impl/src/main/java/net/shibboleth/idp/plugin/authn/webauthn/admin/impl/AddResidentKeyRequirement.java
@@ -14,9 +14,11 @@
 
 package net.shibboleth.idp.plugin.authn.webauthn.admin.impl;
 
+import java.util.function.Function;
 import java.util.stream.Stream;
 
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 
 import org.opensaml.messaging.context.navigate.ChildContextLookup;
 import org.opensaml.profile.context.ProfileRequestContext;
@@ -26,9 +28,8 @@ import com.yubico.webauthn.data.ResidentKeyRequirement;
 
 import net.shibboleth.idp.plugin.authn.webauthn.context.WebAuthnRegistrationContext;
 import net.shibboleth.idp.plugin.authn.webauthn.impl.AbstractWebAuthnAction;
-import net.shibboleth.shared.annotation.constraint.NotEmpty;
-import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.logic.FunctionSupport;
 import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
@@ -42,13 +43,14 @@ public class AddResidentKeyRequirement extends AbstractWebAuthnAction<WebAuthnRe
     /** Class logger. */
     @Nonnull private final Logger log = LoggerFactory.getLogger(AddResidentKeyRequirement.class);
     
-    /** Set the ResidentKey requirement. Default is PREFERRED.*/
-    @Nonnull private ResidentKeyRequirement residentKeyRequirement;
+    /** A strategy to lookup the ResidentKey requirement. Default is PREFERRED. */
+    @Nonnull private 
+    Function<ProfileRequestContext, ResidentKeyRequirement> residentKeyRequirementLookupStrategy;
     
     /** Constructor.*/
     public AddResidentKeyRequirement() {
         super(new ChildContextLookup<>(WebAuthnRegistrationContext.class));
-        residentKeyRequirement = ResidentKeyRequirement.PREFERRED;
+        residentKeyRequirementLookupStrategy = FunctionSupport.constant(ResidentKeyRequirement.PREFERRED);
     }
     
     /**
@@ -56,26 +58,40 @@ public class AddResidentKeyRequirement extends AbstractWebAuthnAction<WebAuthnRe
      * 
      * @param requirement The ResidentKey requirement to set.
      */
-    public void setResidentKeyRequirement(@Nonnull @NotEmpty final String requirement) {
+    public void setResidentKeyRequirement(@Nullable final String requirement) {
         checkSetterPreconditions();
-        Constraint.isNotEmpty(requirement, "ResidentKey requirement can not be null or empty");
-        
+        if (requirement == null) {
+            return;
+        }        
         final ResidentKeyRequirement uvRequirement = 
                 Stream.of(ResidentKeyRequirement.values())
                 .filter(rk -> rk.getValue().equals(requirement))
                 .findAny()
                 .orElseThrow(() -> new ConstraintViolationException("ResidentKey requirement "+requirement+" unknown"));
         assert uvRequirement != null;
-        residentKeyRequirement = uvRequirement;
+        residentKeyRequirementLookupStrategy = FunctionSupport.constant(uvRequirement);
+    }
+    
+    /**
+     * Set the lookup strategy to determine the ResidentKey requirement. 
+     * 
+     * @param strategy The resident key requirement lookup strategy to set.
+     */
+    public void setResidentKeyRequirementLookupStrategy(
+            @Nullable final Function<ProfileRequestContext, ResidentKeyRequirement> strategy) {
+        checkSetterPreconditions();
+        if (strategy != null) {
+            residentKeyRequirementLookupStrategy = strategy;
+        }
     }
     
     /** {@inheritDoc} */
     @Override
     protected void doExecute(final ProfileRequestContext profileRequestContext, 
             final WebAuthnRegistrationContext context) {
-
-        log.trace("{} ResidentKey requirement is '{}'",getLogPrefix(), residentKeyRequirement);
-        context.setResidentKeyRequirement(residentKeyRequirement);
+        final ResidentKeyRequirement requirement = residentKeyRequirementLookupStrategy.apply(profileRequestContext);
+        log.trace("{} ResidentKey requirement is '{}'",getLogPrefix(), requirement);
+        context.setResidentKeyRequirement(requirement);
         
     }
 
diff --git a/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-beans.xml b/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-beans.xml
index 3b588ef..7ebf419 100644
--- a/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-beans.xml
+++ b/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-beans.xml
@@ -107,15 +107,18 @@
     
     <bean id="AddAttestationConveyancePreference" scope="prototype" parent="AbstractWebAuthnRegistrationAction"
         class="net.shibboleth.idp.plugin.authn.webauthn.admin.impl.AddAttestationConveyancePreference"
-        p:attestationConveyancePreference="%{idp.authn.webauthn.registration.attestationConveyancePreference:none}"/>
+        p:attestationConveyancePreference="#{getObject('shibboleth.authn.WebAuthn.AttestationConveyancePreferenceLookupStrategy') == null ? '%{idp.authn.webauthn.registration.attestationConveyancePreference:none}' : null}"
+        p:attestationConveyancePreferenceLookupStrategy="#{getObject('shibboleth.authn.WebAuthn.AttestationConveyancePreferenceLookupStrategy')}"/>
 
     <bean id="AddResidentKeyRequirement" scope="prototype" parent="AbstractWebAuthnRegistrationAction"
         class="net.shibboleth.idp.plugin.authn.webauthn.admin.impl.AddResidentKeyRequirement"
-        p:residentKeyRequirement="%{idp.authn.webauthn.registration.residentKey:preferred}" />
+        p:residentKeyRequirement="#{getObject('shibboleth.authn.WebAuthn.ResidentKeyRequirementLookupStrategy') == null ? '%{idp.authn.webauthn.registration.residentKey:preferred}' : null}"
+        p:residentKeyRequirementLookupStrategy="#{getObject('shibboleth.authn.WebAuthn.ResidentKeyRequirementLookupStrategy')}" />
 
     <bean id="AddAuthenticatorAttachmentRequirement" scope="prototype" parent="AbstractWebAuthnRegistrationAction"
         class="net.shibboleth.idp.plugin.authn.webauthn.admin.impl.AddAuthenticatorAttachmentRequirement"
-        p:authenticatorAttachmentRequirement="%{idp.authn.webauthn.registration.authenticatorAttachment:any}" />
+        p:authenticatorAttachmentRequirement="#{getObject('shibboleth.authn.WebAuthn.AuthenticatorAttachmentRequirementLookupStrategy') == null ? '%{idp.authn.webauthn.registration.authenticatorAttachment:any}' : null}" 
+        p:authenticatorAttachmentRequirementLookupStrategy="#{getObject('shibboleth.authn.WebAuthn.AuthenticatorAttachmentRequirementLookupStrategy')}"/>
 
     <bean id="AddUserVerificationRequired" parent="AbstractWebAuthnBaseAction"
         class="net.shibboleth.idp.plugin.authn.webauthn.impl.AddUserVerificationRequirement" scope="prototype"

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list