Exchange Enum type of Format for String (#30875)
closes #30873 Signed-off-by: Pascal Knüppel <pascal.knueppel@governikus.de>
This commit is contained in:
parent
4970a9b729
commit
96234d42cf
10 changed files with 40 additions and 75 deletions
|
@ -99,7 +99,7 @@ public class OID4VCLoginProtocolFactory implements LoginProtocolFactory, OID4VCE
|
|||
return builtins;
|
||||
}
|
||||
|
||||
private void addServiceFromComponent(Map<Format, VerifiableCredentialsSigningService> signingServices, KeycloakSession keycloakSession, ComponentModel componentModel) {
|
||||
private void addServiceFromComponent(Map<String, VerifiableCredentialsSigningService> signingServices, KeycloakSession keycloakSession, ComponentModel componentModel) {
|
||||
ProviderFactory<VerifiableCredentialsSigningService> factory = keycloakSession
|
||||
.getKeycloakSessionFactory()
|
||||
.getProviderFactory(VerifiableCredentialsSigningService.class, componentModel.getProviderId());
|
||||
|
@ -114,7 +114,7 @@ public class OID4VCLoginProtocolFactory implements LoginProtocolFactory, OID4VCE
|
|||
@Override
|
||||
public Object createProtocolEndpoint(KeycloakSession keycloakSession, EventBuilder event) {
|
||||
|
||||
Map<Format, VerifiableCredentialsSigningService> signingServices = new EnumMap<>(Format.class);
|
||||
Map<String, VerifiableCredentialsSigningService> signingServices = new HashMap<>();
|
||||
RealmModel realm = keycloakSession.getContext().getRealm();
|
||||
realm.getComponentsStream(realm.getId(), VerifiableCredentialsSigningService.class.getName())
|
||||
.forEach(cm -> addServiceFromComponent(signingServices, keycloakSession, cm));
|
||||
|
@ -170,4 +170,4 @@ public class OID4VCLoginProtocolFactory implements LoginProtocolFactory, OID4VCE
|
|||
return PROTOCOL_ID;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,6 +90,10 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.keycloak.protocol.oid4vc.model.Format.JWT_VC;
|
||||
import static org.keycloak.protocol.oid4vc.model.Format.LDP_VC;
|
||||
import static org.keycloak.protocol.oid4vc.model.Format.SD_JWT_VC;
|
||||
|
||||
/**
|
||||
* Provides the (REST-)endpoints required for the OID4VCI protocol.
|
||||
* <p>
|
||||
|
@ -115,13 +119,13 @@ public class OID4VCIssuerEndpoint {
|
|||
// lifespan of the preAuthorizedCodes in seconds
|
||||
private final int preAuthorizedCodeLifeSpan;
|
||||
|
||||
private final Map<Format, VerifiableCredentialsSigningService> signingServices;
|
||||
private final Map<String, VerifiableCredentialsSigningService> signingServices;
|
||||
|
||||
private final boolean isIgnoreScopeCheck;
|
||||
|
||||
public OID4VCIssuerEndpoint(KeycloakSession session,
|
||||
String issuerDid,
|
||||
Map<Format, VerifiableCredentialsSigningService> signingServices,
|
||||
Map<String, VerifiableCredentialsSigningService> signingServices,
|
||||
AppAuthManager.BearerTokenAuthenticator authenticator,
|
||||
ObjectMapper objectMapper, TimeProvider timeProvider, int preAuthorizedCodeLifeSpan) {
|
||||
this.session = session;
|
||||
|
@ -136,7 +140,7 @@ public class OID4VCIssuerEndpoint {
|
|||
|
||||
public OID4VCIssuerEndpoint(KeycloakSession session,
|
||||
String issuerDid,
|
||||
Map<Format, VerifiableCredentialsSigningService> signingServices,
|
||||
Map<String, VerifiableCredentialsSigningService> signingServices,
|
||||
AppAuthManager.BearerTokenAuthenticator authenticator,
|
||||
ObjectMapper objectMapper, TimeProvider timeProvider, int preAuthorizedCodeLifeSpan,
|
||||
boolean isIgnoreScopeCheck) {
|
||||
|
@ -168,7 +172,7 @@ public class OID4VCIssuerEndpoint {
|
|||
throw new BadRequestException(getErrorResponse(ErrorType.INVALID_CREDENTIAL_REQUEST));
|
||||
}
|
||||
SupportedCredentialConfiguration supportedCredentialConfiguration = credentialsMap.get(vcId);
|
||||
Format format = supportedCredentialConfiguration.getFormat();
|
||||
String format = supportedCredentialConfiguration.getFormat();
|
||||
|
||||
// check that the user is allowed to get such credential
|
||||
if (getClientsOfType(supportedCredentialConfiguration.getScope(), format).isEmpty()) {
|
||||
|
@ -303,7 +307,7 @@ public class OID4VCIssuerEndpoint {
|
|||
checkScope(credentialRequestVO);
|
||||
}
|
||||
|
||||
Format requestedFormat = credentialRequestVO.getFormat();
|
||||
String requestedFormat = credentialRequestVO.getFormat();
|
||||
String requestedCredential = credentialRequestVO.getCredentialIdentifier();
|
||||
|
||||
SupportedCredentialConfiguration supportedCredentialConfiguration = Optional
|
||||
|
@ -372,7 +376,7 @@ public class OID4VCIssuerEndpoint {
|
|||
* @param format format of the credential to be created
|
||||
* @return the signed credential
|
||||
*/
|
||||
private Object getCredential(UserSessionModel userSessionModel, String vcType, Format format) {
|
||||
private Object getCredential(UserSessionModel userSessionModel, String vcType, String format) {
|
||||
|
||||
List<OID4VCClient> clients = getClientsOfType(vcType, format);
|
||||
|
||||
|
@ -424,7 +428,7 @@ public class OID4VCIssuerEndpoint {
|
|||
}
|
||||
|
||||
// Return all {@link OID4VCClient}s that support the given type and format
|
||||
private List<OID4VCClient> getClientsOfType(String vcType, Format format) {
|
||||
private List<OID4VCClient> getClientsOfType(String vcType, String format) {
|
||||
LOGGER.debugf("Retrieve all clients of type %s, supporting format %s", vcType, format.toString());
|
||||
|
||||
if (Optional.ofNullable(vcType).filter(type -> !type.isEmpty()).isEmpty()) {
|
||||
|
|
|
@ -74,7 +74,7 @@ public class OID4VCIssuerWellKnownProvider implements WellKnownProvider {
|
|||
public static Map<String, SupportedCredentialConfiguration> getSupportedCredentials(KeycloakSession keycloakSession) {
|
||||
|
||||
RealmModel realm = keycloakSession.getContext().getRealm();
|
||||
List<Format> supportedFormats = realm.getComponentsStream(realm.getId(), VerifiableCredentialsSigningService.class.getName())
|
||||
List<String> supportedFormats = realm.getComponentsStream(realm.getId(), VerifiableCredentialsSigningService.class.getName())
|
||||
.map(cm ->
|
||||
keycloakSession
|
||||
.getKeycloakSessionFactory()
|
||||
|
@ -115,4 +115,4 @@ public class OID4VCIssuerWellKnownProvider implements WellKnownProvider {
|
|||
public static String getCredentialsEndpoint(KeycloakContext context) {
|
||||
return getIssuer(context) + "/protocol/" + OID4VCLoginProtocolFactory.PROTOCOL_ID + "/" + OID4VCIssuerEndpoint.CREDENTIAL_PATH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ import java.util.Optional;
|
|||
*/
|
||||
public class JwtSigningServiceProviderFactory implements VCSigningServiceProviderFactory {
|
||||
|
||||
public static final Format SUPPORTED_FORMAT = Format.JWT_VC;
|
||||
public static final String SUPPORTED_FORMAT = Format.JWT_VC;
|
||||
private static final String HELP_TEXT = "Issues JWT-VCs following the specification of https://identity.foundation/jwt-vc-presentation-profile/.";
|
||||
|
||||
@Override
|
||||
|
@ -83,7 +83,7 @@ public class JwtSigningServiceProviderFactory implements VCSigningServiceProvide
|
|||
}
|
||||
|
||||
@Override
|
||||
public Format supportedFormat() {
|
||||
public String supportedFormat() {
|
||||
return SUPPORTED_FORMAT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ import java.util.Optional;
|
|||
* @author <a href="https://github.com/wistefan">Stefan Wiedemann</a>
|
||||
*/
|
||||
public class LDSigningServiceProviderFactory implements VCSigningServiceProviderFactory {
|
||||
public static final Format SUPPORTED_FORMAT = Format.LDP_VC;
|
||||
public static final String SUPPORTED_FORMAT = Format.LDP_VC;
|
||||
private static final String HELP_TEXT = "Issues Verifiable Credentials in the W3C Data Model, using Linked-Data Proofs. See https://www.w3.org/TR/vc-data-model/";
|
||||
|
||||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||
|
@ -77,8 +77,8 @@ public class LDSigningServiceProviderFactory implements VCSigningServiceProvider
|
|||
}
|
||||
|
||||
@Override
|
||||
public Format supportedFormat() {
|
||||
public String supportedFormat() {
|
||||
return SUPPORTED_FORMAT;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ import java.util.Optional;
|
|||
*/
|
||||
public class SdJwtSigningServiceProviderFactory implements VCSigningServiceProviderFactory {
|
||||
|
||||
public static final Format SUPPORTED_FORMAT = Format.SD_JWT_VC;
|
||||
public static final String SUPPORTED_FORMAT = Format.SD_JWT_VC;
|
||||
private static final String HELP_TEXT = "Issues SD-JWT-VCs following the specification of https://drafts.oauth.net/oauth-sd-jwt-vc/draft-ietf-oauth-sd-jwt-vc.html.";
|
||||
|
||||
@Override
|
||||
|
@ -97,7 +97,7 @@ public class SdJwtSigningServiceProviderFactory implements VCSigningServiceProvi
|
|||
}
|
||||
|
||||
@Override
|
||||
public Format supportedFormat() {
|
||||
public String supportedFormat() {
|
||||
return SUPPORTED_FORMAT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,5 +85,5 @@ public interface VCSigningServiceProviderFactory extends ComponentFactory<Verifi
|
|||
*
|
||||
* @return the format
|
||||
*/
|
||||
Format supportedFormat();
|
||||
}
|
||||
String supportedFormat();
|
||||
}
|
||||
|
|
|
@ -29,18 +29,18 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class CredentialRequest {
|
||||
|
||||
private Format format;
|
||||
private String format;
|
||||
|
||||
@JsonProperty("credential_identifier")
|
||||
private String credentialIdentifier;
|
||||
|
||||
private Proof proof;
|
||||
|
||||
public Format getFormat() {
|
||||
public String getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
public CredentialRequest setFormat(Format format) {
|
||||
public CredentialRequest setFormat(String format) {
|
||||
this.format = format;
|
||||
return this;
|
||||
}
|
||||
|
@ -62,4 +62,4 @@ public class CredentialRequest {
|
|||
this.proof = proof;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,65 +17,26 @@
|
|||
|
||||
package org.keycloak.protocol.oid4vc.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
/**
|
||||
* Enum of supported credential formats
|
||||
*
|
||||
* @author <a href="https://github.com/wistefan">Stefan Wiedemann</a>
|
||||
*/
|
||||
public enum Format {
|
||||
public class Format {
|
||||
|
||||
/**
|
||||
* LD-Credentials {@see https://www.w3.org/TR/vc-data-model/}
|
||||
*/
|
||||
LDP_VC("ldp_vc"),
|
||||
public static final String LDP_VC = "ldp_vc";
|
||||
|
||||
/**
|
||||
* JWT-Credentials {@see https://identity.foundation/jwt-vc-presentation-profile/}
|
||||
*/
|
||||
JWT_VC("jwt_vc"),
|
||||
public static final String JWT_VC = "jwt_vc";
|
||||
|
||||
/**
|
||||
* SD-JWT-Credentials {@see https://drafts.oauth.net/oauth-sd-jwt-vc/draft-ietf-oauth-sd-jwt-vc.html}
|
||||
*/
|
||||
SD_JWT_VC("vc+sd-jwt");
|
||||
public static final String SD_JWT_VC = "vc+sd-jwt";
|
||||
|
||||
private String value;
|
||||
|
||||
Format(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a String into String, as specified in the
|
||||
* <a href="https://download.oracle.com/otndocs/jcp/jaxrs-2_0-fr-eval-spec/index.html">See JAX RS 2.0 Specification, section 3.2, p. 12</a>
|
||||
*/
|
||||
public static Format fromString(String s) {
|
||||
for (Format b : Format.values()) {
|
||||
// using Objects.toString() to be safe if value type non-object type
|
||||
// because types like 'int' etc. will be auto-boxed
|
||||
if (java.util.Objects.toString(b.value).equals(s)) {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unexpected string value '" + s + "'");
|
||||
}
|
||||
|
||||
@Override
|
||||
@JsonValue
|
||||
public String toString() {
|
||||
return String.valueOf(value);
|
||||
}
|
||||
|
||||
@JsonCreator
|
||||
public static Format fromValue(String value) {
|
||||
for (Format b : Format.values()) {
|
||||
if (b.value.equals(value)) {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unexpected value '" + value + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ public class SupportedCredentialConfiguration {
|
|||
private String id;
|
||||
|
||||
@JsonProperty(FORMAT_KEY)
|
||||
private Format format;
|
||||
private String format;
|
||||
|
||||
@JsonProperty(SCOPE_KEY)
|
||||
private String scope;
|
||||
|
@ -85,11 +85,11 @@ public class SupportedCredentialConfiguration {
|
|||
@JsonProperty(CLAIMS_KEY)
|
||||
private Claims claims;
|
||||
|
||||
public Format getFormat() {
|
||||
public String getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
public SupportedCredentialConfiguration setFormat(Format format) {
|
||||
public SupportedCredentialConfiguration setFormat(String format) {
|
||||
this.format = format;
|
||||
return this;
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ public class SupportedCredentialConfiguration {
|
|||
public static SupportedCredentialConfiguration fromDotNotation(String credentialId, Map<String, String> dotNotated) {
|
||||
|
||||
SupportedCredentialConfiguration supportedCredentialConfiguration = new SupportedCredentialConfiguration().setId(credentialId);
|
||||
Optional.ofNullable(dotNotated.get(credentialId + DOT_SEPARATOR + FORMAT_KEY)).map(Format::fromString).ifPresent(supportedCredentialConfiguration::setFormat);
|
||||
Optional.ofNullable(dotNotated.get(credentialId + DOT_SEPARATOR + FORMAT_KEY)).ifPresent(supportedCredentialConfiguration::setFormat);
|
||||
Optional.ofNullable(dotNotated.get(credentialId + DOT_SEPARATOR + VERIFIABLE_CREDENTIAL_TYPE_KEY)).ifPresent(supportedCredentialConfiguration::setVct);
|
||||
Optional.ofNullable(dotNotated.get(credentialId + DOT_SEPARATOR + SCOPE_KEY)).ifPresent(supportedCredentialConfiguration::setScope);
|
||||
Optional.ofNullable(dotNotated.get(credentialId + DOT_SEPARATOR + CRYPTOGRAPHIC_BINDING_METHODS_SUPPORTED_KEY))
|
||||
|
|
Loading…
Reference in a new issue