diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataSourcesUiDefinitionController.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataSourcesUiDefinitionController.groovy index 3600667ba..86ece39b9 100644 --- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataSourcesUiDefinitionController.groovy +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataSourcesUiDefinitionController.groovy @@ -2,6 +2,7 @@ package edu.internet2.tier.shibboleth.admin.ui.controller import com.fasterxml.jackson.databind.ObjectMapper import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration +import groovy.json.JsonOutput import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.context.properties.ConfigurationProperties import org.springframework.core.io.ResourceLoader @@ -42,24 +43,76 @@ class MetadataSourcesUiDefinitionController { ResponseEntity getUiDefinitionJsonSchema() { try { def parsedJson = jacksonObjectMapper.readValue(this.jsonSchemaUrl, Map) - def widget = parsedJson["properties"]["attributeRelease"]["widget"] - def data = [] - customPropertiesConfiguration.getAttributes().each { - def attribute = [:] - attribute["key"] = it["name"] - attribute["label"] = it["displayName"] - data << attribute - } - widget["data"] = data + addReleaseAttributesToJson(parsedJson["properties"]["attributeRelease"]["widget"]) + addRelyingPartyOverridesToJson(parsedJson["properties"]["relyingPartyOverrides"]) + addRelyingPartyOverridesCollectionDefinitions(parsedJson["definitions"]) + println(JsonOutput.prettyPrint(JsonOutput.toJson(parsedJson))) return ResponseEntity.ok(parsedJson) } catch (Exception e) { + e.printStackTrace() return ResponseEntity.status(INTERNAL_SERVER_ERROR) .body([jsonParseError : e.getMessage(), sourceUiSchemaDefinitionFile: this.jsonSchemaUrl]) } } + private void addReleaseAttributesToJson(Object json) { + def data = [] + customPropertiesConfiguration.getAttributes().each { + def attribute = [:] + attribute["key"] = it["name"] + attribute["label"] = it["displayName"] + data << attribute + } + json["data"] = data + } + + private void addRelyingPartyOverridesToJson(Object json) { + def properties = [:] + customPropertiesConfiguration.getOverrides().each { + def property = [:] + if (it["displayType"] == "list" + || it["displayType"] == "set") { + property['$ref'] = "#/definitions/" + it["name"] + } else { + property["title"] = it["displayName"] + property["description"] = it["helpText"] + property["type"] = it["displayType"] + property["default"] = it["defaultValue"] + } + properties[it["name"]] = property + } + json["properties"] = properties + } + + private void addRelyingPartyOverridesCollectionDefinitions(Object json) { + customPropertiesConfiguration.getOverrides().stream().filter { + it -> it["displayType"] && (it["displayType"] == "list" || it["displayType"] == "set") + }.each { + def definition = [:] + definition["title"] = it["displayName"] + definition["description"] = it["helpText"] + definition["type"] = "array" + if (it["displayType"] == "set") { + definition["uniqueItems"] = true + } else if (it["displayType"] == "list") { + definition["uniqueItems"] = false + } + def items = [:] + items["type"] = "string" + items["widget"] = "datalist" + def data = [] + it["defaultValues"].each { value -> + data << value + } + items["data"] = data + definition["items"] = items + definition["default"] = null + json[(String)it["name"]] = definition + } + } + @PostConstruct def init() { jsonSchemaUrl = this.resourceLoader.getResource(this.metadataSourcesUiSchemaLocation).getURL() diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RelyingPartyOverrideProperty.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RelyingPartyOverrideProperty.java index 7841ff6c6..9fa2c5289 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RelyingPartyOverrideProperty.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RelyingPartyOverrideProperty.java @@ -10,11 +10,11 @@ public class RelyingPartyOverrideProperty { private String name; private String displayName; private String displayType; + private String defaultValue; private String helpText; + private List defaultValues; private String persistType; private String persistValue; - private List defaultValues; - private Collection persistValues; private String attributeName; private String attributeFriendlyName; @@ -42,6 +42,14 @@ public void setDisplayType(String displayType) { this.displayType = displayType; } + public String getDefaultValue() { + return defaultValue; + } + + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + public String getHelpText() { return helpText; } @@ -74,14 +82,6 @@ public void setDefaultValues(List defaultValues) { this.defaultValues = defaultValues; } - public Collection getPersistValues() { - return persistValues; - } - - public void setPersistValues(Collection persistValues) { - this.persistValues = persistValues; - } - public String getAttributeName() { return attributeName; } @@ -104,11 +104,11 @@ public String toString() { + "\nname='" + name + '\'' + ", \ndisplayName='" + displayName + '\'' + ", \ndisplayType='" + displayType + '\'' + + ", \ndefaultValue='" + defaultValue + '\'' + ", \nhelpText='" + helpText + '\'' + ", \npersistType='" + persistType + '\'' + ", \npersistValue='" + persistValue + '\'' + ", \ndefaultValues=" + defaultValues - + ", \npersistValues=" + persistValues + ", \nattributeName='" + attributeName + '\'' + ", \nattributeFriendlyName='" + attributeFriendlyName + '\'' + "\n}"; diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index 5fbbf5c69..12bfd55cc 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -48,55 +48,62 @@ custom: overrides: # Default overrides - name: signAssertion - displayName: Sign the Assertion + displayName: label.sign-the-assertion displayType: boolean - helpText: Sign Assertion + defaultValue: false + helpText: tooltip.sign-assertion attributeName: http://shibboleth.net/ns/profiles/saml2/sso/browser/signAssertions attributeFriendlyName: signAssertions - name: dontSignResponse - displayName: Don't Sign the Response + displayName: label.dont-sign-the-response displayType: boolean - helpText: Don't Sign Response + defaultValue: false + helpText: tooltip.dont-sign-response attributeName: http://shibboleth.net/ns/profiles/saml2/sso/browser/signResponses attributeFriendlyName: signResponses - name: turnOffEncryption - displayName: Turn Off Encryption of Response + displayName: label.turn-off-encryption-of-response displayType: boolean - helpText: Turn Off Encryption of Response + defaultValue: false + helpText: tooltip.turn-off-encryption attributeName: http://shibboleth.net/ns/profiles/encryptAssertions attributeFriendlyName: encryptAssertions - name: useSha - displayName: Use SHA1 Signing Algorithm + displayName: label.use-sha1-signing-algorithm displayType: boolean - helpText: Use SHA1 Signing Algorithm + defaultValue: false + helpText: tooltip.usa-sha-algorithm persistType: string persistValue: shibboleth.SecurityConfiguration.SHA1 attributeName: http://shibboleth.net/ns/profiles/securityConfiguration attributeFriendlyName: securityConfiguration - name: ignoreAuthenticationMethod - displayName: Ignore any SP-Requested Authentication Method + displayName: label.ignore-any-sp-requested-authentication-method displayType: boolean - helpText: Ignore any SP-Requested Authentication Method + defaultValue: false + helpText: tooltip.ignore-auth-method persistType: string persistValue: 0x1 attributeName: http://shibboleth.net/ns/profiles/disallowedFeatures attributeFriendlyName: disallowedFeatures - name: omitNotBefore - displayName: Omit Not Before Condition + displayName: label.omit-not-before-condition displayType: boolean - helpText: Omit Not Before Condition + defaultValue: false + helpText: tooltip.omit-not-before-condition attributeName: http://shibboleth.net/ns/profiles/includeConditionsNotBefore attributeFriendlyName: includeConditionsNotBefore - name: responderId - displayName: responderId + displayName: label.responder-id displayType: string - helpText: ResponderId + defaultValue: null + helpText: tooltip.responder-id attributeName: http://shibboleth.net/ns/profiles/responderId attributeFriendlyName: responderId - name: nameIdFormats - displayName: nameIdFormats - displayType: list - helpText: Add NameID Format + displayName: label.nameid-format-to-send + displayType: set + helpText: tooltip.nameid-format defaultValues: - urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified - urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress @@ -105,9 +112,9 @@ custom: attributeName: http://shibboleth.net/ns/profiles/nameIDFormatPrecedence attributeFriendlyName: nameIDFormatPrecedence - name: authenticationMethods - displayName: authenticationMethods - displayType: list - helpText: Authentication Methods to Use + displayName: label.authentication-methods-to-use + displayType: set + helpText: tooltip.authentication-methods-to-use defaultValues: - https://refeds.org/profile/mfa - urn:oasis:names:tc:SAML:2.0:ac:classes:TimeSyncToken @@ -115,8 +122,9 @@ custom: attributeName: http://shibboleth.net/ns/profiles/defaultAuthenticationMethods attributeFriendlyName: defaultAuthenticationMethods - name: forceAuthn - displayName: Force AuthN + displayName: label.force-authn displayType: boolean - helpText: Disallows use (or reuse) of authentication results and login flows that don't provide a real-time proof of user presence in the login process + defaultValue: false + helpText: tooltip.force-authn attributeName: http://shibboleth.net/ns/profiles/forceAuthn attributeFriendlyName: forceAuthn \ No newline at end of file diff --git a/ui/src/assets/schema/filter/entity-attributes.schema.json b/ui/src/assets/schema/filter/entity-attributes.schema.json index 2350a345c..00060d62c 100644 --- a/ui/src/assets/schema/filter/entity-attributes.schema.json +++ b/ui/src/assets/schema/filter/entity-attributes.schema.json @@ -91,97 +91,7 @@ "required": ["value", "entityAttributesFilterTargetType"] }, "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 - }, - "forceAuthn": { - "title": "label.force-authn", - "description": "tooltip.force-authn", - "type": "boolean", - "default": false - }, - "omitNotBefore": { - "title": "label.omit-not-before-condition", - "type": "boolean", - "description": "tooltip.omit-not-before-condition", - "default": false - }, - "responderId": { - "title": "label.responder-id", - "description": "tooltip.responder-id", - "type": "string" - }, - "nameIdFormats": { - "title": "label.nameid-format-to-send", - "placeholder": "label.nameid-format", - "description": "tooltip.nameid-format", - "type": "array", - "uniqueItems": true, - "items": { - "title": "label.nameid-format", - "type": "string", - "widget": { - "id": "datalist", - "data": [ - "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" - ] - } - }, - "default": null - }, - "authenticationMethods": { - "title": "label.authentication-methods-to-use", - "description": "tooltip.authentication-methods-to-use", - "type": "array", - "placeholder": "label.authentication-method", - "uniqueItems": true, - "items": { - "type": "string", - "title": "label.authentication-method", - "widget": { - "id": "datalist", - "data": [ - "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" - ] - } - }, - "default": null - } - } + "type": "object" }, "attributeRelease": { "type": "array", @@ -223,4 +133,4 @@ ] } ] -} \ No newline at end of file +}