From 433f628130fec28795e5368fc14c8d272ab0bfd6 Mon Sep 17 00:00:00 2001 From: Jj! Date: Mon, 13 Sep 2021 17:47:26 -0500 Subject: [PATCH 01/30] [Gradle Release Plugin] - pre tag commit: '1.9.2'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 9c9e650af..721a83c37 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ name=shibui group=edu.internet2.tier.shibboleth.admin.ui -version=1.10.0-SNAPSHOT +version=1.9.2 shibboleth.version=3.4.4 opensaml.version=3.4.3 From 6cae11f2464b69da428eff0f1cdbb3bc0f725b09 Mon Sep 17 00:00:00 2001 From: Jj! Date: Mon, 13 Sep 2021 17:49:12 -0500 Subject: [PATCH 02/30] [Gradle Release Plugin] - new version commit: '1.10.0-SNAPSHOT'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 721a83c37..9c9e650af 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ name=shibui group=edu.internet2.tier.shibboleth.admin.ui -version=1.9.2 +version=1.10.0-SNAPSHOT shibboleth.version=3.4.4 opensaml.version=3.4.3 From b25777b7048d67f1ffb2b0dca29e4b5a8cfa9d19 Mon Sep 17 00:00:00 2001 From: Jj! Date: Thu, 21 Oct 2021 16:37:21 -0500 Subject: [PATCH 03/30] [Gradle Release Plugin] - pre tag commit: '1.10.0'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 9c9e650af..62ae2020c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ name=shibui group=edu.internet2.tier.shibboleth.admin.ui -version=1.10.0-SNAPSHOT +version=1.10.0 shibboleth.version=3.4.4 opensaml.version=3.4.3 From 168c892a90b6c96d2da7606bea4b1c8ea85fc0b0 Mon Sep 17 00:00:00 2001 From: Jj! Date: Thu, 21 Oct 2021 16:37:56 -0500 Subject: [PATCH 04/30] [Gradle Release Plugin] - new version commit: '1.11.0-SNAPSHOT'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 62ae2020c..79bee945d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ name=shibui group=edu.internet2.tier.shibboleth.admin.ui -version=1.10.0 +version=1.11.0-SNAPSHOT shibboleth.version=3.4.4 opensaml.version=3.4.3 From fb32f6732f71737a119a526be934be60d2f7d83b Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Fri, 22 Oct 2021 14:48:05 -0700 Subject: [PATCH 05/30] Fixed missing match --- ...dynamic-http-metadata-provider.schema.json | 7 +-- .../definition/BaseProviderDefinition.js | 1 + .../DynamicHttpMetadataProviderDefinition.js | 43 +++++++++++++++++++ ui/src/app/metadata/hoc/MetadataSchema.js | 2 - ui/src/app/metadata/hooks/configuration.js | 2 +- 5 files changed, 47 insertions(+), 8 deletions(-) diff --git a/backend/src/main/resources/dynamic-http-metadata-provider.schema.json b/backend/src/main/resources/dynamic-http-metadata-provider.schema.json index 8be8bbf9b..5de721ce6 100644 --- a/backend/src/main/resources/dynamic-http-metadata-provider.schema.json +++ b/backend/src/main/resources/dynamic-http-metadata-provider.schema.json @@ -47,13 +47,10 @@ ] }, "match": { + "$id": "match", "title": "label.match", "description": "tooltip.match", - "type": "string", - "widget": { - "id": "string", - "required": true - } + "type": "string" } }, "required": [ diff --git a/ui/src/app/metadata/domain/provider/definition/BaseProviderDefinition.js b/ui/src/app/metadata/domain/provider/definition/BaseProviderDefinition.js index 207eb0a2e..d5d766f38 100644 --- a/ui/src/app/metadata/domain/provider/definition/BaseProviderDefinition.js +++ b/ui/src/app/metadata/domain/provider/definition/BaseProviderDefinition.js @@ -77,6 +77,7 @@ export const BaseProviderDefinition = { } }; }, + overrideSchema: (schema) => schema, uiSchema: { name: { 'ui:help': 'message.must-be-unique' diff --git a/ui/src/app/metadata/domain/provider/definition/DynamicHttpMetadataProviderDefinition.js b/ui/src/app/metadata/domain/provider/definition/DynamicHttpMetadataProviderDefinition.js index 84b694e9a..2786db408 100644 --- a/ui/src/app/metadata/domain/provider/definition/DynamicHttpMetadataProviderDefinition.js +++ b/ui/src/app/metadata/domain/provider/definition/DynamicHttpMetadataProviderDefinition.js @@ -1,14 +1,57 @@ import { BaseProviderDefinition, HttpMetadataResolverAttributesSchema, MetadataFilterPluginsSchema } from './BaseProviderDefinition'; import API_BASE_PATH from '../../../../App.constant'; import defaultsDeep from 'lodash/defaultsDeep'; +import isNil from 'lodash/isNil'; import { DurationOptions } from '../../data'; import { isValidRegex } from '../../../../core/utility/is_valid_regex'; +function findById(o, id) { + //Early return + if (o.$id === id) { + return o; + } + var result, p; + for (p in o) { + if (o.hasOwnProperty(p) && typeof o[p] === 'object') { + result = findById(o[p], id); + if (result) { + return result; + } + } + } + return result; +} + + export const DynamicHttpMetadataProviderWizard = { ...BaseProviderDefinition, label: 'DynamicHttpMetadataProvider', type: 'DynamicHttpMetadataResolver', schema: `${API_BASE_PATH}/ui/MetadataResolver/DynamicHttpMetadataResolver`, + overrideSchema: (schema, models) => { + + const includeMatch = models.some(m => !isNil(m?.metadataRequestURLConstructionScheme?.match)); + + console.log(models) + + if (includeMatch) { + return ({ + ...schema, + properties: { + ...schema.properties, + metadataRequestURLConstructionScheme: { + ...schema.properties.metadataRequestURLConstructionScheme, + properties: { + ...schema.properties.metadataRequestURLConstructionScheme.properties, + match: findById(schema.properties.metadataRequestURLConstructionScheme.dependencies, 'match') + } + } + } + }); + } + + return schema; + }, validator: (data = [], current = { resourceId: null }, group, translator) => { const base = BaseProviderDefinition.validator(data, current, group); diff --git a/ui/src/app/metadata/hoc/MetadataSchema.js b/ui/src/app/metadata/hoc/MetadataSchema.js index 6ee801c28..025e7a415 100644 --- a/ui/src/app/metadata/hoc/MetadataSchema.js +++ b/ui/src/app/metadata/hoc/MetadataSchema.js @@ -54,6 +54,4 @@ export function useMetadataDefinitionValidator(data, current, group) { return definition.validator(data, current, group, translator); } -//getConfigurationSections - export default MetadataSchema; \ No newline at end of file diff --git a/ui/src/app/metadata/hooks/configuration.js b/ui/src/app/metadata/hooks/configuration.js index 0574359a1..0c78cd90f 100644 --- a/ui/src/app/metadata/hooks/configuration.js +++ b/ui/src/app/metadata/hooks/configuration.js @@ -18,5 +18,5 @@ export function useMetadataConfiguration(models, schema, definition, limited = f return {}; } - return getLimitedConfigurationsFn(getConfigurationSections(models, definition, schema), limited); + return getLimitedConfigurationsFn(getConfigurationSections(models, definition, definition.overrideSchema ? definition.overrideSchema(schema, models) : schema), limited); } From 86578f52eb12193576b8b7c170b9e19ce3d10151 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 22 Oct 2021 17:20:52 -0700 Subject: [PATCH 06/30] SHIBUI-2189 When filter is disabled, do not include it in the xml generation --- .../service/JPAMetadataResolverServiceImpl.groovy | 7 +++++-- ...ommonJPAMetadataResolverServiceImplTests.groovy | 7 +++++-- .../JPAMetadataResolverServiceImplTests.groovy | 14 ++++++++++++++ .../admin/ui/util/TestObjectGenerator.groovy | 9 +++++++++ backend/src/test/resources/conf/661.3.xml | 2 ++ 5 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 backend/src/test/resources/conf/661.3.xml diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImpl.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImpl.groovy index 049869b64..fdc9cf799 100644 --- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImpl.groovy +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImpl.groovy @@ -89,6 +89,7 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { } void constructXmlNodeForFilter(EntityAttributesFilter filter, def markupBuilderDelegate) { + if (!filter.isFilterEnabled()) { return } markupBuilderDelegate.MetadataFilter('xsi:type': 'EntityAttributes') { // TODO: enhance. currently this does weird things with namespaces filter.attributes.each { attribute -> @@ -459,8 +460,10 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { } } mr.metadataFilters.each { edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter filter -> - doNamespaceProtectionFilter() - constructXmlNodeForFilter(filter, delegate) + if (filter.isFilterEnabled()) { + doNamespaceProtectionFilter() + constructXmlNodeForFilter(filter, delegate) + } } doNamespaceProtectionFilter() } diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/IncommonJPAMetadataResolverServiceImplTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/IncommonJPAMetadataResolverServiceImplTests.groovy index a44b4beed..378995e99 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/IncommonJPAMetadataResolverServiceImplTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/IncommonJPAMetadataResolverServiceImplTests.groovy @@ -38,7 +38,7 @@ class IncommonJPAMetadataResolverServiceImplTests extends AbstractBaseDataJpaTes def 'simple test generation of metadata-providers.xml'() { when: def mr = metadataResolverRepository.findAll().iterator().next() - mr.metadataFilters << new SignatureValidationFilter(requireSignedRoot: true, certificateFile: '%{idp.home}/credentials/inc-md-cert.pem') + mr.metadataFilters << new SignatureValidationFilter(enabled: true, requireSignedRoot: true, certificateFile: '%{idp.home}/credentials/inc-md-cert.pem') mr.metadataFilters << requiredValidUntilFilterForXmlGenerationTests() mr.metadataFilters << entityRoleWhiteListFilterForXmlGenerationTests() metadataResolverRepository.save(mr) @@ -52,9 +52,10 @@ class IncommonJPAMetadataResolverServiceImplTests extends AbstractBaseDataJpaTes when: //TODO: this might break later def mr = metadataResolverRepository.findAll().iterator().next() - mr.metadataFilters << new SignatureValidationFilter(requireSignedRoot: true, certificateFile: '%{idp.home}/credentials/inc-md-cert.pem') + mr.metadataFilters << new SignatureValidationFilter(enabled: true, requireSignedRoot: true, certificateFile: '%{idp.home}/credentials/inc-md-cert.pem') mr.metadataFilters << requiredValidUntilFilterForXmlGenerationTests() mr.metadataFilters.add(new EntityAttributesFilter().with { + it.enabled = true it.entityAttributesFilterTarget = new EntityAttributesFilterTarget().with { it.entityAttributesFilterTargetType = EntityAttributesFilterTarget.EntityAttributesFilterTargetType.ENTITY it.value = ['https://sp1.example.org'] @@ -81,6 +82,7 @@ class IncommonJPAMetadataResolverServiceImplTests extends AbstractBaseDataJpaTes EntityRoleWhiteListFilter entityRoleWhiteListFilterForXmlGenerationTests() { new EntityRoleWhiteListFilter().with { it.retainedRoles = ['md:SPSSODescriptor'] + it.enabled = true it } } @@ -88,6 +90,7 @@ class IncommonJPAMetadataResolverServiceImplTests extends AbstractBaseDataJpaTes RequiredValidUntilFilter requiredValidUntilFilterForXmlGenerationTests() { new RequiredValidUntilFilter().with { it.maxValidityInterval = 'P14D' + it.enabled = true it } } diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy index 28ba48d30..1bdee5a70 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy @@ -149,6 +149,20 @@ class JPAMetadataResolverServiceImplTests extends AbstractBaseDataJpaTest { generatedXmlIsTheSameAsExpectedXml('/conf/661.xml', domBuilder.parseText(writer.toString())) } + def 'test generating xml when filter is disabled'() { + given: + def filter = testObjectGenerator.entityAttributesFilterWithConditionScript() + filter.setEnabled(Boolean.FALSE) + + when: + genXmlSnippet(markupBuilder) { + JPAMetadataResolverServiceImpl.cast(metadataResolverService).constructXmlNodeForFilter(filter, it) + } + + then: + generatedXmlIsTheSameAsExpectedXml('/conf/661.3.xml', domBuilder.parseText(writer.toString())) + } + def 'test generating EntityAttributesFilter xml snippet with regex'() { given: def filter = testObjectGenerator.entityAttributesFilterWithRegex() diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestObjectGenerator.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestObjectGenerator.groovy index 7ed0709df..bf17b107e 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestObjectGenerator.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestObjectGenerator.groovy @@ -193,6 +193,7 @@ class TestObjectGenerator { it.dynamicTrustedNamesStrategyRef = generator.randomString(10) it.trustEngineRef = generator.randomString(10) it.publicKey = generator.randomString(50) + it.enabled = true; it } } @@ -202,6 +203,7 @@ class TestObjectGenerator { it.name = 'EntityRoleWhiteList' it.retainedRoles = ['role1', 'role2'] it.removeRolelessEntityDescriptors = true + it.enabled = true; it } } @@ -212,6 +214,7 @@ class TestObjectGenerator { it.setEntityAttributesFilterTarget(buildEntityAttributesFilterTarget()) it.setAttributes(buildAttributesList()) it.intoTransientRepresentation() + it.enabled = true; it } } @@ -221,6 +224,7 @@ class TestObjectGenerator { it.name = 'EntityAttributes' it.setEntityAttributesFilterTarget(buildEntityAttributesFilterTargetWithConditionScript()) it.intoTransientRepresentation() + it.enabled = true; it } } @@ -230,6 +234,7 @@ class TestObjectGenerator { it.name = 'EntityAttributes' it.setEntityAttributesFilterTarget(buildEntityAttributesFilterTargetWithRegex()) it.intoTransientRepresentation() + it.enabled = true; it } } @@ -237,6 +242,7 @@ class TestObjectGenerator { RequiredValidUntilFilter requiredValidUntilFilter() { return new RequiredValidUntilFilter().with { it.maxValidityInterval = 'P14D' + it.enabled = true; it } } @@ -246,6 +252,7 @@ class TestObjectGenerator { it.name = "NameIDFormat" it.formats = ['urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'] it.setNameIdFormatFilterTarget(new NameIdFormatFilterTarget(nameIdFormatFilterTargetType: ENTITY, singleValue: 'https://sp1.example.org')) + it.enabled = true; it } } @@ -255,6 +262,7 @@ class TestObjectGenerator { it.name = requiredValidUntilFilter.name it.resourceId = requiredValidUntilFilter.resourceId it.maxValidityInterval = requiredValidUntilFilter.maxValidityInterval + it.enabled = true; it } } @@ -270,6 +278,7 @@ class TestObjectGenerator { it.requireSignedRoot = signatureValidationFilter.requireSignedRoot it.certificateFile = signatureValidationFilter.certificateFile it.defaultCriteriaRef = signatureValidationFilter.defaultCriteriaRef + it.enabled = true; it } } diff --git a/backend/src/test/resources/conf/661.3.xml b/backend/src/test/resources/conf/661.3.xml new file mode 100644 index 000000000..39eabfe8e --- /dev/null +++ b/backend/src/test/resources/conf/661.3.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file From 58937ed976721d14c16c39813dc887bbae75e71f Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 22 Oct 2021 17:46:34 -0700 Subject: [PATCH 07/30] SHIBUI-2217 When filter is disabled, do not include it in the xml generation --- .../admin/ui/service/JPAMetadataResolverServiceImpl.groovy | 4 ++++ .../ui/service/JPAMetadataResolverServiceImplTests.groovy | 1 + 2 files changed, 5 insertions(+) diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImpl.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImpl.groovy index fdc9cf799..79420f6d0 100644 --- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImpl.groovy +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImpl.groovy @@ -129,6 +129,7 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { // TODO: enhance void constructXmlNodeForFilter(EntityRoleWhiteListFilter filter, def markupBuilderDelegate) { + if (!filter.isFilterEnabled()) { return } if (!filter.retainedRoles?.isEmpty()) { markupBuilderDelegate.MetadataFilter( 'xsi:type': 'EntityRoleWhiteList', @@ -143,6 +144,7 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { } void constructXmlNodeForFilter(NameIdFormatFilter filter, def markupBuilderDelegate) { + if (!filter.isFilterEnabled()) { return } def type = filter.nameIdFormatFilterTarget.nameIdFormatFilterTargetType markupBuilderDelegate.MetadataFilter( 'xsi:type': 'NameIDFormat', @@ -181,6 +183,7 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { } void constructXmlNodeForFilter(RequiredValidUntilFilter filter, def markupBuilderDelegate) { + if (!filter.isFilterEnabled()) { return } if (filter.xmlShouldBeGenerated()) { markupBuilderDelegate.MetadataFilter( 'xsi:type': 'RequiredValidUntil', @@ -190,6 +193,7 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { } void constructXmlNodeForFilter(SignatureValidationFilter filter, def markupBuilderDelegate) { + if (!filter.isFilterEnabled()) { return } if (filter.xmlShouldBeGenerated()) { markupBuilderDelegate.MetadataFilter(id: filter.name, 'xsi:type': 'SignatureValidation', diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy index 1bdee5a70..703e44f7a 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy @@ -191,6 +191,7 @@ class JPAMetadataResolverServiceImplTests extends AbstractBaseDataJpaTest { def 'test generating RequiredValidUntilFilter xml snippet'() { given: def filter = new RequiredValidUntilFilter().with { + it.enabled = true it.maxValidityInterval = 'P14D' it } From c8d4aeb22ea89af33618e99011bd6b8547e902eb Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Fri, 22 Oct 2021 15:03:35 -0700 Subject: [PATCH 08/30] Fixed heading type / color --- ui/src/app/core/components/Header.js | 2 +- ui/src/theme/project/typography.scss | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ui/src/app/core/components/Header.js b/ui/src/app/core/components/Header.js index 7bb693b1e..214be0d93 100644 --- a/ui/src/app/core/components/Header.js +++ b/ui/src/app/core/components/Header.js @@ -31,7 +31,7 @@ export function Header () { {brand.logo.alt} - + {loading ?
diff --git a/ui/src/theme/project/typography.scss b/ui/src/theme/project/typography.scss index 058e6666d..dbc6b09a0 100644 --- a/ui/src/theme/project/typography.scss +++ b/ui/src/theme/project/typography.scss @@ -18,4 +18,11 @@ line-height: 1.5; border-radius: 0.2rem; display: block; +} + +.navbar-light .navbar-text { + font-size: 1rem; + font-weight: normal; + margin: 0; + color: rgba(0, 0, 0, 0.75); } \ No newline at end of file From f55fc6a33718335be29226883659adf9a4784f27 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 25 Oct 2021 07:40:22 -0700 Subject: [PATCH 09/30] Fixed accessibility issues --- ui/src/app/core/components/Header.js | 2 +- ui/src/app/form/component/IconButton.js | 3 +- ui/src/app/form/component/InfoIcon.js | 1 + .../component/templates/ArrayFieldTemplate.js | 16 ++++---- .../form/component/widgets/OptionWidget.js | 14 ++++--- .../form/component/widgets/SelectWidget.js | 2 +- .../app/form/component/widgets/TextWidget.js | 2 +- ui/src/app/metadata/copy/CopySource.js | 37 ++++++++++--------- .../domain/source/component/SourceList.js | 6 ++- ui/src/app/metadata/view/MetadataUpload.js | 2 +- 10 files changed, 48 insertions(+), 37 deletions(-) diff --git a/ui/src/app/core/components/Header.js b/ui/src/app/core/components/Header.js index 214be0d93..2a7d32e8c 100644 --- a/ui/src/app/core/components/Header.js +++ b/ui/src/app/core/components/Header.js @@ -26,7 +26,7 @@ export function Header () { const loading = useCurrentUserLoading(); return ( - + {brand.logo.alt} diff --git a/ui/src/app/form/component/IconButton.js b/ui/src/app/form/component/IconButton.js index 5cac9c37d..489345676 100644 --- a/ui/src/app/form/component/IconButton.js +++ b/ui/src/app/form/component/IconButton.js @@ -11,11 +11,12 @@ const mappings = { "arrow-down": , }; -const IconButton = (props) => { +const IconButton = ({children, ...props}) => { const { icon, ...otherProps } = props; return ( ); }; diff --git a/ui/src/app/form/component/InfoIcon.js b/ui/src/app/form/component/InfoIcon.js index 989428435..d813fe777 100644 --- a/ui/src/app/form/component/InfoIcon.js +++ b/ui/src/app/form/component/InfoIcon.js @@ -17,6 +17,7 @@ export function InfoIcon ({ value, placement='left', ...props }) { )} aria-label={translate('tooltip.instruction')}> diff --git a/ui/src/app/form/component/templates/ArrayFieldTemplate.js b/ui/src/app/form/component/templates/ArrayFieldTemplate.js index e138c10a0..637e7f7ea 100644 --- a/ui/src/app/form/component/templates/ArrayFieldTemplate.js +++ b/ui/src/app/form/component/templates/ArrayFieldTemplate.js @@ -86,7 +86,7 @@ const ObjectArrayItem = ({type, ...props}) => { props.disabled || props.readonly || !props.hasMoveUp } onClick={props.onReorderClick(props.index, props.index - 1)} - /> + >Move Up
)} @@ -100,7 +100,7 @@ const ObjectArrayItem = ({type, ...props}) => { props.disabled || props.readonly || !props.hasMoveDown } onClick={props.onReorderClick(props.index, props.index + 1)} - /> + >Move Down )} @@ -114,7 +114,7 @@ const ObjectArrayItem = ({type, ...props}) => { style={btnStyle} disabled={props.disabled || props.readonly} onClick={props.onDropIndexClick(props.index)} - /> + >Delete )} @@ -156,7 +156,7 @@ const DefaultArrayItem = (props) => { props.disabled || props.readonly || !props.hasMoveUp } onClick={props.onReorderClick(props.index, props.index - 1)} - /> + >Move Up )} @@ -170,7 +170,7 @@ const DefaultArrayItem = (props) => { props.disabled || props.readonly || !props.hasMoveDown } onClick={props.onReorderClick(props.index, props.index + 1)} - /> + >Move Down )} @@ -184,7 +184,7 @@ const DefaultArrayItem = (props) => { style={btnStyle} disabled={props.disabled || props.readonly} onClick={props.onDropIndexClick(props.index)} - /> + >Delete )} @@ -210,7 +210,7 @@ const DefaultFixedArrayFieldTemplate = (props) => { className="array-item-add" onClick={props.onAddClick} disabled={props.disabled || props.readonly} - /> + >Add )} @@ -254,7 +254,7 @@ const DefaultNormalArrayFieldTemplate = (props) => { className="array-item-add mx-2" onClick={props.onAddClick} disabled={props.disabled || props.readonly} - /> + >Add )} {(props.uiSchema["ui:description"] || props.schema.description) && ( ( +const ToggleButton = ({ isOpen, onClick, disabled, children }) => ( ); @@ -91,15 +92,16 @@ const OptionWidget = ({ return ( - 0) ? "text-danger" : ""}`}> + 0) ? "text-danger" : ""}`} htmlFor={`option-selector-${id}`}> - {(label || schema.title) && required ? : null} + {(label || schema.title) && required ? : Item {id + 1}} {schema.description && } {({ isMenuShown, toggleMenu }) => ( - toggleMenu()} disabled={disabled || readonly} /> + toggleMenu()} disabled={disabled || readonly}> + Options + )} {rawErrors?.length > 0 && touched && ( diff --git a/ui/src/app/form/component/widgets/SelectWidget.js b/ui/src/app/form/component/widgets/SelectWidget.js index 76dc99ec6..a2ad763e6 100644 --- a/ui/src/app/form/component/widgets/SelectWidget.js +++ b/ui/src/app/form/component/widgets/SelectWidget.js @@ -86,7 +86,7 @@ const SelectWidget = ({ return ( - 0 ? "text-danger" : ""}`}> + 0 ? "text-danger" : ""}`} htmlFor={id}> {(label || schema.title) && required ? : null} diff --git a/ui/src/app/form/component/widgets/TextWidget.js b/ui/src/app/form/component/widgets/TextWidget.js index 8554be911..c4150e0f2 100644 --- a/ui/src/app/form/component/widgets/TextWidget.js +++ b/ui/src/app/form/component/widgets/TextWidget.js @@ -41,7 +41,7 @@ const TextWidget = ({ // const classNames = [rawErrors?.length > 0 ? "is-invalid" : "", type === 'file' ? 'custom-file-label': ""] return ( - 0 && touched ? "text-danger" : ""}`}> + 0 && touched ? "text-danger" : ""}`} htmlFor={id}> {(label || schema.title) && required ? diff --git a/ui/src/app/metadata/copy/CopySource.js b/ui/src/app/metadata/copy/CopySource.js index 65e90a5e5..1034acde5 100644 --- a/ui/src/app/metadata/copy/CopySource.js +++ b/ui/src/app/metadata/copy/CopySource.js @@ -59,6 +59,10 @@ export function CopySource({ copy, onNext }) { setValue('properties', selected); }, [selected, setValue]); + React.useEffect(() => { + console.log(errors, formState); + }, [errors, formState]); + return ( <>
@@ -100,12 +104,10 @@ export function CopySource({ copy, onNext }) { - {errors?.target?.type === 'required' && + className={`form-text text-danger ${errors?.target?.type === 'required' ? '' : 'sr-only'}`}> Entity ID to copy is Required - }
@@ -156,14 +156,15 @@ export function CopySource({ copy, onNext }) { {sections.map((item, i) => - + onSelect(item, checked)} checked={selected.indexOf(item.property) > -1} + aria-labelledby={`property-checkbox-${i}`} /> diff --git a/ui/src/app/metadata/domain/source/component/SourceList.js b/ui/src/app/metadata/domain/source/component/SourceList.js index 41ce7f0cd..baf249c9f 100644 --- a/ui/src/app/metadata/domain/source/component/SourceList.js +++ b/ui/src/app/metadata/domain/source/component/SourceList.js @@ -35,7 +35,11 @@ export default function SourceList({ entities, onDelete, onEnable, onChangeGroup Created Date Enabled {isAdmin && onChangeGroup && Group } - {onDelete && isAdmin && } + {onDelete && isAdmin && + + Actions + + } diff --git a/ui/src/app/metadata/view/MetadataUpload.js b/ui/src/app/metadata/view/MetadataUpload.js index 3c6ce4598..28b953ff4 100644 --- a/ui/src/app/metadata/view/MetadataUpload.js +++ b/ui/src/app/metadata/view/MetadataUpload.js @@ -142,7 +142,7 @@ export function MetadataUpload() { —
- + 0 } type="text" className="form-control"{...register('url')} />
From fea89d1e5778b49457102e78128c7f719d7a526c Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 25 Oct 2021 09:10:18 -0700 Subject: [PATCH 10/30] Fixed placeholder text problems --- .../resources/dynamic-http-metadata-provider.schema.json | 2 +- .../resources/file-system-metadata-provider.schema.json | 2 +- .../resources/filebacked-http-metadata-provider.schema.json | 2 +- backend/src/main/resources/i18n/messages.properties | 6 ++++-- backend/src/main/resources/i18n/messages_en.properties | 2 +- .../resources/local-dynamic-metadata-provider.schema.json | 2 +- ui/src/app/form/component/fields/FilterTargetField.js | 2 +- .../domain/filter/definition/BaseFilterDefinition.js | 2 +- 8 files changed, 11 insertions(+), 9 deletions(-) diff --git a/backend/src/main/resources/dynamic-http-metadata-provider.schema.json b/backend/src/main/resources/dynamic-http-metadata-provider.schema.json index 8be8bbf9b..dd03b63da 100644 --- a/backend/src/main/resources/dynamic-http-metadata-provider.schema.json +++ b/backend/src/main/resources/dynamic-http-metadata-provider.schema.json @@ -9,7 +9,7 @@ "properties": { "name": { "title": "label.metadata-provider-name-dashboard-display-only", - "description": "tooltip.metadata-provider-name-dashboard-display-only", + "description": "tooltip.metadata-provider-name", "type": "string" }, "@type": { diff --git a/backend/src/main/resources/file-system-metadata-provider.schema.json b/backend/src/main/resources/file-system-metadata-provider.schema.json index d238018b9..7969495f2 100644 --- a/backend/src/main/resources/file-system-metadata-provider.schema.json +++ b/backend/src/main/resources/file-system-metadata-provider.schema.json @@ -9,7 +9,7 @@ "properties": { "name": { "title": "label.metadata-provider-name-dashboard-display-only", - "description": "tooltip.metadata-provider-name-dashboard-display-only", + "description": "tooltip.metadata-provider-name", "type": "string", "widget": { "id": "string", diff --git a/backend/src/main/resources/filebacked-http-metadata-provider.schema.json b/backend/src/main/resources/filebacked-http-metadata-provider.schema.json index 9ce22ca94..f678ee306 100644 --- a/backend/src/main/resources/filebacked-http-metadata-provider.schema.json +++ b/backend/src/main/resources/filebacked-http-metadata-provider.schema.json @@ -28,7 +28,7 @@ "properties": { "name": { "title": "label.metadata-provider-name-dashboard-display-only", - "description": "tooltip.metadata-provider-name-dashboard-display-only", + "description": "tooltip.metadata-provider-name", "type": "string", "widget": { "id": "string", diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index 4c22a97ff..d77f9be0f 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -662,7 +662,7 @@ tooltip.max-cache-entry-size=The maximum response body size that may be cached, tooltip.metadata-provider-name=Metadata Provider Name (for display on the Dashboard only) tooltip.metadata-provider-type=Metadata Provider Type tooltip.xml-id=Identifier for logging, identification for command line reload, etc. -tooltip.metadata-url=Identifier for logging, identification for command line reload, etc. +tooltip.metadata-url=The URL that the metadata is served from. tooltip.metadata-file=The absolute path to the local metadata file to be loaded. tooltip.init-from-backup=Flag indicating whether initialization should first attempt to load metadata from the backup file. If true, foreground initialization will be performed by loading the backing file, and then a refresh from the remote HTTP server will be scheduled to execute in a background thread, after a configured delay. This can improve IdP startup times when the remote HTTP file is large in size. tooltip.backing-file=Specifies where the backing file is located. If the remote server is unavailable at startup, the backing file is loaded instead. @@ -718,4 +718,6 @@ tooltip.group-name=Group Name tooltip.group-description=Group Description tooltip.role-name=Role Name -tooltip.role-description=Role Description \ No newline at end of file +tooltip.role-description=Role Description + +tooltip.contact-information=Contact Information \ No newline at end of file diff --git a/backend/src/main/resources/i18n/messages_en.properties b/backend/src/main/resources/i18n/messages_en.properties index 2fa33ffa9..f9f64d4d2 100644 --- a/backend/src/main/resources/i18n/messages_en.properties +++ b/backend/src/main/resources/i18n/messages_en.properties @@ -513,7 +513,7 @@ tooltip.max-cache-entry-size=The maximum response body size that may be cached, tooltip.metadata-provider-name=Metadata Provider Name (for display on the Dashboard only) tooltip.metadata-provider-type=Metadata Provider Type tooltip.xml-id=Identifier for logging, identification for command line reload, etc. -tooltip.metadata-url=Identifier for logging, identification for command line reload, etc. +tooltip.metadata-url=The URL that the metadata is served from. tooltip.metadata-file=The absolute path to the local metadata file to be loaded. tooltip.init-from-backup=Flag indicating whether initialization should first attempt to load metadata from the backup file. If true, foreground initialization will be performed by loading the backing file, and then a refresh from the remote HTTP server will be scheduled to execute in a background thread, after a configured delay. This can improve IdP startup times when the remote HTTP file is large in size. tooltip.backing-file=Specifies where the backing file is located. If the remote server is unavailable at startup, the backing file is loaded instead. diff --git a/backend/src/main/resources/local-dynamic-metadata-provider.schema.json b/backend/src/main/resources/local-dynamic-metadata-provider.schema.json index 1b1951dac..6e81a0a90 100644 --- a/backend/src/main/resources/local-dynamic-metadata-provider.schema.json +++ b/backend/src/main/resources/local-dynamic-metadata-provider.schema.json @@ -9,7 +9,7 @@ "properties": { "name": { "title": "label.metadata-provider-name-dashboard-display-only", - "description": "tooltip.metadata-provider-name-dashboard-display-only", + "description": "tooltip.metadata-provider-name", "type": "string", "widget": { "id": "string", diff --git a/ui/src/app/form/component/fields/FilterTargetField.js b/ui/src/app/form/component/fields/FilterTargetField.js index b9d44c725..49f3663e2 100644 --- a/ui/src/app/form/component/fields/FilterTargetField.js +++ b/ui/src/app/form/component/fields/FilterTargetField.js @@ -162,7 +162,7 @@ const FilterTargetField = ({ - +
diff --git a/ui/src/app/metadata/domain/filter/definition/BaseFilterDefinition.js b/ui/src/app/metadata/domain/filter/definition/BaseFilterDefinition.js index 8bdf9bfab..c0e04a5ac 100644 --- a/ui/src/app/metadata/domain/filter/definition/BaseFilterDefinition.js +++ b/ui/src/app/metadata/domain/filter/definition/BaseFilterDefinition.js @@ -11,7 +11,7 @@ export const BaseFilterDefinition = { return (formData, errors) => { if (names.indexOf(formData.name) > -1) { - errors.name.addError('message.name-unique'); + errors.name.addError('message.name-must-be-unique'); } if (formData.hasOwnProperty(targetProp)) { From 8bde803226ed12b62af0e1aced1cada629aa40a6 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 25 Oct 2021 09:56:25 -0700 Subject: [PATCH 11/30] Fixed version comparison for providers --- ui/src/app/metadata/view/MetadataComparison.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ui/src/app/metadata/view/MetadataComparison.js b/ui/src/app/metadata/view/MetadataComparison.js index 05bfe6d82..1e3524435 100644 --- a/ui/src/app/metadata/view/MetadataComparison.js +++ b/ui/src/app/metadata/view/MetadataComparison.js @@ -17,6 +17,7 @@ import { useTranslation } from '../../i18n/hooks'; import { MetadataFilterVersionList } from '../domain/filter/component/MetadataFilterVersionList'; import { MetadataFilterVersionContext } from '../domain/filter/component/MetadataFilterVersionContext'; import { useMetadataSchema } from '../hooks/schema'; +import { FilterableProviders } from '../domain/provider'; export function MetadataComparison () { @@ -32,6 +33,8 @@ export function MetadataComparison () { const toggleLimited = useTranslation('action.view-only-changes'); + const canFilter = FilterableProviders.indexOf(definition.type) > -1; + return ( <>

@@ -61,7 +64,7 @@ export function MetadataComparison () {

- {type === 'provider' && v && + {type === 'provider' && canFilter && v &&

From 7d792b2090489b54a4772e1d574f47b5b33dfa6b Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 25 Oct 2021 11:18:15 -0700 Subject: [PATCH 12/30] Fixed error message on timeout --- .../src/main/resources/i18n/messages.properties | 1 + ui/src/app/metadata/view/MetadataWizard.js | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index 4c22a97ff..632916239 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -597,6 +597,7 @@ message.invalid-signing=Unless the response or the assertions are signed, SAML s message.session-timeout-heading=Session timed out message.session-timeout-body=Your session has timed out. Please login again. +message.session-timeout=An error has occurred while saving. Your session may have timed out. tooltip.entity-id=Entity ID tooltip.service-provider-name=Service Provider Name (Dashboard Display Only) diff --git a/ui/src/app/metadata/view/MetadataWizard.js b/ui/src/app/metadata/view/MetadataWizard.js index 4a4b4b5c7..6ba534ffd 100644 --- a/ui/src/app/metadata/view/MetadataWizard.js +++ b/ui/src/app/metadata/view/MetadataWizard.js @@ -7,10 +7,12 @@ import { Wizard } from '../wizard/Wizard'; import { useMetadataEntity } from '../hooks/api'; import { createNotificationAction, NotificationTypes, useNotificationDispatcher } from '../../notifications/hoc/Notifications'; import { Prompt, useHistory } from 'react-router'; +import { useTranslator } from '../../i18n/hooks'; export function MetadataWizard ({type, data, onCallback}) { const history = useHistory(); + const translator = useTranslator(); const { post, loading, response } = useMetadataEntity(type === 'source' ? 'source' : 'provider'); @@ -19,15 +21,21 @@ export function MetadataWizard ({type, data, onCallback}) { const [blocking, setBlocking] = React.useState(false); async function save(metadata) { - console.log(metadata); await post('', metadata); if (response.ok) { setBlocking(false); history.push(`/dashboard/metadata/manager/${type === 'source' ? 'resolvers' : 'providers'}`); } else { - const { errorCode, errorMessage, cause } = response.data; + let msg; + if (response.status) { + const { errorCode, errorMessage, cause } = response.data; + msg = `${errorCode}: ${errorMessage} ${cause ? `-${cause}` : ''}`; + } else { + msg = translator('message.session-timeout'); + } + notificationDispatch(createNotificationAction( - `${errorCode}: ${errorMessage} ${cause ? `-${cause}` : ''}`, + msg, NotificationTypes.ERROR )); } From 1fcda5584b4e3cc646f5e41f3bffe8f36814c632 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 25 Oct 2021 11:18:15 -0700 Subject: [PATCH 13/30] Fixed error message on timeout --- .../src/main/resources/i18n/messages.properties | 1 + ui/src/app/metadata/view/MetadataWizard.js | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index 4c22a97ff..632916239 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -597,6 +597,7 @@ message.invalid-signing=Unless the response or the assertions are signed, SAML s message.session-timeout-heading=Session timed out message.session-timeout-body=Your session has timed out. Please login again. +message.session-timeout=An error has occurred while saving. Your session may have timed out. tooltip.entity-id=Entity ID tooltip.service-provider-name=Service Provider Name (Dashboard Display Only) diff --git a/ui/src/app/metadata/view/MetadataWizard.js b/ui/src/app/metadata/view/MetadataWizard.js index 4a4b4b5c7..6ba534ffd 100644 --- a/ui/src/app/metadata/view/MetadataWizard.js +++ b/ui/src/app/metadata/view/MetadataWizard.js @@ -7,10 +7,12 @@ import { Wizard } from '../wizard/Wizard'; import { useMetadataEntity } from '../hooks/api'; import { createNotificationAction, NotificationTypes, useNotificationDispatcher } from '../../notifications/hoc/Notifications'; import { Prompt, useHistory } from 'react-router'; +import { useTranslator } from '../../i18n/hooks'; export function MetadataWizard ({type, data, onCallback}) { const history = useHistory(); + const translator = useTranslator(); const { post, loading, response } = useMetadataEntity(type === 'source' ? 'source' : 'provider'); @@ -19,15 +21,21 @@ export function MetadataWizard ({type, data, onCallback}) { const [blocking, setBlocking] = React.useState(false); async function save(metadata) { - console.log(metadata); await post('', metadata); if (response.ok) { setBlocking(false); history.push(`/dashboard/metadata/manager/${type === 'source' ? 'resolvers' : 'providers'}`); } else { - const { errorCode, errorMessage, cause } = response.data; + let msg; + if (response.status) { + const { errorCode, errorMessage, cause } = response.data; + msg = `${errorCode}: ${errorMessage} ${cause ? `-${cause}` : ''}`; + } else { + msg = translator('message.session-timeout'); + } + notificationDispatch(createNotificationAction( - `${errorCode}: ${errorMessage} ${cause ? `-${cause}` : ''}`, + msg, NotificationTypes.ERROR )); } From e0b202292b2d91182aa0c795e1ac67076a855d7d Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 25 Oct 2021 11:20:28 -0700 Subject: [PATCH 14/30] Revert "Fixed error message on timeout" This reverts commit 7d792b2090489b54a4772e1d574f47b5b33dfa6b. --- .../src/main/resources/i18n/messages.properties | 1 - ui/src/app/metadata/view/MetadataWizard.js | 14 +++----------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index 632916239..4c22a97ff 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -597,7 +597,6 @@ message.invalid-signing=Unless the response or the assertions are signed, SAML s message.session-timeout-heading=Session timed out message.session-timeout-body=Your session has timed out. Please login again. -message.session-timeout=An error has occurred while saving. Your session may have timed out. tooltip.entity-id=Entity ID tooltip.service-provider-name=Service Provider Name (Dashboard Display Only) diff --git a/ui/src/app/metadata/view/MetadataWizard.js b/ui/src/app/metadata/view/MetadataWizard.js index 6ba534ffd..4a4b4b5c7 100644 --- a/ui/src/app/metadata/view/MetadataWizard.js +++ b/ui/src/app/metadata/view/MetadataWizard.js @@ -7,12 +7,10 @@ import { Wizard } from '../wizard/Wizard'; import { useMetadataEntity } from '../hooks/api'; import { createNotificationAction, NotificationTypes, useNotificationDispatcher } from '../../notifications/hoc/Notifications'; import { Prompt, useHistory } from 'react-router'; -import { useTranslator } from '../../i18n/hooks'; export function MetadataWizard ({type, data, onCallback}) { const history = useHistory(); - const translator = useTranslator(); const { post, loading, response } = useMetadataEntity(type === 'source' ? 'source' : 'provider'); @@ -21,21 +19,15 @@ export function MetadataWizard ({type, data, onCallback}) { const [blocking, setBlocking] = React.useState(false); async function save(metadata) { + console.log(metadata); await post('', metadata); if (response.ok) { setBlocking(false); history.push(`/dashboard/metadata/manager/${type === 'source' ? 'resolvers' : 'providers'}`); } else { - let msg; - if (response.status) { - const { errorCode, errorMessage, cause } = response.data; - msg = `${errorCode}: ${errorMessage} ${cause ? `-${cause}` : ''}`; - } else { - msg = translator('message.session-timeout'); - } - + const { errorCode, errorMessage, cause } = response.data; notificationDispatch(createNotificationAction( - msg, + `${errorCode}: ${errorMessage} ${cause ? `-${cause}` : ''}`, NotificationTypes.ERROR )); } From cc9cd4b8c3f9c2aded2080042c3327ec9827cd88 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 25 Oct 2021 11:38:52 -0700 Subject: [PATCH 15/30] Fixed error response when updating group --- ui/src/app/admin/container/MetadataActions.js | 14 +++++++++++++- ui/src/app/dashboard/view/SourcesTab.js | 8 +++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/ui/src/app/admin/container/MetadataActions.js b/ui/src/app/admin/container/MetadataActions.js index 4af521db5..4ed567d23 100644 --- a/ui/src/app/admin/container/MetadataActions.js +++ b/ui/src/app/admin/container/MetadataActions.js @@ -2,7 +2,7 @@ import React from 'react'; import { DeleteConfirmation } from '../../core/components/DeleteConfirmation'; import { useMetadataActivator, useMetadataEntity } from '../../metadata/hooks/api'; -import { NotificationContext, createNotificationAction } from '../../notifications/hoc/Notifications'; +import { NotificationContext, createNotificationAction, NotificationTypes } from '../../notifications/hoc/Notifications'; export function MetadataActions ({type, children}) { @@ -21,6 +21,12 @@ export function MetadataActions ({type, children}) { `Metadata ${type} has been ${enabled ? 'enabled' : 'disabled'}.` )); cb(); + } else { + const { errorCode, errorMessage, cause } = activator?.response?.data; + dispatch(createNotificationAction( + `${errorCode}: ${errorMessage} ${cause ? `-${cause}` : ''}`, + NotificationTypes.ERROR + )); } } @@ -31,6 +37,12 @@ export function MetadataActions ({type, children}) { `Metadata ${type} has been deleted.` )); cb(); + } else { + const { errorCode, errorMessage, cause } = activator?.response?.data; + dispatch(createNotificationAction( + `${errorCode}: ${errorMessage} ${cause ? `-${cause}` : ''}`, + NotificationTypes.ERROR + )); } } diff --git a/ui/src/app/dashboard/view/SourcesTab.js b/ui/src/app/dashboard/view/SourcesTab.js index 36cdc1bdf..b564a3872 100644 --- a/ui/src/app/dashboard/view/SourcesTab.js +++ b/ui/src/app/dashboard/view/SourcesTab.js @@ -6,7 +6,7 @@ import SourceList from '../../metadata/domain/source/component/SourceList'; import { useMetadataEntities, useMetadataEntity } from '../../metadata/hooks/api'; import { Search } from '../component/Search'; -import { NotificationContext, createNotificationAction } from '../../notifications/hoc/Notifications'; +import { NotificationContext, createNotificationAction, NotificationTypes } from '../../notifications/hoc/Notifications'; const searchProps = ['serviceProviderName', 'entityId', 'createdBy']; @@ -42,6 +42,12 @@ export function SourcesTab () { if (updater.response.ok) { dispatch(createNotificationAction(`Updated group successfully.`)); loadSources(); + } else { + const { errorCode, errorMessage, cause } = updater?.response?.data; + dispatch(createNotificationAction( + `${errorCode}: ${errorMessage} ${cause ? `-${cause}` : ''}`, + NotificationTypes.ERROR + )); } } From 6611a46975078d21ed7318346c3818f889dfc838 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 25 Oct 2021 12:16:44 -0700 Subject: [PATCH 16/30] Added enabled properties to version comparison --- .../domain/filter/definition/BaseFilterDefinition.js | 5 ++++- .../filter/definition/EntityAttributesFilterDefinition.js | 3 ++- .../domain/filter/definition/NameIdFilterDefinition.js | 3 ++- .../domain/provider/definition/BaseProviderDefinition.js | 3 +++ .../definition/DynamicHttpMetadataProviderDefinition.js | 3 ++- .../FileBackedHttpMetadataProviderDefinition.js | 3 ++- .../definition/FileSystemMetadataProviderDefinition.js | 3 ++- .../definition/LocalDynamicMetadataProviderDefinition.js | 1 + .../metadata/domain/source/definition/SourceDefinition.js | 8 ++++++-- ui/src/testing/uiSchema.js | 3 +++ 10 files changed, 27 insertions(+), 8 deletions(-) diff --git a/ui/src/app/metadata/domain/filter/definition/BaseFilterDefinition.js b/ui/src/app/metadata/domain/filter/definition/BaseFilterDefinition.js index 8bdf9bfab..f23d6ad6e 100644 --- a/ui/src/app/metadata/domain/filter/definition/BaseFilterDefinition.js +++ b/ui/src/app/metadata/domain/filter/definition/BaseFilterDefinition.js @@ -38,7 +38,10 @@ export const BaseFilterDefinition = { '@type': { 'ui:widget': 'hidden' }, - 'resourceId': { + resourceId: { + 'ui:widget': 'hidden' + }, + filterEnabled: { 'ui:widget': 'hidden' } } diff --git a/ui/src/app/metadata/domain/filter/definition/EntityAttributesFilterDefinition.js b/ui/src/app/metadata/domain/filter/definition/EntityAttributesFilterDefinition.js index 7ef0e08a9..b12d476e9 100644 --- a/ui/src/app/metadata/domain/filter/definition/EntityAttributesFilterDefinition.js +++ b/ui/src/app/metadata/domain/filter/definition/EntityAttributesFilterDefinition.js @@ -75,7 +75,8 @@ export const EntityAttributesFilterEditor= { 'name', '@type', 'resourceId', - 'entityAttributesFilterTarget' + 'entityAttributesFilterTarget', + 'filterEnabled' ] }, { diff --git a/ui/src/app/metadata/domain/filter/definition/NameIdFilterDefinition.js b/ui/src/app/metadata/domain/filter/definition/NameIdFilterDefinition.js index 358b51b34..d7f1492b9 100644 --- a/ui/src/app/metadata/domain/filter/definition/NameIdFilterDefinition.js +++ b/ui/src/app/metadata/domain/filter/definition/NameIdFilterDefinition.js @@ -42,7 +42,8 @@ export const NameIDFilterEditor = { 'name', '@type', 'resourceId', - 'nameIdFormatFilterTarget' + 'nameIdFormatFilterTarget', + 'filterEnabled' ] }, { diff --git a/ui/src/app/metadata/domain/provider/definition/BaseProviderDefinition.js b/ui/src/app/metadata/domain/provider/definition/BaseProviderDefinition.js index 207eb0a2e..e67d53fc2 100644 --- a/ui/src/app/metadata/domain/provider/definition/BaseProviderDefinition.js +++ b/ui/src/app/metadata/domain/provider/definition/BaseProviderDefinition.js @@ -80,6 +80,9 @@ export const BaseProviderDefinition = { uiSchema: { name: { 'ui:help': 'message.must-be-unique' + }, + enabled: { + 'ui:widget': 'hidden' } }, steps: [ diff --git a/ui/src/app/metadata/domain/provider/definition/DynamicHttpMetadataProviderDefinition.js b/ui/src/app/metadata/domain/provider/definition/DynamicHttpMetadataProviderDefinition.js index 84b694e9a..ada2f8458 100644 --- a/ui/src/app/metadata/domain/provider/definition/DynamicHttpMetadataProviderDefinition.js +++ b/ui/src/app/metadata/domain/provider/definition/DynamicHttpMetadataProviderDefinition.js @@ -199,7 +199,8 @@ export const DynamicHttpMetadataProviderEditor = { 'xmlId', 'metadataRequestURLConstructionScheme', 'requireValidMetadata', - 'failFastInitialization' + 'failFastInitialization', + 'enabled' ] }, { diff --git a/ui/src/app/metadata/domain/provider/definition/FileBackedHttpMetadataProviderDefinition.js b/ui/src/app/metadata/domain/provider/definition/FileBackedHttpMetadataProviderDefinition.js index 5001895ce..106edfa55 100644 --- a/ui/src/app/metadata/domain/provider/definition/FileBackedHttpMetadataProviderDefinition.js +++ b/ui/src/app/metadata/domain/provider/definition/FileBackedHttpMetadataProviderDefinition.js @@ -198,7 +198,8 @@ export const FileBackedHttpMetadataProviderEditor = { 'requireValidMetadata', 'failFastInitialization', 'useDefaultPredicateRegistry', - 'satisfyAnyPredicates' + 'satisfyAnyPredicates', + 'enabled' ] }, { diff --git a/ui/src/app/metadata/domain/provider/definition/FileSystemMetadataProviderDefinition.js b/ui/src/app/metadata/domain/provider/definition/FileSystemMetadataProviderDefinition.js index 57d3447af..d97b8e041 100644 --- a/ui/src/app/metadata/domain/provider/definition/FileSystemMetadataProviderDefinition.js +++ b/ui/src/app/metadata/domain/provider/definition/FileSystemMetadataProviderDefinition.js @@ -107,7 +107,8 @@ export const FileSystemMetadataProviderEditor = { 'xmlId', '@type', 'metadataFile', - 'doInitialization' + 'doInitialization', + 'enabled' ], override: { '@type': { diff --git a/ui/src/app/metadata/domain/provider/definition/LocalDynamicMetadataProviderDefinition.js b/ui/src/app/metadata/domain/provider/definition/LocalDynamicMetadataProviderDefinition.js index eea5d3541..66b48d6c4 100644 --- a/ui/src/app/metadata/domain/provider/definition/LocalDynamicMetadataProviderDefinition.js +++ b/ui/src/app/metadata/domain/provider/definition/LocalDynamicMetadataProviderDefinition.js @@ -119,6 +119,7 @@ export const LocalDynamicMetadataProviderEditor = { '@type', 'xmlId', 'sourceDirectory', + 'enabled' ], override: { '@type': { diff --git a/ui/src/app/metadata/domain/source/definition/SourceDefinition.js b/ui/src/app/metadata/domain/source/definition/SourceDefinition.js index 6e2abdee3..70e686ed7 100644 --- a/ui/src/app/metadata/domain/source/definition/SourceDefinition.js +++ b/ui/src/app/metadata/domain/source/definition/SourceDefinition.js @@ -12,7 +12,7 @@ export const SourceBase = { type: '@MetadataProvider', steps: [], schema: `${API_BASE_PATH}/ui/MetadataSources`, - //schema: `/assets/schema/source/metadata-source.json`, + // schema: `/assets/schema/source/metadata-source.json`, parser: (data) => removeNull(data, true), @@ -158,6 +158,9 @@ export const SourceBase = { } ] }, + serviceEnabled: { + 'ui:widget': 'hidden' + }, contacts: { "ui:options": { orderable: false @@ -307,7 +310,8 @@ export const SourceEditor = { 'serviceProviderName', 'entityId', 'organization', - 'contacts' + 'contacts', + 'serviceEnabled' ] }, { diff --git a/ui/src/testing/uiSchema.js b/ui/src/testing/uiSchema.js index c1af6f4fa..8da257247 100644 --- a/ui/src/testing/uiSchema.js +++ b/ui/src/testing/uiSchema.js @@ -65,6 +65,9 @@ const schema = { ], "ui:widget": "hidden" }, + "serviceEnabled": { + "ui:widget": "hidden" + }, "contacts": { "ui:options": { "orderable": false From ef8ed60b93779b211c18bfd5ebbc721a7255df64 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 25 Oct 2021 13:54:05 -0700 Subject: [PATCH 17/30] Fixed validation messages --- ui/src/app/metadata/wizard/MetadataProviderTypeSelector.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ui/src/app/metadata/wizard/MetadataProviderTypeSelector.js b/ui/src/app/metadata/wizard/MetadataProviderTypeSelector.js index 5a091b2d2..dee44b681 100644 --- a/ui/src/app/metadata/wizard/MetadataProviderTypeSelector.js +++ b/ui/src/app/metadata/wizard/MetadataProviderTypeSelector.js @@ -44,6 +44,8 @@ export function MetadataProviderTypeSelector({ type, types = [], children}) { const providerNames = data.map(p => p.name); + console.log(errors); + return ( <>{showSelector ? <> @@ -90,8 +92,8 @@ export function MetadataProviderTypeSelector({ type, types = [], children}) { unique: v => !(providerNames.indexOf(v) > -1) }})} /> - {errors?.name?.unique && } - {errors?.name?.required && } + {errors?.name?.type === 'unique' && } + {errors?.name?.type === 'required' && } From f9fd5afb003bdf369b14306558f8dfa606b99f05 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 25 Oct 2021 14:10:58 -0700 Subject: [PATCH 18/30] Fixed warning message --- ui/src/app/metadata/editor/MetadataFilterEditor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/app/metadata/editor/MetadataFilterEditor.js b/ui/src/app/metadata/editor/MetadataFilterEditor.js index 2fe4f9ca9..21c764f41 100644 --- a/ui/src/app/metadata/editor/MetadataFilterEditor.js +++ b/ui/src/app/metadata/editor/MetadataFilterEditor.js @@ -60,7 +60,7 @@ export function MetadataFilterEditor({children, onNavigate, block}) {

} - {errors.length === 0 && warnings && warnings.hasOwnProperty(section) && + {warnings && warnings.hasOwnProperty(section) && {warnings[section].map((w, widx) =>

From 848d4c7948e1e6fdb5a3d0126a39af17b683700d Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 25 Oct 2021 14:26:16 -0700 Subject: [PATCH 19/30] Fixed appearance of buttons on Safari --- ui/src/theme/project/buttons.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ui/src/theme/project/buttons.scss b/ui/src/theme/project/buttons.scss index c1e8c5d79..df4a903ac 100644 --- a/ui/src/theme/project/buttons.scss +++ b/ui/src/theme/project/buttons.scss @@ -1,6 +1,10 @@ @import '../variables'; @import '~bootstrap/scss/_mixins'; +.btn { + -webkit-appearance: none; +} + .btn.btn-text { display: inline; padding: 0px; From d94dd6078160fa5c897785e5250da45e9d19f809 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 26 Oct 2021 09:51:03 -0700 Subject: [PATCH 20/30] Fixed group names in user dropdown --- ui/src/app/core/components/Header.js | 7 ++++--- ui/src/app/core/user/UserContext.js | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/ui/src/app/core/components/Header.js b/ui/src/app/core/components/Header.js index 7bb693b1e..ab4ae8804 100644 --- a/ui/src/app/core/components/Header.js +++ b/ui/src/app/core/components/Header.js @@ -13,7 +13,7 @@ import Translate from '../../i18n/components/translate'; import { useTranslator } from '../../i18n/hooks'; import { brand } from '../../app.brand'; -import { useCurrentUser, useCurrentUserLoading, useIsAdmin } from '../user/UserContext'; +import { useCurrentUser, useCurrentUserLoading, useIsAdmin, useUserGroupNames } from '../user/UserContext'; import { BASE_PATH } from '../../App.constant'; export function Header () { @@ -22,7 +22,8 @@ export function Header () { const isAdmin = useIsAdmin(); - const { username, groupId } = useCurrentUser(); + const { username } = useCurrentUser(); + const name = useUserGroupNames(); const loading = useCurrentUserLoading(); return ( @@ -97,7 +98,7 @@ export function Header () { Groups - {groupId} + {name}

diff --git a/ui/src/app/core/user/UserContext.js b/ui/src/app/core/user/UserContext.js index 14666abe8..f2438a9ef 100644 --- a/ui/src/app/core/user/UserContext.js +++ b/ui/src/app/core/user/UserContext.js @@ -72,7 +72,17 @@ function useCanEnable() { function useUserGroup() { const user = useCurrentUser(); - return user?.userGroups[0]; + return (user?.userGroups && user.userGroups.length > 0) ? user.userGroups[0] : null; +} + +function useUserGroups() { + const user = useCurrentUser(); + return (user?.userGroups && Array.isArray(user.userGroups)) ? user.userGroups : []; +} + +function useUserGroupNames() { + const groups = useUserGroups(); + return groups.map(g => g.name).join(', '); } function useUserGroupRegexValidator () { @@ -91,5 +101,6 @@ export { useCanEnable, useCurrentUserLoading, useUserGroupRegexValidator, - useUserGroup + useUserGroup, + useUserGroupNames }; From 80b3e59e6d4ed9bdd06dde3418fb4d9bfb7475bb Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 26 Oct 2021 11:32:32 -0700 Subject: [PATCH 21/30] Fixed issue with contention modal --- .../src/main/resources/i18n/messages.properties | 1 + ui/src/app/metadata/Metadata.js | 2 +- ui/src/app/metadata/editor/MetadataEditor.js | 14 ++++++++------ ui/src/app/metadata/hooks/api.js | 7 ++++--- ui/src/app/metadata/view/MetadataEdit.js | 4 ++-- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index 4c22a97ff..b43c52d50 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -69,6 +69,7 @@ action.groups=Groups action.source-group=Group action.enable=Enable action.disable=Disable +action.get-latest=Get latest changes action.add-new-role=Add new role action.roles=Roles diff --git a/ui/src/app/metadata/Metadata.js b/ui/src/app/metadata/Metadata.js index 81cd1e35a..20fec9021 100644 --- a/ui/src/app/metadata/Metadata.js +++ b/ui/src/app/metadata/Metadata.js @@ -49,7 +49,7 @@ export function Metadata () { } /> - + } /> diff --git a/ui/src/app/metadata/editor/MetadataEditor.js b/ui/src/app/metadata/editor/MetadataEditor.js index 0c8757d97..8cbec6770 100644 --- a/ui/src/app/metadata/editor/MetadataEditor.js +++ b/ui/src/app/metadata/editor/MetadataEditor.js @@ -21,14 +21,14 @@ import { checkChanges } from '../hooks/utility'; import { createNotificationAction, NotificationTypes, useNotificationDispatcher } from '../../notifications/hoc/Notifications'; import { useUserGroup } from '../../core/user/UserContext'; -export function MetadataEditor ({ current }) { +export function MetadataEditor ({ current, reload }) { const translator = useTranslator(); const group = useUserGroup(); const { type, id, section } = useParams(); - const { update, loading } = useMetadataUpdater(`${ API_BASE_PATH }${getMetadataPath(type)}`, current); + const { update, loading } = useMetadataUpdater(`${ API_BASE_PATH }${getMetadataPath(type)}`, current, reload); const notificationDispatch = useNotificationDispatcher(); @@ -51,9 +51,8 @@ export function MetadataEditor ({ current }) { .then(() => { gotoDetail({ refresh: true }); }) - .catch(err => { - // window.location.reload(); - notificationDispatch(createNotificationAction(`${err.errorCode} - ${translator(err.errorMessage)}`, NotificationTypes.ERROR)) + .catch((err) => { + notificationDispatch(createNotificationAction(`Updated data with latest changes`, NotificationTypes.INFO)) }); }; @@ -74,7 +73,6 @@ export function MetadataEditor ({ current }) { history.push(path); setBlocking(resetBlock); }); - // setBlocking(resetBlock); }; const [blocking, setBlocking] = React.useState(false); @@ -85,6 +83,10 @@ export function MetadataEditor ({ current }) { const canFilter = FilterableProviders.indexOf(definition.type) > -1; + React.useEffect(() => { + dispatch(setFormDataAction(current)); + }, [current, dispatch]) + return (
{ dispatch(openContentionModalAction(current, latest, body, async (resolution) => { resolve(await update(p, resolution)); - }, () => { - reject(); + }, (err) => { + cancel && cancel(); + reject(err); })); }); } diff --git a/ui/src/app/metadata/view/MetadataEdit.js b/ui/src/app/metadata/view/MetadataEdit.js index 45d326312..6fcabd933 100644 --- a/ui/src/app/metadata/view/MetadataEdit.js +++ b/ui/src/app/metadata/view/MetadataEdit.js @@ -3,13 +3,13 @@ import { MetadataForm } from '../hoc/MetadataFormContext'; import { MetadataEditor } from '../editor/MetadataEditor'; import { useMetadataObject } from '../hoc/MetadataSelector'; -export function MetadataEdit() { +export function MetadataEdit({reload}) { const base = useMetadataObject(); return ( - + ); } \ No newline at end of file From ea172eb4f53a4065af838a3d4d8509f6d44b6fa9 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 26 Oct 2021 12:46:14 -0700 Subject: [PATCH 22/30] Removed filter list button from restoration editing --- ui/src/app/metadata/editor/MetadataEditor.js | 4 ++-- ui/src/app/metadata/view/MetadataRestore.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/src/app/metadata/editor/MetadataEditor.js b/ui/src/app/metadata/editor/MetadataEditor.js index 0c8757d97..3281ee100 100644 --- a/ui/src/app/metadata/editor/MetadataEditor.js +++ b/ui/src/app/metadata/editor/MetadataEditor.js @@ -21,7 +21,7 @@ import { checkChanges } from '../hooks/utility'; import { createNotificationAction, NotificationTypes, useNotificationDispatcher } from '../../notifications/hoc/Notifications'; import { useUserGroup } from '../../core/user/UserContext'; -export function MetadataEditor ({ current }) { +export function MetadataEditor ({ restore, current }) { const translator = useTranslator(); const group = useUserGroup(); @@ -83,7 +83,7 @@ export function MetadataEditor ({ current }) { const warnings = definition.warnings && definition.warnings(metadata); - const canFilter = FilterableProviders.indexOf(definition.type) > -1; + const canFilter = restore ? false : FilterableProviders.indexOf(definition.type) > -1; return (
diff --git a/ui/src/app/metadata/view/MetadataRestore.js b/ui/src/app/metadata/view/MetadataRestore.js index 3dd257d4d..7d009c60f 100644 --- a/ui/src/app/metadata/view/MetadataRestore.js +++ b/ui/src/app/metadata/view/MetadataRestore.js @@ -16,7 +16,7 @@ export function MetadataRestore() { ...metadata, version: latest.version }}> - From 9a23a7fa1efb2161f39a06d1bf73b12383dd8975 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 26 Oct 2021 12:54:16 -0700 Subject: [PATCH 23/30] Fixed test --- ui/src/app/core/components/Header.test.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ui/src/app/core/components/Header.test.js b/ui/src/app/core/components/Header.test.js index 70d186d91..59866943f 100644 --- a/ui/src/app/core/components/Header.test.js +++ b/ui/src/app/core/components/Header.test.js @@ -17,11 +17,13 @@ jest.mock('../../i18n/hooks', () => ({ const mockIsAdmin = jest.fn(); const mockCurrentUser = jest.fn(); const mockCurrentUserLoading = jest.fn(); +const mockUseUserGroupNames = jest.fn(); jest.mock('../user/UserContext', () => ({ useIsAdmin: () => mockIsAdmin(), useCurrentUser: () => mockCurrentUser(), - useCurrentUserLoading: () => mockCurrentUserLoading() + useCurrentUserLoading: () => mockCurrentUserLoading(), + useUserGroupNames: () => mockUseUserGroupNames() })); describe('header for admins', () => { @@ -29,6 +31,7 @@ describe('header for admins', () => { mockIsAdmin.mockReturnValue(true); mockCurrentUser.mockReturnValue({ username: 'foo', groupId: 'bar' }); mockCurrentUserLoading.mockReturnValue(false); + mockUseUserGroupNames.mockReturnValue('Foo'); }); it('should display logo and navigation', () => { From a40d3fc3804598a704f4d8d5ef75ba4a64b2fd14 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Wed, 27 Oct 2021 12:26:23 -0700 Subject: [PATCH 24/30] SHIBUI-2182 "match" was not coming through in the JSON (Regex URL Scheme for DynamicHttpMetadataProvider --- ...lerVersionEndpointsIntegrationTests.groovy | 33 ++++++++++++++++++- .../MetadataRequestURLConstructionScheme.java | 5 ++- .../EnversMetadataResolverVersionService.java | 25 +++++++++++++- 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/backend/src/enversTest/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolverControllerVersionEndpointsIntegrationTests.groovy b/backend/src/enversTest/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolverControllerVersionEndpointsIntegrationTests.groovy index 8cb3df104..92d53ff65 100644 --- a/backend/src/enversTest/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolverControllerVersionEndpointsIntegrationTests.groovy +++ b/backend/src/enversTest/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolverControllerVersionEndpointsIntegrationTests.groovy @@ -150,6 +150,37 @@ class MetadataResolverControllerVersionEndpointsIntegrationTests extends Specifi mrv2.body.name == 'resolverUPDATED' } + def "SHIBUI-2182"() { + given: + def mr = new DynamicHttpMetadataResolver().with { + it.name = 'resolver2' + it.metadataRequestURLConstructionScheme = new RegexScheme().with { + it.match = 'This is the match field' + it.content = 'some content' + it + } + it + } + mr = repository.save(mr) + //Will create a second version for UPDATE revision + mr.name = 'resolverUPDATED' + mr.metadataRequestURLConstructionScheme.match = 'This is the match field too' + repository.save(mr) + + when: + def allVersions = getAllMetadataResolverVersions(mr.resourceId, List) + def mrv1 = getMetadataResolverForVersion(mr.resourceId, allVersions.body[0].id, MetadataResolver) + def mrv2 = getMetadataResolverForVersion(mr.resourceId, allVersions.body[1].id, MetadataResolver) + + then: + mrv1.statusCodeValue == 200 + mrv1.body.name == 'resolver2' + mrv1.body.metadataRequestURLConstructionScheme.match == 'This is the match field' + mrv2.statusCodeValue == 200 + mrv2.body.name == 'resolverUPDATED' + mrv2.body.metadataRequestURLConstructionScheme.match == 'This is the match field too' + } + def "SHIBUI-1386"() { given: MetadataResolver mr = new FileBackedHttpMetadataResolver(name: 'testme') @@ -292,4 +323,4 @@ trait AttributeReleaseAndOverrides { Map overrides(int filterIndex) { (this.metadataFilters[filterIndex] as EntityAttributesFilter).relyingPartyOverrides } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataRequestURLConstructionScheme.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataRequestURLConstructionScheme.java index a1223840e..e24b5cb02 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataRequestURLConstructionScheme.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataRequestURLConstructionScheme.java @@ -64,4 +64,7 @@ public String toString() { String type; String content; -} + + @Transient + String match; +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EnversMetadataResolverVersionService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EnversMetadataResolverVersionService.java index b0d90195f..375e91ad6 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EnversMetadataResolverVersionService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EnversMetadataResolverVersionService.java @@ -1,9 +1,14 @@ package edu.internet2.tier.shibboleth.admin.ui.service; import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetadataResolver; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataRequestURLConstructionScheme; import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.RegexScheme; import edu.internet2.tier.shibboleth.admin.ui.domain.versioning.Version; import edu.internet2.tier.shibboleth.admin.ui.envers.EnversVersionServiceSupport; +import org.springframework.aop.framework.Advised; +import org.springframework.aop.support.AopUtils; import java.util.List; @@ -36,8 +41,26 @@ public MetadataResolver findSpecificVersionOfMetadataResolver(String resourceId, //The @PostLoad is not honored by Envers. So need to do this manually for EntityAttributesFilters //So the correct representation is built and returned to upstream clients expecting JSON resolver.entityAttributesFilterIntoTransientRepresentation(); + if (resolver instanceof DynamicHttpMetadataResolver) { + MetadataRequestURLConstructionScheme scheme = ((DynamicHttpMetadataResolver)resolver).getMetadataRequestURLConstructionScheme(); + RegexScheme rs = null; + try { + rs = getTargetObject(scheme, RegexScheme.class); + ((DynamicHttpMetadataResolver)resolver).setMetadataRequestURLConstructionScheme(rs); + } + catch (Exception e) { + } + } return resolver; + } + @SuppressWarnings({"unchecked"}) + protected T getTargetObject(Object proxy, Class targetClass) throws Exception { + if (AopUtils.isJdkDynamicProxy(proxy)) { + return (T) ((Advised)proxy).getTargetSource().getTarget(); + } else { + return (T) proxy; // expected to be cglib proxy then, which is simply a specialized class + } } -} +} \ No newline at end of file From f136f4fc9ccef930d9761a383214573889a3997c Mon Sep 17 00:00:00 2001 From: chasegawa Date: Wed, 27 Oct 2021 13:15:17 -0700 Subject: [PATCH 25/30] SHIBUI-2182 restoring EnversMetadataResolverVersionService to previous --- .../EnversMetadataResolverVersionService.java | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EnversMetadataResolverVersionService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EnversMetadataResolverVersionService.java index 375e91ad6..558af5789 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EnversMetadataResolverVersionService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EnversMetadataResolverVersionService.java @@ -1,14 +1,9 @@ package edu.internet2.tier.shibboleth.admin.ui.service; import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter; -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetadataResolver; -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataRequestURLConstructionScheme; import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver; -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.RegexScheme; import edu.internet2.tier.shibboleth.admin.ui.domain.versioning.Version; import edu.internet2.tier.shibboleth.admin.ui.envers.EnversVersionServiceSupport; -import org.springframework.aop.framework.Advised; -import org.springframework.aop.support.AopUtils; import java.util.List; @@ -41,26 +36,8 @@ public MetadataResolver findSpecificVersionOfMetadataResolver(String resourceId, //The @PostLoad is not honored by Envers. So need to do this manually for EntityAttributesFilters //So the correct representation is built and returned to upstream clients expecting JSON resolver.entityAttributesFilterIntoTransientRepresentation(); - if (resolver instanceof DynamicHttpMetadataResolver) { - MetadataRequestURLConstructionScheme scheme = ((DynamicHttpMetadataResolver)resolver).getMetadataRequestURLConstructionScheme(); - RegexScheme rs = null; - try { - rs = getTargetObject(scheme, RegexScheme.class); - ((DynamicHttpMetadataResolver)resolver).setMetadataRequestURLConstructionScheme(rs); - } - catch (Exception e) { - } - } return resolver; - } - @SuppressWarnings({"unchecked"}) - protected T getTargetObject(Object proxy, Class targetClass) throws Exception { - if (AopUtils.isJdkDynamicProxy(proxy)) { - return (T) ((Advised)proxy).getTargetSource().getTarget(); - } else { - return (T) proxy; // expected to be cglib proxy then, which is simply a specialized class - } } } \ No newline at end of file From 3b06ce7dd12b0a335ad346adb500e7344d6fa468 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 28 Oct 2021 08:58:11 -0700 Subject: [PATCH 26/30] Fixed placeholder text --- backend/src/main/resources/i18n/messages.properties | 2 ++ ui/src/app/metadata/wizard/MetadataProviderTypeSelector.js | 2 +- ui/src/testing/dynamic-http.schema.js | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index d77f9be0f..f4bf44a8b 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -75,6 +75,8 @@ action.roles=Roles action.source-role=Role action.select-bundle=Select Bundle +action.get-latest=Get latest + value.enabled=Enabled value.disabled=Disabled value.current=Current diff --git a/ui/src/app/metadata/wizard/MetadataProviderTypeSelector.js b/ui/src/app/metadata/wizard/MetadataProviderTypeSelector.js index 5a091b2d2..4c91bcf23 100644 --- a/ui/src/app/metadata/wizard/MetadataProviderTypeSelector.js +++ b/ui/src/app/metadata/wizard/MetadataProviderTypeSelector.js @@ -82,7 +82,7 @@ export function MetadataProviderTypeSelector({ type, types = [], children}) { - + Date: Thu, 28 Oct 2021 09:57:20 -0700 Subject: [PATCH 27/30] Fixed issue with navigation --- ui/src/app/metadata/editor/MetadataEditor.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ui/src/app/metadata/editor/MetadataEditor.js b/ui/src/app/metadata/editor/MetadataEditor.js index 3281ee100..1ebc8e8f0 100644 --- a/ui/src/app/metadata/editor/MetadataEditor.js +++ b/ui/src/app/metadata/editor/MetadataEditor.js @@ -71,10 +71,9 @@ export function MetadataEditor ({ restore, current }) { const resetBlock = blocking; setBlocking(false); setTimeout(() => { - history.push(path); + history.push(restore ? `../${path}/edit` : path); setBlocking(resetBlock); }); - // setBlocking(resetBlock); }; const [blocking, setBlocking] = React.useState(false); From c56d1e93cd3cb5d835e80a1c585c24012a58b059 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 28 Oct 2021 10:57:53 -0700 Subject: [PATCH 28/30] Fixed spinner on save for sources --- ui/src/app/metadata/wizard/MetadataSourceWizard.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ui/src/app/metadata/wizard/MetadataSourceWizard.js b/ui/src/app/metadata/wizard/MetadataSourceWizard.js index 364d74421..66e75e32b 100644 --- a/ui/src/app/metadata/wizard/MetadataSourceWizard.js +++ b/ui/src/app/metadata/wizard/MetadataSourceWizard.js @@ -12,16 +12,15 @@ import { useMetadataDefinitionContext, useMetadataSchemaContext, useMetadataDefi import { useMetadataFormDispatcher, setFormDataAction, setFormErrorAction, useMetadataFormData, useMetadataFormErrors } from '../hoc/MetadataFormContext'; import { MetadataConfiguration } from '../component/MetadataConfiguration'; import { Configuration } from '../hoc/Configuration'; -import { useMetadataEntity, useMetadataSources } from '../hooks/api'; +import { useMetadataSources } from '../hooks/api'; import Translate from '../../i18n/components/translate'; import { checkChanges } from '../hooks/utility'; import { useUserGroup } from '../../core/user/UserContext'; -export function MetadataSourceWizard ({ onShowNav, onSave, block }) { +export function MetadataSourceWizard ({ onShowNav, onSave, block, loading }) { - const { loading } = useMetadataEntity('source'); const group = useUserGroup(); const { data } = useMetadataSources({ @@ -61,6 +60,8 @@ export function MetadataSourceWizard ({ onShowNav, onSave, block }) { const validator = useMetadataDefinitionValidator(data, null, group); const warnings = definition.warnings && definition.warnings(metadata); + React.useEffect(() => console.log(loading), [loading]); + return ( <>
From 781d58c0a1794fb430dcfe787db5cc767c1d1117 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 28 Oct 2021 12:10:36 -0700 Subject: [PATCH 29/30] Removed logging --- backend/src/main/resources/application.properties | 2 ++ ui/src/app/form/component/widgets/AttributeReleaseWidget.js | 2 -- ui/src/app/metadata/view/MetadataWizard.js | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index 0556e5b45..ac72fcc21 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -1,6 +1,8 @@ # Server Configuration #server.port=8080 +server.servlet.session.timeout=1m + # Logging Configuration #logging.config=classpath:log4j2.xml diff --git a/ui/src/app/form/component/widgets/AttributeReleaseWidget.js b/ui/src/app/form/component/widgets/AttributeReleaseWidget.js index a4f13eead..e8f5956aa 100644 --- a/ui/src/app/form/component/widgets/AttributeReleaseWidget.js +++ b/ui/src/app/form/component/widgets/AttributeReleaseWidget.js @@ -98,8 +98,6 @@ const AttributeReleaseWidget = ({ const [bundle, setBundle] = React.useState(); - React.useEffect(() => console.log(bundle), [bundle]); - const onMouseOver = (opt) => setBundle(opt); const onMouseOut = () => setBundle(null); diff --git a/ui/src/app/metadata/view/MetadataWizard.js b/ui/src/app/metadata/view/MetadataWizard.js index 4a4b4b5c7..2b3753412 100644 --- a/ui/src/app/metadata/view/MetadataWizard.js +++ b/ui/src/app/metadata/view/MetadataWizard.js @@ -19,7 +19,6 @@ export function MetadataWizard ({type, data, onCallback}) { const [blocking, setBlocking] = React.useState(false); async function save(metadata) { - console.log(metadata); await post('', metadata); if (response.ok) { setBlocking(false); From 9fc2a1e13a2b6a37159b09b5da254bd726a8f2e1 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 28 Oct 2021 14:54:43 -0700 Subject: [PATCH 30/30] reverted property change --- backend/src/main/resources/application.properties | 2 -- 1 file changed, 2 deletions(-) diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index ac72fcc21..0556e5b45 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -1,8 +1,6 @@ # Server Configuration #server.port=8080 -server.servlet.session.timeout=1m - # Logging Configuration #logging.config=classpath:log4j2.xml