diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index dcd97aee4..bf4d6c69c 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -134,6 +134,9 @@ value.DOUBLE=Double value.DURATION=Duration value.SPRING_BEAN_ID=Spring Bean ID +value.oidc=OIDC (OpenID Connect) +value.saml=SAML + brand.header.title=Source Management brand.logo-link-label=Shibboleth brand.logo-link-description=Link to Shibboleth Website @@ -221,6 +224,7 @@ label.select-protocol=Select Protocol label.nameid-format=NameID Format label.nameid-formats=NameID Formats label.name-and-entity-id=Name and Entity ID +label.name-and-entity-id-protocol=Name, Entity ID, Protocol label.organization-information=Organization Information label.contact-information=Contact Information label.given-name=Given Name @@ -289,6 +293,9 @@ label.finish-summary-validation=Finished! label.select-entity-id-to-copy=Select the Entity ID to copy label.metadata-source-name-dashboard-display-only=Service Provider Name (Dashboard Display Only) label.new-entity-id=New Entity ID +label.metadata-source-protocol=Identity Protocol +label.select-source-protocol=Select Protocol + label.sections-to-copy=Sections to Copy? label.add-a-new-metadata-resolver=Add a new metadata source label.how-are-you-adding-the-metadata-information=How are you adding the metadata information? @@ -416,6 +423,7 @@ label.remove-empty-entities-descriptors=Remove Empty Entities Descriptors? label.select-metadata-provider-type=Select Metadata Provider Type label.select-metadata-filter-type=Select Metadata Filter Type +label.select-metadata-source-protocol=Select Metadata Source Protocol label.filter-list=Filter List label.common-attributes=Common Attributes label.reloading-attributes=Reloading Attributes @@ -631,6 +639,7 @@ message.session-timeout=An error has occurred while saving. Your session may hav tooltip.entity-id=An entityID is the SAML identifier that uniquely names a service provider. tooltip.service-provider-name=Service Provider Name (Dashboard Display Only) +tooltip.metadata-source-protocol=Identity Protocol tooltip.force-authn=Disallows use (or reuse) of authentication results and login flows that don\u0027t provide a real-time proof of user presence in the login process tooltip.ignore-request-signatures=Whether to skip validation of signatures on requests when dealing with badly broken or incompetently operated services tooltip.service-provider-name-dashboard-display-only=Service Provider Name (Dashboard Display Only) @@ -794,3 +803,58 @@ value.algorithm-cbc-tripledes=CBC (TRIPLEDES) - http://www.w3.org/2001/04/xmlenc message.algorithms-unique=Each algorithm may only be used once. +label.oauth-rp-extensions=OAuth Relying Party Extensions + +label.post-logout-redirect-uris=Post Logout Redirect URIs +tooltip.post-logout-redirect-uris=Each value is defined in an extension element. +label.default-acr-values=Default ACR Values +tooltip.default-acr-values=Each value is defined in an extension element. +label.request-uris=Request URIs +tooltip.request-uris=Each value is defined in an extension element. +label.audience=Audience +tooltip.audience=Each value is defined in an extension element (the element itself is a standard SAML element imported from the Assertion schema).The audience claim is not drawn from any standard, but an extension supported by Shibboleth to control/validate the “resource” parameter used in various OAuth protocol extensions, particularly in the client_credentials grant flow. + +label.client-uri=Client URI +tooltip.client-uri=OPTIONAL. URL of the home page of the Client. The value of this field MUST point to a valid Web page. +label.responseTypes=Response Types +tooltip.response-types=OPTIONAL. JSON array containing a list of the OAuth 2.0 response_type values that the Client is declaring that it will restrict itself to using. If omitted, the default is that the Client will use only the code Response Type. +label.sector-identifier-uri=Sector Identifier URI +tooltip.sector-identifier-uri=OPTIONAL. URL using the https scheme to be used in calculating Pseudonymous Identifiers by the OP. The URL references a file with a single JSON array of redirect_uri values. +label.id-token-encrypted-response-alg=ID Token Encrypted Response Algorithm. +tooltip.id-token-encrypted-response-alg=REQUIRED for encrypting the ID Token issued to this Client. If this is requested, the response will be signed then encrypted. +label.application-type=Application Type +tooltip.application-type=OPTIONAL. Kind of the application. The default, if omitted, is web. The defined values are native or web. +label.token-endpoint-auth-signing-alg=Token Endpoint Auth Signing Algorithm +tooltip.token-endpoint-auth-signing-alg=OPTIONAL. JWS [JWS] alg algorithm [JWA] that MUST be used for signing the JWT [JWT] used to authenticate the Client at the Token Endpoint for the private_key_jwt and client_secret_jwt authentication methods. +label.id-token-encrypted-response-enc=ID Token Encrypted Response Encoding +tooltip.id-token-encrypted-response-enc=OPTIONAL. JWE enc algorithm [JWA] REQUIRED for encrypting the ID Token issued to this Client. +label.require-auth-time=Require Auth Time +tooltip.require-auth-time=OPTIONAL. Boolean value specifying whether the auth_time Claim in the ID Token is REQUIRED. +label.user-info-encrypted-response-enc=User Info Encrypted Response Encoding +tooltip.user-info-encrypted-response-enc=OPTIONAL. JWE enc algorithm [JWA] REQUIRED for encrypting UserInfo Responses. +label.user-info-signed-response-alg=User Info Signed Response Algorithm +tooltip.user-info-signed-response-alg=OPTIONAL. JWS alg algorithm [JWA] REQUIRED for signing UserInfo Responses. +label.user-info-encrypted-response-alg=User Info Encrypted Response Algorithm +tooltip.user-info-encrypted-response-alg=OPTIONAL. JWE [JWE] alg algorithm [JWA] REQUIRED for encrypting UserInfo Responses. +label.grant-types=Grant Types +tooltip.grant-types=OPTIONAL. JSON array containing a list of the OAuth 2.0 Grant Types that the Client is declaring that it will restrict itself to using. +label.software-id=Software ID +tooltip.software-id=Unique identifier of software. +label.request-object-encryption-enc=Requse Object Encryption Encoding +tooltip.request-object-encryption-enc=OPTIONAL. JWE enc algorithm [JWA] the RP is declaring that it may use for encrypting Request Objects sent to the OP. +label.initiate-login-uri=Initiate Login URI +tooltip.initiate-login-uri=OPTIONAL. URI using the https scheme that a third party can use to initiate a login by the RP +label.request-object-encryption-alg=Request Object Encryption Algorithm +tooltip.request-object-encryption-alg=OPTIONAL. JWE [JWE] alg algorithm [JWA] the RP is declaring that it may use for encrypting Request Objects sent to the OP. +label.token-endpoint-auth-method=Token Endpoint Auth Method +tooltip.token-endpoint-auth-method=OPTIONAL. Requested Client Authentication method for the Token Endpoint. +label.request-object-signing-alg=Request Object Signing Algorithm +tooltip.request-object-signing-alg=OPTIONAL. JWS [JWS] alg algorithm [JWA] that MUST be used for signing Request Objects sent to the OP. +label.scopes=Scopes +tooltip.scopes=Multiple-valued claims that map directly into XML Attributes in a metadata extension element. +label.id-token-signed-response-alg=ID Token Signed Response Algorithm +tooltip.id-token-signed-response-alg=OPTIONAL. JWS alg algorithm [JWA] REQUIRED for signing the ID Token issued to this Client. +label.software-version=Software Version +tooltip.software-version=Version of Software +label.default-max-age=Default Max Age +tooltip.default-max-age=Specifies that the End-User MUST be actively authenticated if the End-User was authenticated longer ago than the specified number of seconds. diff --git a/backend/src/main/resources/metadata-sources-ui-schema.json b/backend/src/main/resources/metadata-sources-ui-schema.json index fdb7e5d46..3019b511c 100644 --- a/backend/src/main/resources/metadata-sources-ui-schema.json +++ b/backend/src/main/resources/metadata-sources-ui-schema.json @@ -1,10 +1,24 @@ { "type": "object", "required": [ + "protocol", "serviceProviderName", "entityId" ], "properties": { + "protocol": { + "title": "label.metadata-source-protocol", + "description": "tooltip.metadata-source-protocol", + "type": "string", + "enum": [ + "OIDC", + "SAML" + ], + "enumNames": [ + "value.oidc", + "value.saml" + ] + }, "serviceProviderName": { "title": "label.service-provider-name", "description": "tooltip.service-provider-name", @@ -40,9 +54,6 @@ }, "securityInfo": { "type": "object", - "widget": { - "id": "fieldset" - }, "dependencies": { "authenticationRequestsSigned": { "oneOf": [ diff --git a/ui/public/assets/schema/source/metadata-source-oidc.json b/ui/public/assets/schema/source/metadata-source-oidc.json new file mode 100644 index 000000000..2bfe1f72e --- /dev/null +++ b/ui/public/assets/schema/source/metadata-source-oidc.json @@ -0,0 +1,709 @@ +{ + "type": "object", + "required": ["serviceProviderName", "entityId"], + "properties": { + "protocol": { + "title": "label.source-protocol", + "description": "tooltip.source-protocol", + "type": "string" + }, + "serviceProviderName": { + "title": "label.service-provider-name", + "description": "tooltip.service-provider-name", + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "entityId": { + "title": "label.entity-id", + "description": "tooltip.entity-id", + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "serviceEnabled": { + "title": "label.enable-this-service", + "description": "tooltip.enable-this-service-upon-saving", + "type": "boolean" + }, + "organization": { "$ref": "#/definitions/Organization" }, + "contacts": { + "title": "label.contact-information", + "description": "tooltip.contact-information", + "type": "array", + "items": { "$ref": "#/definitions/Contact" } + }, + "mdui": { "$ref": "#/definitions/MDUI" }, + "securityInfo": { + "type": "object", + "dependencies": { + "authenticationRequestsSigned": { + "oneOf": [ + { + "properties": { + "authenticationRequestsSigned": { + "enum": [true] + }, + "x509Certificates": { "minItems": 1 } + } + }, + { + "properties": { + "authenticationRequestsSigned": { + "enum": [false] + }, + "x509Certificates": { "minItems": 0 } + } + } + ] + } + }, + "properties": { + "authenticationRequestsSigned": { + "title": "label.authentication-requests-signed", + "description": "tooltip.authentication-requests-signed", + "type": "boolean", + "enumNames": ["value.true", "value.false"] + }, + "wantAssertionsSigned": { + "title": "label.want-assertions-signed", + "description": "tooltip.want-assertions-signed", + "type": "boolean", + "enumNames": ["value.true", "value.false"] + }, + "keyDescriptors": { + "title": "label.key-descriptors", + "description": "tooltip.key-descriptors", + "type": "array", + "items": { "$ref": "#/definitions/Certificate" } + } + } + }, + "assertionConsumerServices": { + "title": "label.assertion-consumer-service-endpoints", + "description": "tooltip.assertion-consumer-service-endpoints", + "type": "array", + "items": { "$ref": "#/definitions/AssertionConsumerService" } + }, + "serviceProviderSsoDescriptor": { + "type": "object", + "properties": { + "protocolSupportEnum": { + "title": "label.protocol-support-enumeration", + "description": "tooltip.protocol-support-enumeration", + "type": "string", + "widget": { "id": "select" }, + "oneOf": [ + { "enum": ["SAML 2"], "description": "SAML 2" }, + { "enum": ["SAML 1.1"], "description": "SAML 1.1" }, + { + "enum": [ + "http://openid.net/specs/openid-connect-core-1_0.html" + ], + "description": "OIDC" + } + ] + }, + "nameIdFormats": { "$ref": "#/definitions/nameIdFormats" }, + "extensions": { + "type": "object", + "properties": { + "OAuthRPExtensions": { + "title": "label.oauth-rp-extensions", + "type": "object", + "properties": { + "postLogoutRedirectUris": { + "title": "label.post-logout-redirect-uris", + "description": "tooltip.post-logout-redirect-uris", + "type": "array", + "items": { + "type": "string" + } + }, + "defaultAcrValues": { + "title": "label.default-acr-values", + "description": "tooltip.default-acr-values", + "type": "array", + "items": { + "type": "string" + } + }, + "requestUris": { + "title": "label.request-uris", + "description": "tooltip.request-uris", + "type": "array", + "items": { + "type": "string" + } + }, + "audience": { + "title": "label.audience", + "description": "tooltip.audience", + "type": "array", + "items": { + "type": "string" + } + }, + "attributes": { + "type": "object", + "properties": { + "clientUri": { + "title": "label.client-uri", + "description": "tooltip.client-uri", + "type": "string" + }, + "responseTypes": { + "title": "label.responseTypes", + "description": "tooltip.response-types", + "type": "string" + }, + "sectorIdentifierUri": { + "title": "label.sector-identifier-uri", + "description": "tooltip.sector-identifier-uri", + "type": "string" + }, + "idTokenEncryptedResponseAlg": { + "title": "label.id-token-encrypted-response-alg", + "description": "tooltip.id-token-encrypted-response-alg", + "type": "string" + }, + "applicationType": { + "title": "label.application-type", + "description": "tooltip.application-type", + "type": "string" + }, + "tokenEndpointAuthSigningAlg": { + "title": "label.token-endpoint-auth-signing-alg", + "description": "tooltip.token-endpoint-auth-signing-alg", + "type": "string" + }, + "idTokenEncryptedResponseEnc": { + "title": "label.id-token-encrypted-response-enc", + "description": "tooltip.id-token-encrypted-response-enc", + "type": "string" + }, + "requireAuthTime": { + "title": "label.require-auth-time", + "description": "tooltip.require-auth-time", + "type": "boolean" + }, + "userInfoEncryptedResponseEnc": { + "title": "label.user-info-encrypted-response-enc", + "description": "tooltip.user-info-encrypted-response-enc", + "type": "string" + }, + "userInfoSignedResponseAlg": { + "title": "label.user-info-signed-response-alg", + "description": "tooltip.user-info-signed-response-alg", + "type": "string" + }, + "userInfoEncryptedResponseAlg": { + "title": "label.user-info-encrypted-response-alg", + "description": "tooltip.user-info-encrypted-response-alg", + "type": "string" + }, + "grantTypes": { + "title": "label.grant-types", + "description": "tooltip.grant-types", + "type": "string" + }, + "softwareId": { + "title": "label.software-id", + "description": "tooltip.software-id", + "type": "string" + }, + "requestObjectEncryptionEnc": { + "title": "label.request-object-encryption-enc", + "description": "tooltip.request-object-encryption-enc", + "type": "string" + }, + "initiateLoginUri": { + "title": "label.initiate-login-uri", + "description": "tooltip.initiate-login-uri", + "type": "string" + }, + "requestObjectEncryptionAlg": { + "title": "label.request-object-encryption-alg", + "description": "tooltip.request-object-encryption-alg", + "type": "string" + }, + "tokenEndpointAuthMethod": { + "title": "label.token-endpoint-auth-method", + "description": "tooltip.token-endpoint-auth-method", + "type": "string" + }, + "requestObjectSigningAlg": { + "title": "label.request-object-signing-alg", + "description": "tooltip.request-object-signing-alg", + "type": "string" + }, + "scopes": { + "title": "label.scopes", + "description": "tooltip.scopes", + "type": "string" + }, + "idTokenSignedResponseAlg": { + "title": "label.id-token-signed-response-alg", + "description": "tooltip.id-token-signed-response-alg", + "type": "string" + }, + "softwareVersion": { + "title": "label.software-version", + "description": "tooltip.software-version", + "type": "string" + }, + "defaultMaxAge": { + "title": "label.default-max-age", + "description": "tooltip.default-max-age", + "type": "number" + } + } + } + } + } + } + } + } + }, + "logoutEndpoints": { + "title": "label.logout-endpoints", + "description": "tooltip.logout-endpoints", + "type": "array", + "items": { "$ref": "#/definitions/LogoutEndpoint" } + }, + "relyingPartyOverrides": { + "type": "object", + "properties": { + "signAssertion": { + "title": "label.sign-the-assertion", + "description": "tooltip.sign-assertion", + "type": "boolean", + "default": false + }, + "nameIdFormats": { "$ref": "#/definitions/nameIdFormats" }, + "responderId": { + "title": "label.responder-id", + "description": "tooltip.responder-id", + "type": "string" + }, + "authenticationMethods": { + "$ref": "#/definitions/authenticationMethods" + }, + "ignoreRequestSignatures": { + "title": "label.ignore-request-signatures", + "description": "tooltip.ignore-request-signatures", + "type": "boolean", + "default": false + }, + "turnOffEncryption": { + "title": "label.turn-off-encryption-of-response", + "description": "tooltip.turn-off-encryption", + "type": "boolean", + "default": false + }, + "forceAuthn": { + "title": "label.force-authn", + "description": "tooltip.force-authn", + "type": "boolean", + "default": false + }, + "dontSignResponse": { + "title": "label.dont-sign-the-response", + "description": "tooltip.dont-sign-response", + "type": "boolean", + "default": false + }, + "ignoreAuthenticationMethod": { + "title": "label.ignore-any-sp-requested-authentication-method", + "description": "tooltip.ignore-auth-method", + "type": "boolean", + "default": false + }, + "useSha": { + "title": "label.use-sha1-signing-algorithm", + "description": "tooltip.usa-sha-algorithm", + "type": "boolean", + "default": false + }, + "omitNotBefore": { + "title": "label.omit-not-before-condition", + "description": "tooltip.omit-not-before-condition", + "type": "boolean", + "default": false + } + } + }, + "attributeRelease": { + "type": "array", + "title": "label.attribute-release", + "description": "Attribute release table - select the attributes you want to release (default unchecked)", + "items": { + "type": "string", + "enum": [ + "eduPersonPrincipalName", + "uid", + "mail", + "surname", + "givenName", + "eduPersonAffiliation", + "eduPersonScopedAffiliation", + "eduPersonPrimaryAffiliation", + "eduPersonEntitlement", + "eduPersonAssurance", + "eduPersonUniqueId", + "employeeNumber" + ], + "enumNames": [ + "label.attribute-eduPersonPrincipalName", + "label.attribute-uid", + "label.attribute-mail", + "label.attribute-surname", + "label.attribute-givenName", + "label.attribute-eduPersonAffiliation", + "label.attribute-eduPersonScopedAffiliation", + "label.attribute-eduPersonPrimaryAffiliation", + "label.attribute-eduPersonEntitlement", + "label.attribute-eduPersonAssurance", + "label.attribute-eduPersonUniqueId", + "label.attribute-employeeNumber" + ] + }, + "uniqueItems": true + } + }, + "definitions": { + "Contact": { + "type": "object", + "required": ["name", "type", "emailAddress"], + "properties": { + "name": { + "title": "label.contact-name", + "description": "tooltip.contact-name", + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "type": { + "title": "label.contact-type", + "description": "tooltip.contact-type", + "type": "string", + "widget": "select", + "minLength": 1, + "oneOf": [ + { "enum": ["support"], "description": "value.support" }, + { + "enum": ["technical"], + "description": "value.technical" + }, + { + "enum": ["administrative"], + "description": "value.administrative" + }, + { "enum": ["other"], "description": "value.other" } + ] + }, + "emailAddress": { + "title": "label.contact-email-address", + "description": "tooltip.contact-email", + "type": "string", + "pattern": "^(mailto:)?(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$", + "minLength": 1, + "maxLength": 255 + } + } + }, + "Certificate": { + "type": "object", + "required": ["type", "value", "elementType"], + "properties": { + "name": { + "title": "label.certificate-name-display-only", + "description": "tooltip.certificate-name", + "type": "string", + "maxLength": 255 + }, + "elementType": { + "title": "label.element-type", + "description": "tooltip.element-type", + "type": "string", + "enum": [ + "X509Data", + "jwksUri", + "jwksData", + "clientSecret", + "clientSecretRef" + ] + }, + "type": { + "title": "label.certificate-type", + "type": "string", + "widget": { "id": "radio", "class": "form-check-inline" }, + "oneOf": [ + { "enum": ["signing"], "description": "value.signing" }, + { + "enum": ["encryption"], + "description": "value.encryption" + }, + { "enum": ["both"], "description": "value.both" } + ] + }, + "value": { + "title": "label.certificate-value", + "description": "tooltip.certificate-value", + "type": "string", + "widget": "textarea", + "minLength": 1 + } + } + }, + "AssertionConsumerService": { + "type": "object", + "required": ["locationUrl", "binding"], + "properties": { + "locationUrl": { + "title": "label.assertion-consumer-service-location", + "description": "tooltip.assertion-consumer-service-location", + "type": "string", + "widget": { "id": "string", "help": "message.valid-url" }, + "minLength": 1, + "maxLength": 255 + }, + "binding": { + "title": "label.assertion-consumer-service-location-binding", + "description": "tooltip.assertion-consumer-service-location-binding", + "type": "string", + "widget": "select", + "oneOf": [ + { + "enum": [ + "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" + ], + "description": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" + }, + { + "enum": [ + "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" + ], + "description": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" + }, + { + "enum": [ + "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" + ], + "description": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" + }, + { + "enum": [ + "urn:oasis:names:tc:SAML:2.0:bindings:PAOS" + ], + "description": "urn:oasis:names:tc:SAML:2.0:bindings:PAOS" + }, + { + "enum": [ + "urn:oasis:names:tc:SAML:1.0:profiles:browser-post" + ], + "description": "urn:oasis:names:tc:SAML:1.0:profiles:browser-post" + }, + { + "enum": [ + "urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" + ], + "description": "urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" + }, + { + "enum": [ + "https://tools.ietf.org/html/rfc6749#section-3.1.2" + ], + "description": "https://tools.ietf.org/html/rfc6749#section-3.1.2" + } + ] + }, + "makeDefault": { + "title": "label.mark-as-default", + "description": "tooltip.mark-as-default", + "type": "boolean" + } + } + }, + "LogoutEndpoint": { + "description": "tooltip.new-endpoint", + "type": "object", + "fieldsets": [{ "fields": ["url", "bindingType"] }], + "required": ["url", "bindingType"], + "properties": { + "url": { + "title": "label.url", + "description": "tooltip.url", + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "bindingType": { + "title": "label.binding-type", + "description": "tooltip.binding-type", + "type": "string", + "widget": "select", + "oneOf": [ + { + "enum": [ + "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" + ], + "description": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" + }, + { + "enum": [ + "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" + ], + "description": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" + }, + { + "enum": [ + "urn:oasis:names:tc:SAML:2.0:bindings:SOAP" + ], + "description": "urn:oasis:names:tc:SAML:2.0:bindings:SOAP" + }, + { + "enum": [ + "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" + ], + "description": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" + } + ] + } + } + }, + "MDUI": { + "type": "object", + "widget": { "id": "fieldset" }, + "fieldsets": [ + { + "type": "group", + "fields": ["displayName", "informationUrl", "description"] + }, + { + "type": "group", + "fields": [ + "privacyStatementUrl", + "logoUrl", + "logoWidth", + "logoHeight" + ] + } + ], + "properties": { + "displayName": { + "title": "label.display-name", + "description": "tooltip.mdui-display-name", + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "informationUrl": { + "title": "label.information-url", + "description": "tooltip.mdui-information-url", + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "privacyStatementUrl": { + "title": "label.privacy-statement-url", + "description": "tooltip.mdui-privacy-statement-url", + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "description": { + "title": "label.description", + "description": "tooltip.mdui-description", + "type": "string", + "widget": { "id": "textarea" }, + "minLength": 1, + "maxLength": 255 + }, + "logoUrl": { + "title": "label.logo-url", + "description": "tooltip.mdui-logo-url", + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "logoHeight": { + "title": "label.logo-height", + "description": "tooltip.mdui-logo-height", + "minimum": 0, + "type": "integer" + }, + "logoWidth": { + "title": "label.logo-width", + "description": "tooltip.mdui-logo-width", + "minimum": 0, + "type": "integer" + } + } + }, + "Organization": { + "type": "object", + "properties": { + "name": { + "title": "label.organization-name", + "description": "tooltip.organization-name", + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "displayName": { + "title": "label.organization-display-name", + "description": "tooltip.organization-display-name", + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "url": { + "title": "label.organization-url", + "description": "tooltip.organization-url", + "type": "string", + "minLength": 1, + "maxLength": 255 + } + }, + "dependencies": { + "name": { "required": ["displayName", "url"] }, + "displayName": { "required": ["name", "url"] }, + "url": { "required": ["name", "displayName"] } + } + }, + "nameIdFormats": { + "title": "label.nameid-format-to-send", + "description": "tooltip.nameid-format", + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "examples": [ + "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified", + "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", + "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "urn:oasis:names:tc:SAML:2.0:nameid-format:transient" + ] + } + }, + "authenticationMethods": { + "title": "label.authentication-methods-to-use", + "description": "tooltip.authentication-methods-to-use", + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "examples": [ + "https://refeds.org/profile/mfa", + "urn:oasis:names:tc:SAML:2.0:ac:classes:TimeSyncToken", + "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport" + ] + } + } + } +} diff --git a/ui/public/assets/schema/source/metadata-source.json b/ui/public/assets/schema/source/metadata-source-saml.json similarity index 75% rename from ui/public/assets/schema/source/metadata-source.json rename to ui/public/assets/schema/source/metadata-source-saml.json index 7348000d7..44bc9b963 100644 --- a/ui/public/assets/schema/source/metadata-source.json +++ b/ui/public/assets/schema/source/metadata-source-saml.json @@ -1,10 +1,12 @@ { "type": "object", - "required": [ - "serviceProviderName", - "entityId" - ], + "required": ["serviceProviderName", "entityId"], "properties": { + "protocol": { + "title": "label.source-protocol", + "description": "tooltip.source-protocol", + "type": "string" + }, "serviceProviderName": { "title": "label.service-provider-name", "description": "tooltip.service-provider-name", @@ -24,93 +26,79 @@ "description": "tooltip.enable-this-service-upon-saving", "type": "boolean" }, - "organization": { - "$ref": "#/definitions/Organization" - }, + "organization": { "$ref": "#/definitions/Organization" }, "contacts": { "title": "label.contact-information", "description": "tooltip.contact-information", "type": "array", - "items": { - "$ref": "#/definitions/Contact" - } + "items": { "$ref": "#/definitions/Contact" } }, - "mdui": { - "$ref": "#/definitions/MDUI" + "mdui": { "$ref": "#/definitions/MDUI" }, + "dependencies": { + "securityInfo": { + "oneOf": [ + { + "properties": { + "@type": { + "enum": [ + "OIDC" + ] + } + } + } + ] + } }, "securityInfo": { "type": "object", - "widget": { - "id": "fieldset" - }, "dependencies": { "authenticationRequestsSigned": { "oneOf": [ { "properties": { "authenticationRequestsSigned": { - "enum": [ - true - ] + "enum": [true] }, - "x509Certificates": { - "minItems": 1 - } + "keyDescriptors": { "minItems": 1 } } }, { "properties": { "authenticationRequestsSigned": { - "enum": [ - false - ] + "enum": [false] }, - "x509Certificates": { - "minItems": 0 - } + "keyDescriptors": { "minItems": 0 } } } ] } }, "properties": { - "x509CertificateAvailable": { - "type": "boolean" - }, "authenticationRequestsSigned": { "title": "label.authentication-requests-signed", "description": "tooltip.authentication-requests-signed", "type": "boolean", - "enumNames": [ - "value.true", - "value.false" - ] + "enumNames": ["value.true", "value.false"] }, "wantAssertionsSigned": { "title": "label.want-assertions-signed", "description": "tooltip.want-assertions-signed", "type": "boolean", - "enumNames": [ - "value.true", - "value.false" - ] + "enumNames": ["value.true", "value.false"] }, - "x509Certificates": { - "title": "label.x509-certificates", + "keyDescriptors": { + "title": "label.key-descriptors", + "description": "tooltip.key-descriptors", "type": "array", - "items": { - "$ref": "#/definitions/Certificate" - } + "items": { "$ref": "#/definitions/Certificate" } } } }, "assertionConsumerServices": { "title": "label.assertion-consumer-service-endpoints", - "description": "", + "description": "tooltip.assertion-consumer-service-endpoints", "type": "array", - "items": { - "$ref": "#/definitions/AssertionConsumerService" - } + "items": { "$ref": "#/definitions/AssertionConsumerService" } }, "serviceProviderSsoDescriptor": { "type": "object", @@ -119,36 +107,20 @@ "title": "label.protocol-support-enumeration", "description": "tooltip.protocol-support-enumeration", "type": "string", - "widget": { - "id": "select" - }, + "widget": { "id": "select" }, "oneOf": [ - { - "enum": [ - "SAML 2" - ], - "description": "SAML 2" - }, - { - "enum": [ - "SAML 1.1" - ], - "description": "SAML 1.1" - } + { "enum": ["SAML 2"], "description": "SAML 2" }, + { "enum": ["SAML 1.1"], "description": "SAML 1.1" } ] }, - "nameIdFormats": { - "$ref": "#/definitions/nameIdFormats" - } + "nameIdFormats": { "$ref": "#/definitions/nameIdFormats" } } }, "logoutEndpoints": { "title": "label.logout-endpoints", "description": "tooltip.logout-endpoints", "type": "array", - "items": { - "$ref": "#/definitions/LogoutEndpoint" - } + "items": { "$ref": "#/definitions/LogoutEndpoint" } }, "relyingPartyOverrides": { "type": "object", @@ -159,9 +131,7 @@ "type": "boolean", "default": false }, - "nameIdFormats": { - "$ref": "#/definitions/nameIdFormats" - }, + "nameIdFormats": { "$ref": "#/definitions/nameIdFormats" }, "responderId": { "title": "label.responder-id", "description": "tooltip.responder-id", @@ -170,6 +140,12 @@ "authenticationMethods": { "$ref": "#/definitions/authenticationMethods" }, + "ignoreRequestSignatures": { + "title": "label.ignore-request-signatures", + "description": "tooltip.ignore-request-signatures", + "type": "boolean", + "default": false + }, "turnOffEncryption": { "title": "label.turn-off-encryption-of-response", "description": "tooltip.turn-off-encryption", @@ -194,12 +170,6 @@ "type": "boolean", "default": false }, - "ignoreRequestSignatures": { - "title": "label.ignore-request-signatures", - "description": "tooltip.ignore-request-signatures", - "type": "boolean", - "default": false - }, "useSha": { "title": "label.use-sha1-signing-algorithm", "description": "tooltip.usa-sha-algorithm", @@ -221,18 +191,6 @@ "items": { "type": "string", "enum": [ - [ - "givenName", - "eduPersonAffiliation", - "eduPersonScopedAffiliation", - "employeeNumber" - ], - [ - "uid", - "surname", - "eduPersonAffiliation", - "employeeNumber" - ], "eduPersonPrincipalName", "uid", "mail", @@ -247,8 +205,18 @@ "employeeNumber" ], "enumNames": [ - "Bundle 1", - "Bundle 2" + "label.attribute-eduPersonPrincipalName", + "label.attribute-uid", + "label.attribute-mail", + "label.attribute-surname", + "label.attribute-givenName", + "label.attribute-eduPersonAffiliation", + "label.attribute-eduPersonScopedAffiliation", + "label.attribute-eduPersonPrimaryAffiliation", + "label.attribute-eduPersonEntitlement", + "label.attribute-eduPersonAssurance", + "label.attribute-eduPersonUniqueId", + "label.attribute-employeeNumber" ] }, "uniqueItems": true @@ -257,11 +225,7 @@ "definitions": { "Contact": { "type": "object", - "required": [ - "name", - "type", - "emailAddress" - ], + "required": ["name", "type", "emailAddress"], "properties": { "name": { "title": "label.contact-name", @@ -277,30 +241,16 @@ "widget": "select", "minLength": 1, "oneOf": [ + { "enum": ["support"], "description": "value.support" }, { - "enum": [ - "support" - ], - "description": "value.support" - }, - { - "enum": [ - "technical" - ], + "enum": ["technical"], "description": "value.technical" }, { - "enum": [ - "administrative" - ], + "enum": ["administrative"], "description": "value.administrative" }, - { - "enum": [ - "other" - ], - "description": "value.other" - } + { "enum": ["other"], "description": "value.other" } ] }, "emailAddress": { @@ -315,10 +265,7 @@ }, "Certificate": { "type": "object", - "required": [ - "type", - "value" - ], + "required": ["type", "value"], "properties": { "name": { "title": "label.certificate-name-display-only", @@ -326,32 +273,23 @@ "type": "string", "maxLength": 255 }, + "elementType": { + "title": "label.element-type", + "description": "tooltip.element-type", + "type": "string", + "default": "X509Data" + }, "type": { "title": "label.certificate-type", "type": "string", - "widget": { - "id": "radio", - "class": "form-check-inline" - }, + "widget": { "id": "radio", "class": "form-check-inline" }, "oneOf": [ + { "enum": ["signing"], "description": "value.signing" }, { - "enum": [ - "signing" - ], - "description": "value.signing" - }, - { - "enum": [ - "encryption" - ], + "enum": ["encryption"], "description": "value.encryption" }, - { - "enum": [ - "both" - ], - "description": "value.both" - } + { "enum": ["both"], "description": "value.both" } ] }, "value": { @@ -365,19 +303,13 @@ }, "AssertionConsumerService": { "type": "object", - "required": [ - "locationUrl", - "binding" - ], + "required": ["locationUrl", "binding"], "properties": { "locationUrl": { "title": "label.assertion-consumer-service-location", "description": "tooltip.assertion-consumer-service-location", "type": "string", - "widget": { - "id": "string", - "help": "message.valid-url" - }, + "widget": { "id": "string", "help": "message.valid-url" }, "minLength": 1, "maxLength": 255 }, @@ -435,18 +367,8 @@ "LogoutEndpoint": { "description": "tooltip.new-endpoint", "type": "object", - "fieldsets": [ - { - "fields": [ - "url", - "bindingType" - ] - } - ], - "required": [ - "url", - "bindingType" - ], + "fieldsets": [{ "fields": ["url", "bindingType"] }], + "required": ["url", "bindingType"], "properties": { "url": { "title": "label.url", @@ -491,17 +413,11 @@ }, "MDUI": { "type": "object", - "widget": { - "id": "fieldset" - }, + "widget": { "id": "fieldset" }, "fieldsets": [ { "type": "group", - "fields": [ - "displayName", - "informationUrl", - "description" - ] + "fields": ["displayName", "informationUrl", "description"] }, { "type": "group", @@ -539,9 +455,7 @@ "title": "label.description", "description": "tooltip.mdui-description", "type": "string", - "widget": { - "id": "textarea" - }, + "widget": { "id": "textarea" }, "minLength": 1, "maxLength": 255 }, @@ -592,24 +506,9 @@ } }, "dependencies": { - "name": { - "required": [ - "displayName", - "url" - ] - }, - "displayName": { - "required": [ - "name", - "url" - ] - }, - "url": { - "required": [ - "name", - "displayName" - ] - } + "name": { "required": ["displayName", "url"] }, + "displayName": { "required": ["name", "url"] }, + "url": { "required": ["name", "displayName"] } } }, "nameIdFormats": { diff --git a/ui/src/app/form/component/templates/ArrayFieldTemplate.js b/ui/src/app/form/component/templates/ArrayFieldTemplate.js index 598986589..947dcebfc 100644 --- a/ui/src/app/form/component/templates/ArrayFieldTemplate.js +++ b/ui/src/app/form/component/templates/ArrayFieldTemplate.js @@ -65,7 +65,7 @@ const CustomToggle = ({children, eventKey, type, callback}) => { const isCurrentEventKey = activeEventKey === eventKey; return ( - @@ -74,7 +74,7 @@ const CustomToggle = ({children, eventKey, type, callback}) => { const ObjectArrayItem = ({type, ...props}) => { - const btnStyle = { + const btnStyle = { flex: 1, paddingLeft: 6, paddingRight: 6, @@ -82,10 +82,10 @@ const ObjectArrayItem = ({type, ...props}) => { }; return (
- +
- + {props.hasToolbar && ( @@ -135,7 +135,7 @@ const ObjectArrayItem = ({type, ...props}) => {
)}
- +
{props.children}
diff --git a/ui/src/app/metadata/Metadata.js b/ui/src/app/metadata/Metadata.js index 89b8a4bc5..604156d8d 100644 --- a/ui/src/app/metadata/Metadata.js +++ b/ui/src/app/metadata/Metadata.js @@ -21,7 +21,7 @@ export function Metadata () { {(entity, reload) => - + diff --git a/ui/src/app/metadata/copy/CopySource.js b/ui/src/app/metadata/copy/CopySource.js index d7d0be54a..60e866d7e 100644 --- a/ui/src/app/metadata/copy/CopySource.js +++ b/ui/src/app/metadata/copy/CopySource.js @@ -11,8 +11,6 @@ import kebabCase from 'lodash/kebabCase'; import { useMetadataSources } from '../hooks/api'; import { useMetadataSourceSections } from '../domain/source/definition/SourceDefinition'; - - export function CopySource({ copy, onNext }) { const { data = [] } = useMetadataSources({ cachePolicy: 'no-cache' }, []); diff --git a/ui/src/app/metadata/domain/index.js b/ui/src/app/metadata/domain/index.js index 17c57d4c6..89b7b1584 100644 --- a/ui/src/app/metadata/domain/index.js +++ b/ui/src/app/metadata/domain/index.js @@ -4,14 +4,14 @@ import { MetadataProviderEditorTypes, MetadataProviderWizardTypes } from './prov import { DynamicHttpMetadataProviderEditor } from './provider/definition/DynamicHttpMetadataProviderDefinition'; import { FileBackedHttpMetadataProviderEditor } from './provider/definition/FileBackedHttpMetadataProviderDefinition'; import { LocalDynamicMetadataProviderEditor } from './provider/definition/LocalDynamicMetadataProviderDefinition'; -import { SourceEditor, SourceWizard } from "./source/definition/SourceDefinition"; +import { MetadataSourceEditorTypes, MetadataSourceWizardTypes } from "./source"; export const editors = { - source: SourceEditor + ...MetadataSourceEditorTypes }; export const wizards = { - source: SourceWizard + ...MetadataSourceWizardTypes }; export const ProviderEditorTypes = [ @@ -37,10 +37,10 @@ export const FilterableProviders = [ export const getWizard = (type) => ProviderWizardTypes.find(def => def.type === type) || FilterEditorTypes.find(def => def.type === type) || - SourceWizard; + wizards[type]; export const getDefinition = (type) => typeof type === 'string' ? ProviderEditorTypes.find(def => def.type === type) || FilterEditorTypes.find(def => def.type === type) || - SourceEditor : type; \ No newline at end of file + editors[type] : type; \ No newline at end of file diff --git a/ui/src/app/metadata/domain/source/definition/OidcSourceDefinition.js b/ui/src/app/metadata/domain/source/definition/OidcSourceDefinition.js new file mode 100644 index 000000000..64cb35f90 --- /dev/null +++ b/ui/src/app/metadata/domain/source/definition/OidcSourceDefinition.js @@ -0,0 +1,83 @@ +import defaultsDeep from 'lodash/defaultsDeep'; +import API_BASE_PATH from '../../../../App.constant'; +import { SourceBase, SourceEditor, SourceWizard } from './SourceDefinition'; + +export const OidcSourceBase = defaultsDeep({ + label: 'OIDC Metadata Source', + type: '@MetadataProvider', + schema: `assets/schema/source/metadata-source-oidc.json`, + uiSchema: defaultsDeep({ + serviceProviderSsoDescriptor: { + ...SourceBase.uiSchema.serviceProviderSsoDescriptor, + layout: { + groups: [ + { + classNames: 'bg-light border rounded px-4 pt-4 mb-4', + size: 6, + fields: [ + 'protocolSupportEnum', + 'nameIdFormats' + ], + }, + { + size: 12, + fields: [ + 'extensions' + ], + } + ] + }, + extensions: { + OAuthRPExtensions: { + layout: { + groups: [ + { + fields: [ + 'postLogoutRedirectUris', + 'defaultAcrValues', + 'requestUris', + 'audience' + ], + }, + { + fields: [ + 'attributes' + ], + } + ] + }, + postLogoutRedirectUris: { + "ui:options": { + orderable: false + }, + }, + defaultAcrValues: { + "ui:options": { + orderable: false + }, + }, + requestUris: { + "ui:options": { + orderable: false + }, + }, + audience: { + "ui:options": { + orderable: false + }, + } + } + } + } + }, SourceBase.uiSchema) +}, SourceBase); + +export const OidcSourceEditor = defaultsDeep({ + ...SourceEditor, +}, OidcSourceBase); + +export const OidcSourceWizard = defaultsDeep({ + ...SourceWizard, +}, OidcSourceBase); + + diff --git a/ui/src/app/metadata/domain/source/definition/SamlSourceDefinition.js b/ui/src/app/metadata/domain/source/definition/SamlSourceDefinition.js new file mode 100644 index 000000000..7279dd2b8 --- /dev/null +++ b/ui/src/app/metadata/domain/source/definition/SamlSourceDefinition.js @@ -0,0 +1,32 @@ +import defaultsDeep from 'lodash/defaultsDeep'; +import API_BASE_PATH from '../../../../App.constant'; +import { SourceBase, SourceEditor, SourceWizard } from './SourceDefinition'; + +export const SamlSourceBase = defaultsDeep({ + label: 'SAML Metadata Source', + type: '@MetadataProvider', + schema: `assets/schema/source/metadata-source-saml.json`, + uiSchema: defaultsDeep({ + securityInfo: { + keyDescriptors: { + items: { + elementType: { + 'ui:readonly': true + } + } + } + } + }, SourceBase.uiSchema) +}, SourceBase); + +console.log(SamlSourceBase); + +export const SamlSourceEditor = defaultsDeep({ + ...SourceEditor, +}, SamlSourceBase); + +export const SamlSourceWizard = defaultsDeep({ + ...SourceWizard, +}, SamlSourceBase); + + diff --git a/ui/src/app/metadata/domain/source/definition/SourceDefinition.js b/ui/src/app/metadata/domain/source/definition/SourceDefinition.js index 41d409907..2069473ad 100644 --- a/ui/src/app/metadata/domain/source/definition/SourceDefinition.js +++ b/ui/src/app/metadata/domain/source/definition/SourceDefinition.js @@ -9,11 +9,6 @@ import isNil from 'lodash/isNil'; import { useMetadataSchemaContext } from '../../../hoc/MetadataSchema'; export const SourceBase = { - label: 'Metadata Source', - type: '@MetadataProvider', - steps: [], - schema: `${API_BASE_PATH}/ui/MetadataSources`, - // schema: `/assets/schema/source/metadata-source.json`, parser: (data) => removeNull(data, true), @@ -91,14 +86,6 @@ export const SourceBase = { } } - if (formData?.securityInfo?.x509Certificates) { - if (formData.securityInfo.x509Certificates?.length > 0) { - d.securityInfo.x509CertificateAvailable = true; - } else { - d.securityInfo.x509CertificateAvailable = false; - } - } - return d; }, @@ -109,6 +96,7 @@ export const SourceBase = { { size: 6, fields: [ + 'protocol', 'serviceProviderName', 'entityId', 'organization' @@ -127,7 +115,7 @@ export const SourceBase = { ], }, { - size: 6, + size: 12, fields: [ 'serviceProviderSsoDescriptor' ], @@ -230,14 +218,11 @@ export const SourceBase = { fields: [ 'authenticationRequestsSigned', 'wantAssertionsSigned', - 'x509Certificates' + 'keyDescriptors' ], } ] }, - x509CertificateAvailable: { - 'ui:widget': 'hidden' - }, authenticationRequestsSigned: { 'ui:widget': 'radio', 'ui:options': { @@ -250,11 +235,12 @@ export const SourceBase = { inline: true } }, - x509Certificates: { + keyDescriptors: { type: 'certificate', "ui:options": { orderable: false }, + 'ui:order': ['name', 'elementType', 'type', 'value'], items: { type: { 'ui:widget': 'radio', @@ -306,13 +292,18 @@ export const SourceBase = { export const SourceEditor = { ...SourceBase, - uiSchema: defaultsDeep({}, SourceBase.uiSchema), + uiSchema: defaultsDeep({ + protocol: { + 'ui:readonly': true + } + }, SourceBase.uiSchema), steps: [ { index: 1, - id: 'common', + id: 'org-info', label: 'label.sp-org-info', fields: [ + 'protocol', 'serviceProviderName', 'entityId', 'organization', @@ -387,13 +378,6 @@ export const SourceWizard = { { size: 6, classNames: 'bg-light border rounded px-4 pt-4 pb-3', - fields: [ - 'serviceProviderName', - 'entityId' - ] - }, - { - size: 6, fields: [ 'organization', ], @@ -459,6 +443,7 @@ export const SourceWizard = { id: 'common', label: 'label.name-and-entity-id', fields: [ + 'protocol', 'serviceProviderName', 'entityId' ] diff --git a/ui/src/app/metadata/domain/source/definition/SourceDefinition.test.js b/ui/src/app/metadata/domain/source/definition/SourceDefinition.test.js index 18dbc589c..92801c052 100644 --- a/ui/src/app/metadata/domain/source/definition/SourceDefinition.test.js +++ b/ui/src/app/metadata/domain/source/definition/SourceDefinition.test.js @@ -92,8 +92,7 @@ describe('SourceDefinition', () => { securityInfo: { x509Certificates: [ {} - ], - x509CertificateAvailable: true + ] } }); @@ -106,8 +105,7 @@ describe('SourceDefinition', () => { } )).toMatchObject({ securityInfo: { - x509Certificates: [], - x509CertificateAvailable: false + x509Certificates: [] } }); diff --git a/ui/src/app/metadata/domain/source/index.js b/ui/src/app/metadata/domain/source/index.js new file mode 100644 index 000000000..6a25b7cf8 --- /dev/null +++ b/ui/src/app/metadata/domain/source/index.js @@ -0,0 +1,12 @@ +import { OidcSourceWizard, OidcSourceEditor } from './definition/OidcSourceDefinition'; +import { SamlSourceEditor, SamlSourceWizard } from './definition/SamlSourceDefinition'; + +export const MetadataSourceWizardTypes = { + OIDC: OidcSourceWizard, + SAML: SamlSourceWizard, +}; + +export const MetadataSourceEditorTypes = { + OIDC: OidcSourceEditor, + SAML: SamlSourceEditor, +}; diff --git a/ui/src/app/metadata/hoc/MetadataSchema.js b/ui/src/app/metadata/hoc/MetadataSchema.js index ea14361d9..61010936e 100644 --- a/ui/src/app/metadata/hoc/MetadataSchema.js +++ b/ui/src/app/metadata/hoc/MetadataSchema.js @@ -10,6 +10,7 @@ export const MetadataSchemaLoading = React.createContext(); export function MetadataSchema({ type, children, wizard = false }) { const definition = React.useMemo(() => wizard ? getWizard(type) : getDefinition(type), [type, wizard]); + const [loading, setLoading] = React.useState(false); const { get, response } = useFetch(``, { diff --git a/ui/src/app/metadata/hooks/api.js b/ui/src/app/metadata/hooks/api.js index a67f9ef5a..24f96b1e6 100644 --- a/ui/src/app/metadata/hooks/api.js +++ b/ui/src/app/metadata/hooks/api.js @@ -93,6 +93,14 @@ export function useMetadataProviderTypes(opts = {}, onMount = null) { return useFetch(`${API_BASE_PATH}/ui/MetadataResolver/types`, opts, onMount); } +export function useMetadataSourceProtocols(opts = {}, onMount = null) { + return [ + { label: 'value.oidc', value: 'OIDC' }, + { label: 'value.saml', value: 'SAML' }, + // { label: 'value.cas', value: 'CAS' } + ]; +} + export function useMetadataFilterTypes () { return MetadataFilterTypes; } diff --git a/ui/src/app/metadata/new/NewSource.js b/ui/src/app/metadata/new/NewSource.js index 90a8e61e5..3908165e5 100644 --- a/ui/src/app/metadata/new/NewSource.js +++ b/ui/src/app/metadata/new/NewSource.js @@ -7,6 +7,8 @@ import { MetadataCopy } from '../view/MetadataCopy'; import { MetadataUpload } from '../view/MetadataUpload'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faCopy, faLink, faPlusSquare } from '@fortawesome/free-solid-svg-icons'; +import { MetadataSourceProtocolSelector } from '../wizard/MetadataSourceProtocolSelector'; +import { useMetadataSourceProtocols } from '../hooks/api'; export function NewSource() { @@ -14,6 +16,8 @@ export function NewSource() { const [showNav, setShowNav] = React.useState(true); + const protocols = useMetadataSourceProtocols(); + return (
@@ -75,22 +79,36 @@ export function NewSource() {
} - - - - { setShowNav(s) }} /> - } /> - - - } /> - + + + + {(data, onRestart) => + + { setShowNav(s) }} + onCallback={onRestart} + data={{ + protocol: data.protocol, + serviceProviderName: data.serviceProviderName, + entityId: data.entityId + }} /> + + } + + + } /> + + + } /> + + { setShowNav(s) } } /> - } /> - - - } /> - - +
+ } /> + + + } /> + diff --git a/ui/src/app/metadata/view/MetadataCopy.js b/ui/src/app/metadata/view/MetadataCopy.js index d489e724e..5a529387d 100644 --- a/ui/src/app/metadata/view/MetadataCopy.js +++ b/ui/src/app/metadata/view/MetadataCopy.js @@ -1,6 +1,4 @@ import React from 'react'; -import { MetadataSchema } from '../hoc/MetadataSchema'; - import { CopySource } from '../copy/CopySource'; import { SaveCopy } from '../copy/SaveCopy'; import { useMetadataEntity } from '../hooks/api'; @@ -52,9 +50,7 @@ export function MetadataCopy ({ onShowNav }) { } {confirm && copy && - - - + } ); diff --git a/ui/src/app/metadata/view/MetadataWizard.js b/ui/src/app/metadata/view/MetadataWizard.js index a95ca777c..36de25c12 100644 --- a/ui/src/app/metadata/view/MetadataWizard.js +++ b/ui/src/app/metadata/view/MetadataWizard.js @@ -9,7 +9,7 @@ import { createNotificationAction, NotificationTypes, useNotificationDispatcher import { Prompt, useHistory } from 'react-router-dom'; import { useTranslator } from '../../i18n/hooks'; -export function MetadataWizard ({type, data, onCallback}) { +export function MetadataWizard ({type, data, onCallback, onContinue}) { const history = useHistory(); const translator = useTranslator(); @@ -55,9 +55,9 @@ export function MetadataWizard ({type, data, onCallback}) { `message.unsaved-editor` } /> - + {type === 'source' ? - + : } diff --git a/ui/src/app/metadata/wizard/MetadataSourceProtocolSelector.js b/ui/src/app/metadata/wizard/MetadataSourceProtocolSelector.js new file mode 100644 index 000000000..c84b4b410 --- /dev/null +++ b/ui/src/app/metadata/wizard/MetadataSourceProtocolSelector.js @@ -0,0 +1,154 @@ +import React from 'react'; +import { faArrowCircleRight, faAsterisk, faSpinner } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; + +import { useForm } from 'react-hook-form'; +import Form from 'react-bootstrap/Form'; +import Translate from '../../i18n/components/translate'; +import { InfoIcon } from '../../form/component/InfoIcon'; +import { useTranslator } from '../../i18n/hooks'; +import { useMetadataSources } from '../hooks/api'; +import Button from 'react-bootstrap/esm/Button'; + +export function MetadataSourceProtocolSelector({ types = [], loading, children}) { + + const [sourceNames, setSourceNames] = React.useState([]); + const [sourceIds, setSourceIds] = React.useState([]); + + const translator = useTranslator(); + + const { data = [] } = useMetadataSources({ cachePolicy: 'no-cache' }, []); + + const [showSelector, setShowSelector] = React.useState(true); + + const { register, formState, handleSubmit, getValues } = useForm({ + mode: 'onChange', + reValidateMode: 'onChange', + defaultValues: { + serviceProviderName: null, + protocol: null, + entityID: null, + }, + resolver: undefined, + context: undefined, + criteriaMode: 'firstError', + shouldFocusError: true, + shouldUnregister: false, + }); + + const { isValid, errors } = formState; + + const onNext = (data) => { + setShowSelector(false); + }; + + const onShowSelector = () => { + setShowSelector(true); + }; + + React.useEffect(() => { + setSourceNames(data.map(s => s.serviceProviderName)); + setSourceIds(data.map(s => s.entityId)); + }, [data]); + + React.useState(() => console.log(sourceNames), [sourceNames]); + + return ( + <>{showSelector ? + <> + +
+
+
+
+
+ + + + + + {loading && } + + + + + + {types.map(t => )} + + + + + + + + + + + !(sourceNames.indexOf(v) > -1) + }})} /> + + {errors?.serviceProviderName?.type === 'unique' && } + {errors?.serviceProviderName?.type === 'required' && } + + + + + + + + + + + !(sourceIds.indexOf(v) > -1) + }})} /> + + {errors?.entityId?.type === 'unique' && } + {errors?.entityId?.type === 'required' && } + + +
+
+
+
+ + : + children(getValues(), onShowSelector) + } + + ); +} \ No newline at end of file diff --git a/ui/src/app/metadata/wizard/Wizard.js b/ui/src/app/metadata/wizard/Wizard.js index cc52249fe..49360160d 100644 --- a/ui/src/app/metadata/wizard/Wizard.js +++ b/ui/src/app/metadata/wizard/Wizard.js @@ -35,10 +35,11 @@ function reducer(state, action) { } } -function Wizard ({children}) { +function Wizard ({children, starting = 'common'}) { const [state, dispatch] = React.useReducer(reducer, { - ...initialState + ...initialState, + current: starting }); const contextValue = React.useMemo(() => ({ state, dispatch }), [state, dispatch]); diff --git a/ui/src/testing/sourceSchema.js b/ui/src/testing/sourceSchema.js index c723fd548..4b06db14a 100644 --- a/ui/src/testing/sourceSchema.js +++ b/ui/src/testing/sourceSchema.js @@ -1,3 +1,3 @@ -const SCHEMA = { "type": "object", "required": ["serviceProviderName", "entityId"], "properties": { "serviceProviderName": { "title": "label.service-provider-name", "description": "tooltip.service-provider-name", "type": "string", "minLength": 1, "maxLength": 255 }, "entityId": { "title": "label.entity-id", "description": "tooltip.entity-id", "type": "string", "minLength": 1, "maxLength": 255 }, "organization": { "$ref": "#/definitions/Organization" }, "contacts": { "title": "label.contact-information", "description": "tooltip.contact-information", "type": "array", "items": { "$ref": "#/definitions/Contact" } }, "mdui": { "$ref": "#/definitions/MDUI" }, "securityInfo": { "type": "object", "widget": { "id": "fieldset" }, "dependencies": { "authenticationRequestsSigned": { "oneOf": [{ "properties": { "authenticationRequestsSigned": { "enum": [true] }, "x509Certificates": { "minItems": 1 } } }, { "properties": { "authenticationRequestsSigned": { "enum": [false] }, "x509Certificates": { "minItems": 0 } } }] } }, "properties": { "x509CertificateAvailable": { "type": "boolean", "default": true }, "authenticationRequestsSigned": { "title": "label.authentication-requests-signed", "description": "tooltip.authentication-requests-signed", "type": "boolean", "enumNames": ["value.true", "value.false"] }, "wantAssertionsSigned": { "title": "label.want-assertions-signed", "description": "tooltip.want-assertions-signed", "type": "boolean", "enumNames": ["value.true", "value.false"] }, "x509Certificates": { "title": "label.x509-certificates", "type": "array", "items": { "$ref": "#/definitions/Certificate" } } } }, "assertionConsumerServices": { "title": "label.assertion-consumer-service-endpoints", "description": "", "type": "array", "items": { "$ref": "#/definitions/AssertionConsumerService" } }, "serviceProviderSsoDescriptor": { "type": "object", "properties": { "protocolSupportEnum": { "title": "label.protocol-support-enumeration", "description": "tooltip.protocol-support-enumeration", "type": "string", "widget": { "id": "select" }, "oneOf": [{ "enum": ["SAML 2"], "description": "SAML 2" }, { "enum": ["SAML 1.1"], "description": "SAML 1.1" }] }, "nameIdFormats": { "$ref": "#/definitions/nameIdFormats" } }, "dependencies": { "nameIdFormats": ["protocolSupportEnum"] } }, "logoutEndpoints": { "title": "label.logout-endpoints", "description": "tooltip.logout-endpoints", "type": "array", "items": { "$ref": "#/definitions/LogoutEndpoint" } }, "relyingPartyOverrides": { "type": "object", "properties": { "signAssertion": { "title": "label.sign-the-assertion", "description": "tooltip.sign-assertion", "type": "boolean", "default": false }, "dontSignResponse": { "title": "label.dont-sign-the-response", "description": "tooltip.dont-sign-response", "type": "boolean", "default": false }, "turnOffEncryption": { "title": "label.turn-off-encryption-of-response", "description": "tooltip.turn-off-encryption", "type": "boolean", "default": false }, "useSha": { "title": "label.use-sha1-signing-algorithm", "description": "tooltip.usa-sha-algorithm", "type": "boolean", "default": false }, "ignoreAuthenticationMethod": { "title": "label.ignore-any-sp-requested-authentication-method", "description": "tooltip.ignore-auth-method", "type": "boolean", "default": false }, "omitNotBefore": { "title": "label.omit-not-before-condition", "description": "tooltip.omit-not-before-condition", "type": "boolean", "default": false }, "responderId": { "title": "label.responder-id", "description": "tooltip.responder-id", "type": "string", "default": "" }, "nameIdFormats": { "$ref": "#/definitions/nameIdFormats" }, "authenticationMethods": { "$ref": "#/definitions/authenticationMethods" }, "forceAuthn": { "title": "label.force-authn", "description": "tooltip.force-authn", "type": "boolean", "default": false } } }, "attributeRelease": { "type": "array", "title": "label.attribute-release", "description": "Attribute release table - select the attributes you want to release (default unchecked)", "items": { "type": "string", "enum": ["eduPersonPrincipalName", "uid", "mail", "surname", "givenName", "eduPersonAffiliation", "eduPersonScopedAffiliation", "eduPersonPrimaryAffiliation", "eduPersonEntitlement", "eduPersonAssurance", "eduPersonUniqueId", "employeeNumber"] }, "uniqueItems": true } }, "definitions": { "Contact": { "type": "object", "required": ["name", "type", "emailAddress"], "properties": { "name": { "title": "label.contact-name", "description": "tooltip.contact-name", "type": "string", "minLength": 1, "maxLength": 255 }, "type": { "title": "label.contact-type", "description": "tooltip.contact-type", "type": "string", "widget": "select", "minLength": 1, "oneOf": [{ "enum": ["support"], "description": "value.support" }, { "enum": ["technical"], "description": "value.technical" }, { "enum": ["administrative"], "description": "value.administrative" }, { "enum": ["other"], "description": "value.other" }] }, "emailAddress": { "title": "label.contact-email-address", "description": "tooltip.contact-email", "type": "string", "pattern": "^(mailto:)?(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$", "minLength": 1, "maxLength": 255 } } }, "Certificate": { "type": "object", "required": ["type", "value"], "properties": { "name": { "title": "label.certificate-name-display-only", "description": "tooltip.certificate-name", "type": "string", "maxLength": 255 }, "type": { "title": "label.certificate-type", "type": "string", "widget": { "id": "radio", "class": "form-check-inline" }, "oneOf": [{ "enum": ["signing"], "description": "value.signing" }, { "enum": ["encryption"], "description": "value.encryption" }, { "enum": ["both"], "description": "value.both" }] }, "value": { "title": "label.certificate", "description": "tooltip.certificate", "type": "string", "widget": "textarea", "minLength": 1 } } }, "AssertionConsumerService": { "type": "object", "required": ["locationUrl", "binding"], "properties": { "locationUrl": { "title": "label.assertion-consumer-service-location", "description": "tooltip.assertion-consumer-service-location", "type": "string", "widget": { "id": "string", "help": "message.valid-url" }, "minLength": 1, "maxLength": 255 }, "binding": { "title": "label.assertion-consumer-service-location-binding", "description": "tooltip.assertion-consumer-service-location-binding", "type": "string", "widget": "select", "oneOf": [{ "enum": ["urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"], "description": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" }, { "enum": ["urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign"], "description": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" }, { "enum": ["urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"], "description": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" }, { "enum": ["urn:oasis:names:tc:SAML:2.0:bindings:PAOS"], "description": "urn:oasis:names:tc:SAML:2.0:bindings:PAOS" }, { "enum": ["urn:oasis:names:tc:SAML:1.0:profiles:browser-post"], "description": "urn:oasis:names:tc:SAML:1.0:profiles:browser-post" }, { "enum": ["urn:oasis:names:tc:SAML:1.0:profiles:artifact-01"], "description": "urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" }] }, "makeDefault": { "title": "label.mark-as-default", "description": "tooltip.mark-as-default", "type": "boolean" } } }, "LogoutEndpoint": { "description": "tooltip.new-endpoint", "type": "object", "fieldsets": [{ "fields": ["url", "bindingType"] }], "required": ["url", "bindingType"], "properties": { "url": { "title": "label.url", "description": "tooltip.url", "type": "string", "minLength": 1, "maxLength": 255 }, "bindingType": { "title": "label.binding-type", "description": "tooltip.binding-type", "type": "string", "widget": "select", "oneOf": [{ "enum": ["urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"], "description": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" }, { "enum": ["urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"], "description": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" }, { "enum": ["urn:oasis:names:tc:SAML:2.0:bindings:SOAP"], "description": "urn:oasis:names:tc:SAML:2.0:bindings:SOAP" }, { "enum": ["urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"], "description": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" }] } } }, "MDUI": { "type": "object", "widget": { "id": "fieldset" }, "fieldsets": [{ "type": "group", "fields": ["displayName", "informationUrl", "description"] }, { "type": "group", "fields": ["privacyStatementUrl", "logoUrl", "logoWidth", "logoHeight"] }], "properties": { "displayName": { "title": "label.display-name", "description": "tooltip.mdui-display-name", "type": "string", "minLength": 1, "maxLength": 255 }, "informationUrl": { "title": "label.information-url", "description": "tooltip.mdui-information-url", "type": "string", "minLength": 1, "maxLength": 255 }, "privacyStatementUrl": { "title": "label.privacy-statement-url", "description": "tooltip.mdui-privacy-statement-url", "type": "string", "minLength": 1, "maxLength": 255 }, "description": { "title": "label.description", "description": "tooltip.mdui-description", "type": "string", "widget": { "id": "textarea" }, "minLength": 1, "maxLength": 255 }, "logoUrl": { "title": "label.logo-url", "description": "tooltip.mdui-logo-url", "type": "string", "minLength": 1, "maxLength": 255 }, "logoHeight": { "title": "label.logo-height", "description": "tooltip.mdui-logo-height", "minimum": 0, "type": "integer" }, "logoWidth": { "title": "label.logo-width", "description": "tooltip.mdui-logo-width", "minimum": 0, "type": "integer" } } }, "Organization": { "type": "object", "properties": { "name": { "title": "label.organization-name", "description": "tooltip.organization-name", "type": "string", "minLength": 1, "maxLength": 255 }, "displayName": { "title": "label.organization-display-name", "description": "tooltip.organization-display-name", "type": "string", "minLength": 1, "maxLength": 255 }, "url": { "title": "label.organization-url", "description": "tooltip.organization-url", "type": "string", "minLength": 1, "maxLength": 255 } }, "dependencies": { "name": { "required": ["displayName", "url"] }, "displayName": { "required": ["name", "url"] }, "url": { "required": ["name", "displayName"] } } }, "nameIdFormats": { "title": "label.nameid-format-to-send", "description": "tooltip.nameid-format", "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 255, "examples": ["urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified", "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"] } }, "authenticationMethods": { "title": "label.authentication-methods-to-use", "description": "tooltip.authentication-methods-to-use", "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 255, "examples": ["https://refeds.org/profile/mfa", "urn:oasis:names:tc:SAML:2.0:ac:classes:TimeSyncToken", "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"] } } } }; +const SCHEMA = { "type": "object", "required": ["serviceProviderName", "entityId"], "properties": { "serviceProviderName": { "title": "label.service-provider-name", "description": "tooltip.service-provider-name", "type": "string", "minLength": 1, "maxLength": 255 }, "entityId": { "title": "label.entity-id", "description": "tooltip.entity-id", "type": "string", "minLength": 1, "maxLength": 255 }, "organization": { "$ref": "#/definitions/Organization" }, "contacts": { "title": "label.contact-information", "description": "tooltip.contact-information", "type": "array", "items": { "$ref": "#/definitions/Contact" } }, "mdui": { "$ref": "#/definitions/MDUI" }, "securityInfo": { "type": "object", "widget": { "id": "fieldset" }, "dependencies": { "authenticationRequestsSigned": { "oneOf": [{ "properties": { "authenticationRequestsSigned": { "enum": [true] }, "x509Certificates": { "minItems": 1 } } }, { "properties": { "authenticationRequestsSigned": { "enum": [false] }, "x509Certificates": { "minItems": 0 } } }] } }, "properties": { "authenticationRequestsSigned": { "title": "label.authentication-requests-signed", "description": "tooltip.authentication-requests-signed", "type": "boolean", "enumNames": ["value.true", "value.false"] }, "wantAssertionsSigned": { "title": "label.want-assertions-signed", "description": "tooltip.want-assertions-signed", "type": "boolean", "enumNames": ["value.true", "value.false"] }, "x509Certificates": { "title": "label.x509-certificates", "type": "array", "items": { "$ref": "#/definitions/Certificate" } } } }, "assertionConsumerServices": { "title": "label.assertion-consumer-service-endpoints", "description": "", "type": "array", "items": { "$ref": "#/definitions/AssertionConsumerService" } }, "serviceProviderSsoDescriptor": { "type": "object", "properties": { "protocolSupportEnum": { "title": "label.protocol-support-enumeration", "description": "tooltip.protocol-support-enumeration", "type": "string", "widget": { "id": "select" }, "oneOf": [{ "enum": ["SAML 2"], "description": "SAML 2" }, { "enum": ["SAML 1.1"], "description": "SAML 1.1" }] }, "nameIdFormats": { "$ref": "#/definitions/nameIdFormats" } }, "dependencies": { "nameIdFormats": ["protocolSupportEnum"] } }, "logoutEndpoints": { "title": "label.logout-endpoints", "description": "tooltip.logout-endpoints", "type": "array", "items": { "$ref": "#/definitions/LogoutEndpoint" } }, "relyingPartyOverrides": { "type": "object", "properties": { "signAssertion": { "title": "label.sign-the-assertion", "description": "tooltip.sign-assertion", "type": "boolean", "default": false }, "dontSignResponse": { "title": "label.dont-sign-the-response", "description": "tooltip.dont-sign-response", "type": "boolean", "default": false }, "turnOffEncryption": { "title": "label.turn-off-encryption-of-response", "description": "tooltip.turn-off-encryption", "type": "boolean", "default": false }, "useSha": { "title": "label.use-sha1-signing-algorithm", "description": "tooltip.usa-sha-algorithm", "type": "boolean", "default": false }, "ignoreAuthenticationMethod": { "title": "label.ignore-any-sp-requested-authentication-method", "description": "tooltip.ignore-auth-method", "type": "boolean", "default": false }, "omitNotBefore": { "title": "label.omit-not-before-condition", "description": "tooltip.omit-not-before-condition", "type": "boolean", "default": false }, "responderId": { "title": "label.responder-id", "description": "tooltip.responder-id", "type": "string", "default": "" }, "nameIdFormats": { "$ref": "#/definitions/nameIdFormats" }, "authenticationMethods": { "$ref": "#/definitions/authenticationMethods" }, "forceAuthn": { "title": "label.force-authn", "description": "tooltip.force-authn", "type": "boolean", "default": false } } }, "attributeRelease": { "type": "array", "title": "label.attribute-release", "description": "Attribute release table - select the attributes you want to release (default unchecked)", "items": { "type": "string", "enum": ["eduPersonPrincipalName", "uid", "mail", "surname", "givenName", "eduPersonAffiliation", "eduPersonScopedAffiliation", "eduPersonPrimaryAffiliation", "eduPersonEntitlement", "eduPersonAssurance", "eduPersonUniqueId", "employeeNumber"] }, "uniqueItems": true } }, "definitions": { "Contact": { "type": "object", "required": ["name", "type", "emailAddress"], "properties": { "name": { "title": "label.contact-name", "description": "tooltip.contact-name", "type": "string", "minLength": 1, "maxLength": 255 }, "type": { "title": "label.contact-type", "description": "tooltip.contact-type", "type": "string", "widget": "select", "minLength": 1, "oneOf": [{ "enum": ["support"], "description": "value.support" }, { "enum": ["technical"], "description": "value.technical" }, { "enum": ["administrative"], "description": "value.administrative" }, { "enum": ["other"], "description": "value.other" }] }, "emailAddress": { "title": "label.contact-email-address", "description": "tooltip.contact-email", "type": "string", "pattern": "^(mailto:)?(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$", "minLength": 1, "maxLength": 255 } } }, "Certificate": { "type": "object", "required": ["type", "value"], "properties": { "name": { "title": "label.certificate-name-display-only", "description": "tooltip.certificate-name", "type": "string", "maxLength": 255 }, "type": { "title": "label.certificate-type", "type": "string", "widget": { "id": "radio", "class": "form-check-inline" }, "oneOf": [{ "enum": ["signing"], "description": "value.signing" }, { "enum": ["encryption"], "description": "value.encryption" }, { "enum": ["both"], "description": "value.both" }] }, "value": { "title": "label.certificate", "description": "tooltip.certificate", "type": "string", "widget": "textarea", "minLength": 1 } } }, "AssertionConsumerService": { "type": "object", "required": ["locationUrl", "binding"], "properties": { "locationUrl": { "title": "label.assertion-consumer-service-location", "description": "tooltip.assertion-consumer-service-location", "type": "string", "widget": { "id": "string", "help": "message.valid-url" }, "minLength": 1, "maxLength": 255 }, "binding": { "title": "label.assertion-consumer-service-location-binding", "description": "tooltip.assertion-consumer-service-location-binding", "type": "string", "widget": "select", "oneOf": [{ "enum": ["urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"], "description": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" }, { "enum": ["urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign"], "description": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" }, { "enum": ["urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"], "description": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" }, { "enum": ["urn:oasis:names:tc:SAML:2.0:bindings:PAOS"], "description": "urn:oasis:names:tc:SAML:2.0:bindings:PAOS" }, { "enum": ["urn:oasis:names:tc:SAML:1.0:profiles:browser-post"], "description": "urn:oasis:names:tc:SAML:1.0:profiles:browser-post" }, { "enum": ["urn:oasis:names:tc:SAML:1.0:profiles:artifact-01"], "description": "urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" }] }, "makeDefault": { "title": "label.mark-as-default", "description": "tooltip.mark-as-default", "type": "boolean" } } }, "LogoutEndpoint": { "description": "tooltip.new-endpoint", "type": "object", "fieldsets": [{ "fields": ["url", "bindingType"] }], "required": ["url", "bindingType"], "properties": { "url": { "title": "label.url", "description": "tooltip.url", "type": "string", "minLength": 1, "maxLength": 255 }, "bindingType": { "title": "label.binding-type", "description": "tooltip.binding-type", "type": "string", "widget": "select", "oneOf": [{ "enum": ["urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"], "description": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" }, { "enum": ["urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"], "description": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" }, { "enum": ["urn:oasis:names:tc:SAML:2.0:bindings:SOAP"], "description": "urn:oasis:names:tc:SAML:2.0:bindings:SOAP" }, { "enum": ["urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"], "description": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" }] } } }, "MDUI": { "type": "object", "widget": { "id": "fieldset" }, "fieldsets": [{ "type": "group", "fields": ["displayName", "informationUrl", "description"] }, { "type": "group", "fields": ["privacyStatementUrl", "logoUrl", "logoWidth", "logoHeight"] }], "properties": { "displayName": { "title": "label.display-name", "description": "tooltip.mdui-display-name", "type": "string", "minLength": 1, "maxLength": 255 }, "informationUrl": { "title": "label.information-url", "description": "tooltip.mdui-information-url", "type": "string", "minLength": 1, "maxLength": 255 }, "privacyStatementUrl": { "title": "label.privacy-statement-url", "description": "tooltip.mdui-privacy-statement-url", "type": "string", "minLength": 1, "maxLength": 255 }, "description": { "title": "label.description", "description": "tooltip.mdui-description", "type": "string", "widget": { "id": "textarea" }, "minLength": 1, "maxLength": 255 }, "logoUrl": { "title": "label.logo-url", "description": "tooltip.mdui-logo-url", "type": "string", "minLength": 1, "maxLength": 255 }, "logoHeight": { "title": "label.logo-height", "description": "tooltip.mdui-logo-height", "minimum": 0, "type": "integer" }, "logoWidth": { "title": "label.logo-width", "description": "tooltip.mdui-logo-width", "minimum": 0, "type": "integer" } } }, "Organization": { "type": "object", "properties": { "name": { "title": "label.organization-name", "description": "tooltip.organization-name", "type": "string", "minLength": 1, "maxLength": 255 }, "displayName": { "title": "label.organization-display-name", "description": "tooltip.organization-display-name", "type": "string", "minLength": 1, "maxLength": 255 }, "url": { "title": "label.organization-url", "description": "tooltip.organization-url", "type": "string", "minLength": 1, "maxLength": 255 } }, "dependencies": { "name": { "required": ["displayName", "url"] }, "displayName": { "required": ["name", "url"] }, "url": { "required": ["name", "displayName"] } } }, "nameIdFormats": { "title": "label.nameid-format-to-send", "description": "tooltip.nameid-format", "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 255, "examples": ["urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified", "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"] } }, "authenticationMethods": { "title": "label.authentication-methods-to-use", "description": "tooltip.authentication-methods-to-use", "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 255, "examples": ["https://refeds.org/profile/mfa", "urn:oasis:names:tc:SAML:2.0:ac:classes:TimeSyncToken", "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"] } } } }; export default SCHEMA; \ No newline at end of file diff --git a/ui/src/testing/uiSchema.js b/ui/src/testing/uiSchema.js index 8da257247..a58082e38 100644 --- a/ui/src/testing/uiSchema.js +++ b/ui/src/testing/uiSchema.js @@ -140,9 +140,6 @@ const schema = { } ] }, - "x509CertificateAvailable": { - "ui:widget": "hidden" - }, "authenticationRequestsSigned": { "ui:widget": "radio", "ui:options": {