From 6668431fb711841fa6281cc86cd055c2268424be Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 5 Nov 2018 09:49:44 -0700 Subject: [PATCH 01/20] SHIBUI-701 Added schema and fixed bugs for FileSystemMetadataProvider --- .../resources/i18n/messages_en.properties | 5 + .../file-system-metadata-provider.ts | 7 + .../provider-wizard-step.component.ts | 6 +- .../provider/model/base.provider.form.ts | 9 - .../model/file-backed-http.provider.form.ts | 9 + .../model/file-system.provider.form.ts | 112 ++++++++++++ ui/src/app/metadata/provider/model/index.ts | 7 +- .../metadata/provider/model/provider.form.ts | 13 +- ui/src/app/wizard/reducer/index.ts | 4 +- .../schema/provider/file-system.schema.json | 166 ++++++++++++++++++ .../filebacked-http-reloading.schema.json | 45 ----- .../provider/metadata-provider.schema.json | 15 +- 12 files changed, 328 insertions(+), 70 deletions(-) create mode 100644 ui/src/app/metadata/domain/model/providers/file-system-metadata-provider.ts create mode 100644 ui/src/app/metadata/provider/model/file-system.provider.form.ts create mode 100644 ui/src/assets/schema/provider/file-system.schema.json diff --git a/backend/src/main/resources/i18n/messages_en.properties b/backend/src/main/resources/i18n/messages_en.properties index 3d4670252..d666ef6c9 100644 --- a/backend/src/main/resources/i18n/messages_en.properties +++ b/backend/src/main/resources/i18n/messages_en.properties @@ -70,6 +70,9 @@ value.encryption=Encryption value.both=Both value.file-backed-http-metadata-provider=FileBackedHttpMetadataProvider +value.file-system-metadata-provider=FileSystemMetadataProvider +value.local-dynamic-metadata-provider=LocalDynamicMetadataProvider +value.dynamic-http-metadata-provider=DynamicHttpMetadataProvider value.entity-attributes-filter=EntityAttributes Filter value.spdescriptor=SPSSODescriptor value.attr-auth-descriptor=AttributeAuthorityDescriptor @@ -293,6 +296,8 @@ label.metadata-provider-status=Metadata Provider Status label.enable-provider-upon-saving=Enable Metadata Provider upon saving? label.certificate-type=Type +label.metadata-file=Metadata File + label.enable-filter=Enable Filter? label.required-valid-until=Required Valid Until Filter label.max-validity-interval=Max Validity Interval diff --git a/ui/src/app/metadata/domain/model/providers/file-system-metadata-provider.ts b/ui/src/app/metadata/domain/model/providers/file-system-metadata-provider.ts new file mode 100644 index 000000000..e884151c1 --- /dev/null +++ b/ui/src/app/metadata/domain/model/providers/file-system-metadata-provider.ts @@ -0,0 +1,7 @@ +import { BaseMetadataProvider } from './base-metadata-provider'; + +export interface FileSystemMetadataProvider extends BaseMetadataProvider { + id: string; + metadataFile: string; + reloadableMetadataResolverAttributes: any; +} diff --git a/ui/src/app/metadata/provider/container/provider-wizard-step.component.ts b/ui/src/app/metadata/provider/container/provider-wizard-step.component.ts index 05d121bba..9ff4ded23 100644 --- a/ui/src/app/metadata/provider/container/provider-wizard-step.component.ts +++ b/ui/src/app/metadata/provider/container/provider-wizard-step.component.ts @@ -1,6 +1,6 @@ import { Component, OnDestroy } from '@angular/core'; import { Observable, Subject } from 'rxjs'; -import { withLatestFrom, map, distinctUntilChanged, skipWhile } from 'rxjs/operators'; +import { withLatestFrom, map, distinctUntilChanged, skipWhile, filter } from 'rxjs/operators'; import { Store } from '@ngrx/store'; import * as fromProvider from '../reducer'; @@ -42,7 +42,9 @@ export class ProviderWizardStepComponent implements OnDestroy { constructor( private store: Store, ) { - this.schema$ = this.store.select(fromWizard.getParsedSchema); + this.schema$ = this.store.select(fromWizard.getSchema).pipe( + filter(s => s && Object.keys(s.properties).length > 0) + ); this.definition$ = this.store.select(fromWizard.getWizardDefinition); this.changes$ = this.store.select(fromProvider.getEntityChanges); diff --git a/ui/src/app/metadata/provider/model/base.provider.form.ts b/ui/src/app/metadata/provider/model/base.provider.form.ts index 459eaa956..ecbcab666 100644 --- a/ui/src/app/metadata/provider/model/base.provider.form.ts +++ b/ui/src/app/metadata/provider/model/base.provider.form.ts @@ -1,6 +1,5 @@ import { Wizard } from '../../../wizard/model'; import { BaseMetadataProvider } from '../../domain/model/providers'; -import { UriValidator } from '../../../shared/validation/uri.validator'; export const BaseMetadataProviderEditor: Wizard = { label: 'BaseMetadataProvider', @@ -30,14 +29,6 @@ export const BaseMetadataProviderEditor: Wizard = { params: [value] } : null; return err; - }, - '/metadataURL': (value, property, form) => { - return !UriValidator.isUri(value) ? { - code: 'INVALID_URI', - path: `#${property.path}`, - message: 'message.uri-valid-format', - params: [value] - } : null; } }; return validators; diff --git a/ui/src/app/metadata/provider/model/file-backed-http.provider.form.ts b/ui/src/app/metadata/provider/model/file-backed-http.provider.form.ts index 2c8103438..f6bd3796f 100644 --- a/ui/src/app/metadata/provider/model/file-backed-http.provider.form.ts +++ b/ui/src/app/metadata/provider/model/file-backed-http.provider.form.ts @@ -1,6 +1,7 @@ import { Wizard } from '../../../wizard/model'; import { FileBackedHttpMetadataProvider } from '../../domain/model/providers/file-backed-http-metadata-provider'; import { BaseMetadataProviderEditor } from './base.provider.form'; +import { UriValidator } from '../../../shared/validation/uri.validator'; export const FileBackedHttpMetadataProviderWizard: Wizard = { ...BaseMetadataProviderEditor, @@ -17,6 +18,14 @@ export const FileBackedHttpMetadataProviderWizard: Wizard { + return !UriValidator.isUri(value) ? { + code: 'INVALID_URI', + path: `#${property.path}`, + message: 'message.uri-valid-format', + params: [value] + } : null; + }; return validators; }, steps: [ diff --git a/ui/src/app/metadata/provider/model/file-system.provider.form.ts b/ui/src/app/metadata/provider/model/file-system.provider.form.ts new file mode 100644 index 000000000..e84e79aa4 --- /dev/null +++ b/ui/src/app/metadata/provider/model/file-system.provider.form.ts @@ -0,0 +1,112 @@ +import { Wizard } from '../../../wizard/model'; +import { FileSystemMetadataProvider } from '../../domain/model/providers/file-system-metadata-provider'; +import { BaseMetadataProviderEditor } from './base.provider.form'; + +export const FileSystemMetadataProviderWizard: Wizard = { + ...BaseMetadataProviderEditor, + label: 'FileSystemMetadataProvider', + type: 'FileSystemMetadataResolver', + getValidators(namesList: string[] = [], xmlIdList: string[] = []): any { + const validators = BaseMetadataProviderEditor.getValidators(namesList); + validators['/xmlId'] = (value, property, form) => { + const err = xmlIdList.indexOf(value) > -1 ? { + code: 'INVALID_ID', + path: `#${property.path}`, + message: 'message.id-unique', + params: [value] + } : null; + return err; + }; + return validators; + }, + steps: [ + { + id: 'common', + label: 'label.common-attributes', + index: 2, + initialValues: [], + schema: 'assets/schema/provider/file-system.schema.json', + fields: [ + 'xmlId', + 'metadataFile' + ], + fieldsets: [ + { + type: 'group-lg', + class: ['col-12'], + fields: [ + 'xmlId', + 'metadataFile' + ] + } + ] + }, + { + id: 'reloading', + label: 'label.reloading-attributes', + index: 3, + initialValues: [], + schema: 'assets/schema/provider/file-system.schema.json', + fields: [ + 'reloadableMetadataResolverAttributes' + ], + fieldsets: [ + { + type: 'group-lg', + class: ['col-12'], + fields: [ + 'reloadableMetadataResolverAttributes' + ] + } + ] + }, + { + id: 'summary', + label: 'label.finished', + index: 4, + initialValues: [], + schema: 'assets/schema/provider/file-system.schema.json', + fields: [ + 'enabled' + ], + fieldsets: [ + { + type: 'group-lg', + class: ['col-12'], + fields: [ + 'enabled' + ] + } + ] + } + ] +}; + + +export const FileSystemMetadataProviderEditor: Wizard = { + ...FileSystemMetadataProviderWizard, + steps: [ + { + id: 'common', + label: 'label.common-attributes', + index: 1, + initialValues: [], + schema: 'assets/schema/provider/filebacked-http-common.editor.schema.json', + fields: [ + 'enabled', + 'xmlId', + 'metadataFile' + ] + }, + { + id: 'reloading', + label: 'label.reloading-attributes', + index: 2, + initialValues: [], + schema: 'assets/schema/provider/filebacked-http-reloading.schema.json', + fields: [ + 'reloadableMetadataResolverAttributes' + ] + } + ] +}; diff --git a/ui/src/app/metadata/provider/model/index.ts b/ui/src/app/metadata/provider/model/index.ts index cfb64a08d..02ef91ec7 100644 --- a/ui/src/app/metadata/provider/model/index.ts +++ b/ui/src/app/metadata/provider/model/index.ts @@ -1,12 +1,15 @@ import { FileBackedHttpMetadataProviderWizard } from './file-backed-http.provider.form'; import { FileBackedHttpMetadataProviderEditor } from './file-backed-http.provider.form'; +import { FileSystemMetadataProviderWizard, FileSystemMetadataProviderEditor } from './file-system.provider.form'; export const MetadataProviderWizardTypes = [ - FileBackedHttpMetadataProviderWizard + FileBackedHttpMetadataProviderWizard, + FileSystemMetadataProviderWizard ]; export const MetadataProviderEditorTypes = [ - FileBackedHttpMetadataProviderEditor + FileBackedHttpMetadataProviderEditor, + FileSystemMetadataProviderEditor ]; export * from './file-backed-http.provider.form'; diff --git a/ui/src/app/metadata/provider/model/provider.form.ts b/ui/src/app/metadata/provider/model/provider.form.ts index 28e5794c5..26fbdd966 100644 --- a/ui/src/app/metadata/provider/model/provider.form.ts +++ b/ui/src/app/metadata/provider/model/provider.form.ts @@ -1,6 +1,5 @@ import { Wizard, WizardStep } from '../../../wizard/model'; import { MetadataProvider } from '../../domain/model'; -import { Metadata } from '../../domain/domain.type'; import { BaseMetadataProviderEditor } from './base.provider.form'; export const MetadataProviderWizard: Wizard = { @@ -17,7 +16,17 @@ export const MetadataProviderWizard: Wizard = { fields: [ 'name', '@type' + ], + fieldsets: [ + { + type: 'section', + class: ['col-12'], + fields: [ + 'name', + '@type' + ] + } ] } - ] as WizardStep[] + ] as WizardStep[], }; diff --git a/ui/src/app/wizard/reducer/index.ts b/ui/src/app/wizard/reducer/index.ts index 0d7176565..30f00b18d 100644 --- a/ui/src/app/wizard/reducer/index.ts +++ b/ui/src/app/wizard/reducer/index.ts @@ -61,12 +61,14 @@ export const getSplitSchema = (schema: any, step: WizardStep) => { const required = (schema.required || []).filter(val => keys.indexOf(val) > -1); let s: any = { type: schema.type, - definitions: schema.definitions, properties: { ...keys.reduce( (properties, key) => ({ ...properties, [key]: schema.properties[key] }) , {}) } }; + if (schema.definitions) { + s.definitions = schema.definitions; + } if (required && required.length) { s.required = required; } diff --git a/ui/src/assets/schema/provider/file-system.schema.json b/ui/src/assets/schema/provider/file-system.schema.json new file mode 100644 index 000000000..e015b15d8 --- /dev/null +++ b/ui/src/assets/schema/provider/file-system.schema.json @@ -0,0 +1,166 @@ +{ + "type": "object", + "required": [ + "name", + "@type", + "xmlId", + "metadataFile" + ], + "properties": { + "name": { + "title": "label.metadata-provider-name", + "description": "tooltip.metadata-provider-name", + "type": "string", + "widget": { + "id": "string", + "help": "message.must-be-unique" + } + }, + "@type": { + "title": "label.metadata-provider-type", + "description": "tooltip.metadata-provider-type", + "placeholder": "label.select-metadata-type", + "type": "string", + "readOnly": true, + "widget": { + "id": "select", + "disabled": true + }, + "oneOf": [ + { + "enum": [ + "FileSystemMetadataResolver" + ], + "description": "value.file-system-metadata-provider" + } + ] + }, + "xmlId": { + "title": "label.xml-id", + "description": "tooltip.xml-id", + "type": "string", + "default": "", + "minLength": 1 + }, + "metadataFile": { + "title": "label.metadata-file", + "description": "tooltip.metadata-file", + "type": "string", + "default": "", + "minLength": 1 + }, + "enabled": { + "title": "label.enable-provider-upon-saving", + "description": "tooltip.enable-provider-upon-saving", + "type": "boolean", + "default": false + }, + "reloadableMetadataResolverAttributes": { + "type": "object", + "properties": { + "minRefreshDelay": { + "title": "label.min-refresh-delay", + "description": "tooltip.min-refresh-delay", + "type": "string", + "placeholder": "label.duration", + "widget": { + "id": "datalist", + "data": [ + "PT0S", + "PT30S", + "PT1M", + "PT10M", + "PT30M", + "PT1H", + "PT4H", + "PT12H", + "PT24H" + ] + }, + "default": null, + "pattern": "^(R\\d*\\/)?P(?:\\d+(?:\\.\\d+)?Y)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?W)?(?:\\d+(?:\\.\\d+)?D)?(?:T(?:\\d+(?:\\.\\d+)?H)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?S)?)?$" + }, + "maxRefreshDelay": { + "title": "label.max-refresh-delay", + "description": "tooltip.max-refresh-delay", + "type": "string", + "placeholder": "label.duration", + "widget": { + "id": "datalist", + "data": [ + "PT0S", + "PT30S", + "PT1M", + "PT10M", + "PT30M", + "PT1H", + "PT4H", + "PT12H", + "PT24H" + ] + }, + "default": null, + "pattern": "^(R\\d*\\/)?P(?:\\d+(?:\\.\\d+)?Y)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?W)?(?:\\d+(?:\\.\\d+)?D)?(?:T(?:\\d+(?:\\.\\d+)?H)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?S)?)?$" + }, + "refreshDelayFactor": { + "title": "label.refresh-delay-factor", + "description": "tooltip.refresh-delay-factor", + "type": "number", + "widget": { + "id": "number", + "step": 0.01 + }, + "placeholder": "label.real-number", + "minimum": 0, + "maximum": 1, + "default": null + }, + "resolveViaPredicatesOnly": { + "title": "label.resolve-via-predicates-only", + "description": "tooltip.resolve-via-predicates-only", + "type": "boolean", + "widget": { + "id": "boolean-radio" + }, + "oneOf": [ + { + "enum": [ + true + ], + "description": "value.true" + }, + { + "enum": [ + false + ], + "description": "value.false" + } + ], + "default": true + }, + "expirationWarningThreshold": { + "title": "label.expiration-warning-threshold", + "description": "tooltip.expiration-warning-threshold", + "type": "string", + "placeholder": "label.duration", + "widget": { + "id": "datalist", + "data": [ + "PT0S", + "PT30S", + "PT1M", + "PT10M", + "PT30M", + "PT1H", + "PT4H", + "PT12H", + "PT24H" + ] + }, + "default": null, + "pattern": "^(R\\d*\\/)?P(?:\\d+(?:\\.\\d+)?Y)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?W)?(?:\\d+(?:\\.\\d+)?D)?(?:T(?:\\d+(?:\\.\\d+)?H)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?S)?)?$" + } + } + } + } +} \ No newline at end of file diff --git a/ui/src/assets/schema/provider/filebacked-http-reloading.schema.json b/ui/src/assets/schema/provider/filebacked-http-reloading.schema.json index f7f884e6a..de58d5137 100644 --- a/ui/src/assets/schema/provider/filebacked-http-reloading.schema.json +++ b/ui/src/assets/schema/provider/filebacked-http-reloading.schema.json @@ -60,51 +60,6 @@ "minimum": 0, "maximum": 1, "default": null - }, - "resolveViaPredicatesOnly": { - "title": "label.resolve-via-predicates-only", - "description": "tooltip.resolve-via-predicates-only", - "type": "boolean", - "widget": { - "id": "boolean-radio" - }, - "oneOf": [ - { - "enum": [ - true - ], - "description": "value.true" - }, - { - "enum": [ - false - ], - "description": "value.false" - } - ], - "default": true - }, - "expirationWarningThreshold": { - "title": "label.expiration-warning-threshold", - "description": "tooltip.expiration-warning-threshold", - "type": "string", - "placeholder": "label.duration", - "widget": { - "id": "datalist", - "data": [ - "PT0S", - "PT30S", - "PT1M", - "PT10M", - "PT30M", - "PT1H", - "PT4H", - "PT12H", - "PT24H" - ] - }, - "default": null, - "pattern": "^(R\\d*\\/)?P(?:\\d+(?:\\.\\d+)?Y)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?W)?(?:\\d+(?:\\.\\d+)?D)?(?:T(?:\\d+(?:\\.\\d+)?H)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?S)?)?$" } } } diff --git a/ui/src/assets/schema/provider/metadata-provider.schema.json b/ui/src/assets/schema/provider/metadata-provider.schema.json index 6cd17323f..3b3179815 100644 --- a/ui/src/assets/schema/provider/metadata-provider.schema.json +++ b/ui/src/assets/schema/provider/metadata-provider.schema.json @@ -28,6 +28,12 @@ "FileBackedHttpMetadataResolver" ], "description": "value.file-backed-http-metadata-provider" + }, + { + "enum": [ + "FileSystemMetadataResolver" + ], + "description": "value.file-system-metadata-provider" } ] } @@ -35,14 +41,5 @@ "required": [ "name", "@type" - ], - "fieldsets": [ - { - "type": "section", - "fields": [ - "name", - "@type" - ] - } ] } \ No newline at end of file From ce25cf31716658912f06d0bc82b6f735947b5440 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 5 Nov 2018 09:50:47 -0700 Subject: [PATCH 02/20] SHIBUI-701 Added schema and fixed bugs for FileSystemMetadataProvider --- backend/src/main/resources/i18n/messages.properties | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index 83b644910..d666ef6c9 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -70,6 +70,9 @@ value.encryption=Encryption value.both=Both value.file-backed-http-metadata-provider=FileBackedHttpMetadataProvider +value.file-system-metadata-provider=FileSystemMetadataProvider +value.local-dynamic-metadata-provider=LocalDynamicMetadataProvider +value.dynamic-http-metadata-provider=DynamicHttpMetadataProvider value.entity-attributes-filter=EntityAttributes Filter value.spdescriptor=SPSSODescriptor value.attr-auth-descriptor=AttributeAuthorityDescriptor @@ -293,6 +296,8 @@ label.metadata-provider-status=Metadata Provider Status label.enable-provider-upon-saving=Enable Metadata Provider upon saving? label.certificate-type=Type +label.metadata-file=Metadata File + label.enable-filter=Enable Filter? label.required-valid-until=Required Valid Until Filter label.max-validity-interval=Max Validity Interval @@ -407,7 +412,7 @@ tooltip.authentication-methods-to-use=Authentication Methods to Use tooltip.ignore-auth-method=Ignore any SP-Requested Authentication Method tooltip.omit-not-before-condition=Omit Not Before Condition tooltip.responder-id=ResponderId -tooltip.instruction=Information icon - press spacebar to read additional information for this form field +tooltip.instruction=Information icon tooltip.attribute-release-table=Attribute release table - select the attributes you want to release (default unchecked) tooltip.metadata-filter-name=Metadata Filter Name tooltip.metadata-filter-type=Metadata Filter Type @@ -433,7 +438,7 @@ tooltip.backing-file=Specifies where the backing file is located. If the remote tooltip.backup-file-init-refresh-delay=Delay duration after which to schedule next HTTP refresh when initialized from the backing file. tooltip.require-valid-metadata=Whether candidate metadata found by the resolver must be valid in order to be returned (where validity is implementation specific, but in SAML cases generally depends on a validUntil attribute.) If this flag is true, then invalid candidate metadata will not be returned. tooltip.fail-fast-init=Whether to fail initialization of the underlying MetadataResolverService (and possibly the IdP as a whole) if the initialization of a metadata provider fails. When false, the IdP may start, and will continue to attempt to reload valid metadata if configured to do so, but operations that require valid metadata will fail until it does. -tooltip.use-default-predicate-reg=Whether to fail initialization of the underlying MetadataResolverService (and possibly the IdP as a whole) if the initialization of a metadata provider fails. When false, the IdP may start, and will continue to attempt to reload valid metadata if configured to do so, but operations that require valid metadata will fail until it does. +tooltip.use-default-predicate-reg=Flag which determines whether the default CriterionPredicateRegistry will be used if a custom one is not supplied explicitly. tooltip.satisfy-any-predicates=Flag which determines whether predicates used in filtering are connected by a logical 'OR' (true) or by logical 'AND' (false). tooltip.enable-provider-upon-saving=Enable Metadata Provider upon saving? From 6babb7123aacc10b7631451e1268c0c751b37823 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 5 Nov 2018 09:52:34 -0700 Subject: [PATCH 03/20] SHIBUI-701 Copied schema to backend folder --- .../file-system-metadata-provider.schema.json | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 backend/src/main/resources/file-system-metadata-provider.schema.json diff --git a/backend/src/main/resources/file-system-metadata-provider.schema.json b/backend/src/main/resources/file-system-metadata-provider.schema.json new file mode 100644 index 000000000..e015b15d8 --- /dev/null +++ b/backend/src/main/resources/file-system-metadata-provider.schema.json @@ -0,0 +1,166 @@ +{ + "type": "object", + "required": [ + "name", + "@type", + "xmlId", + "metadataFile" + ], + "properties": { + "name": { + "title": "label.metadata-provider-name", + "description": "tooltip.metadata-provider-name", + "type": "string", + "widget": { + "id": "string", + "help": "message.must-be-unique" + } + }, + "@type": { + "title": "label.metadata-provider-type", + "description": "tooltip.metadata-provider-type", + "placeholder": "label.select-metadata-type", + "type": "string", + "readOnly": true, + "widget": { + "id": "select", + "disabled": true + }, + "oneOf": [ + { + "enum": [ + "FileSystemMetadataResolver" + ], + "description": "value.file-system-metadata-provider" + } + ] + }, + "xmlId": { + "title": "label.xml-id", + "description": "tooltip.xml-id", + "type": "string", + "default": "", + "minLength": 1 + }, + "metadataFile": { + "title": "label.metadata-file", + "description": "tooltip.metadata-file", + "type": "string", + "default": "", + "minLength": 1 + }, + "enabled": { + "title": "label.enable-provider-upon-saving", + "description": "tooltip.enable-provider-upon-saving", + "type": "boolean", + "default": false + }, + "reloadableMetadataResolverAttributes": { + "type": "object", + "properties": { + "minRefreshDelay": { + "title": "label.min-refresh-delay", + "description": "tooltip.min-refresh-delay", + "type": "string", + "placeholder": "label.duration", + "widget": { + "id": "datalist", + "data": [ + "PT0S", + "PT30S", + "PT1M", + "PT10M", + "PT30M", + "PT1H", + "PT4H", + "PT12H", + "PT24H" + ] + }, + "default": null, + "pattern": "^(R\\d*\\/)?P(?:\\d+(?:\\.\\d+)?Y)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?W)?(?:\\d+(?:\\.\\d+)?D)?(?:T(?:\\d+(?:\\.\\d+)?H)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?S)?)?$" + }, + "maxRefreshDelay": { + "title": "label.max-refresh-delay", + "description": "tooltip.max-refresh-delay", + "type": "string", + "placeholder": "label.duration", + "widget": { + "id": "datalist", + "data": [ + "PT0S", + "PT30S", + "PT1M", + "PT10M", + "PT30M", + "PT1H", + "PT4H", + "PT12H", + "PT24H" + ] + }, + "default": null, + "pattern": "^(R\\d*\\/)?P(?:\\d+(?:\\.\\d+)?Y)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?W)?(?:\\d+(?:\\.\\d+)?D)?(?:T(?:\\d+(?:\\.\\d+)?H)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?S)?)?$" + }, + "refreshDelayFactor": { + "title": "label.refresh-delay-factor", + "description": "tooltip.refresh-delay-factor", + "type": "number", + "widget": { + "id": "number", + "step": 0.01 + }, + "placeholder": "label.real-number", + "minimum": 0, + "maximum": 1, + "default": null + }, + "resolveViaPredicatesOnly": { + "title": "label.resolve-via-predicates-only", + "description": "tooltip.resolve-via-predicates-only", + "type": "boolean", + "widget": { + "id": "boolean-radio" + }, + "oneOf": [ + { + "enum": [ + true + ], + "description": "value.true" + }, + { + "enum": [ + false + ], + "description": "value.false" + } + ], + "default": true + }, + "expirationWarningThreshold": { + "title": "label.expiration-warning-threshold", + "description": "tooltip.expiration-warning-threshold", + "type": "string", + "placeholder": "label.duration", + "widget": { + "id": "datalist", + "data": [ + "PT0S", + "PT30S", + "PT1M", + "PT10M", + "PT30M", + "PT1H", + "PT4H", + "PT12H", + "PT24H" + ] + }, + "default": null, + "pattern": "^(R\\d*\\/)?P(?:\\d+(?:\\.\\d+)?Y)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?W)?(?:\\d+(?:\\.\\d+)?D)?(?:T(?:\\d+(?:\\.\\d+)?H)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?S)?)?$" + } + } + } + } +} \ No newline at end of file From 9072bb690b2a986c05977e78360a16feb69abb30 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 5 Nov 2018 10:34:02 -0700 Subject: [PATCH 04/20] SHIBUI-701 Removed unnecessary values from schema --- .../file-system-metadata-provider.schema.json | 45 ------------------- .../schema/provider/file-system.schema.json | 45 ------------------- 2 files changed, 90 deletions(-) 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 e015b15d8..f44761f86 100644 --- a/backend/src/main/resources/file-system-metadata-provider.schema.json +++ b/backend/src/main/resources/file-system-metadata-provider.schema.json @@ -114,51 +114,6 @@ "minimum": 0, "maximum": 1, "default": null - }, - "resolveViaPredicatesOnly": { - "title": "label.resolve-via-predicates-only", - "description": "tooltip.resolve-via-predicates-only", - "type": "boolean", - "widget": { - "id": "boolean-radio" - }, - "oneOf": [ - { - "enum": [ - true - ], - "description": "value.true" - }, - { - "enum": [ - false - ], - "description": "value.false" - } - ], - "default": true - }, - "expirationWarningThreshold": { - "title": "label.expiration-warning-threshold", - "description": "tooltip.expiration-warning-threshold", - "type": "string", - "placeholder": "label.duration", - "widget": { - "id": "datalist", - "data": [ - "PT0S", - "PT30S", - "PT1M", - "PT10M", - "PT30M", - "PT1H", - "PT4H", - "PT12H", - "PT24H" - ] - }, - "default": null, - "pattern": "^(R\\d*\\/)?P(?:\\d+(?:\\.\\d+)?Y)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?W)?(?:\\d+(?:\\.\\d+)?D)?(?:T(?:\\d+(?:\\.\\d+)?H)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?S)?)?$" } } } diff --git a/ui/src/assets/schema/provider/file-system.schema.json b/ui/src/assets/schema/provider/file-system.schema.json index e015b15d8..f44761f86 100644 --- a/ui/src/assets/schema/provider/file-system.schema.json +++ b/ui/src/assets/schema/provider/file-system.schema.json @@ -114,51 +114,6 @@ "minimum": 0, "maximum": 1, "default": null - }, - "resolveViaPredicatesOnly": { - "title": "label.resolve-via-predicates-only", - "description": "tooltip.resolve-via-predicates-only", - "type": "boolean", - "widget": { - "id": "boolean-radio" - }, - "oneOf": [ - { - "enum": [ - true - ], - "description": "value.true" - }, - { - "enum": [ - false - ], - "description": "value.false" - } - ], - "default": true - }, - "expirationWarningThreshold": { - "title": "label.expiration-warning-threshold", - "description": "tooltip.expiration-warning-threshold", - "type": "string", - "placeholder": "label.duration", - "widget": { - "id": "datalist", - "data": [ - "PT0S", - "PT30S", - "PT1M", - "PT10M", - "PT30M", - "PT1H", - "PT4H", - "PT12H", - "PT24H" - ] - }, - "default": null, - "pattern": "^(R\\d*\\/)?P(?:\\d+(?:\\.\\d+)?Y)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?W)?(?:\\d+(?:\\.\\d+)?D)?(?:T(?:\\d+(?:\\.\\d+)?H)?(?:\\d+(?:\\.\\d+)?M)?(?:\\d+(?:\\.\\d+)?S)?)?$" } } } From b46699da774047372078d89fe03357dea1833304 Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Wed, 7 Nov 2018 10:27:28 -0700 Subject: [PATCH 05/20] [SHIBUI-701] Adding support for provider schemas. Added new controller. This is a WIP. --- ...adataProviderUiDefinitionController.groovy | 73 +++++++++++++++++++ .../JsonSchemaComponentsConfiguration.java | 10 +++ .../jsonschema/JsonSchemaLocationLookup.java | 21 ++++++ .../JsonSchemaResourceLocation.java | 3 +- 4 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataProviderUiDefinitionController.groovy diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataProviderUiDefinitionController.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataProviderUiDefinitionController.groovy new file mode 100644 index 000000000..c68f1eedb --- /dev/null +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataProviderUiDefinitionController.groovy @@ -0,0 +1,73 @@ +package edu.internet2.tier.shibboleth.admin.ui.controller + +import com.fasterxml.jackson.databind.ObjectMapper +import edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation +import edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocationRegistry +import edu.internet2.tier.shibboleth.admin.ui.service.JsonSchemaBuilderService +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +import javax.annotation.PostConstruct + +import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.dynamicHttpMetadataProviderSchema +import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.filesystemMetadataProviderSchema +import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.localDynamicMetadataProviderSchema +import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.metadataSourcesSchema +import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR +import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType + +/** + * Controller implementing REST resource responsible for exposing structure definition for metadata sources user + * interface in terms of JSON schema. + * + * @author Dmitriy Kopylenko + * @author Bill Smith (wsmith@unicon.net) + */ +@RestController +@RequestMapping('/api/ui/MetadataProvider') +class MetadataProviderUiDefinitionController { + + @Autowired + JsonSchemaResourceLocationRegistry jsonSchemaResourceLocationRegistry + + JsonSchemaResourceLocation jsonSchemaLocation + + @Autowired + ObjectMapper jacksonObjectMapper + + @GetMapping(value = "/{providerType}") + ResponseEntity getUiDefinitionJsonSchema(@PathVariable String providerType) { + switch (JsonSchemaResourceLocation.SchemaType.valueOf(providerType)) { + case SchemaType.LOCAL_DYNAMIC_METADATA_PROVIDER: + jsonSchemaLocation = localDynamicMetadataProviderSchema(this.jsonSchemaResourceLocationRegistry) + break + case SchemaType.FILESYSTEM_METADATA_PROVIDER: + jsonSchemaLocation = filesystemMetadataProviderSchema(this.jsonSchemaResourceLocationRegistry) + break + case SchemaType.DYNAMIC_HTTP_METADATA_PROVIDER: + jsonSchemaLocation = dynamicHttpMetadataProviderSchema(this.jsonSchemaResourceLocationRegistry) + break + default: + throw new UnsupportedOperationException("Json schema for an unsupported metadata provider (" + providerType + ") was requested") + } + try { + def parsedJson = jacksonObjectMapper.readValue(this.jsonSchemaLocation.url, Map) + return ResponseEntity.ok(parsedJson) + } + catch (Exception e) { + e.printStackTrace() + return ResponseEntity.status(INTERNAL_SERVER_ERROR) + .body([jsonParseError : e.getMessage(), + sourceUiSchemaDefinitionFile: this.jsonSchemaLocation.url]) + } + } + + @PostConstruct + void init() { + this.jsonSchemaLocation = metadataSourcesSchema(this.jsonSchemaResourceLocationRegistry) + } +} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/JsonSchemaComponentsConfiguration.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/JsonSchemaComponentsConfiguration.java index 1bf2745c6..326e6e4b5 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/JsonSchemaComponentsConfiguration.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/JsonSchemaComponentsConfiguration.java @@ -11,6 +11,7 @@ import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.*; import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.ENTITY_ATTRIBUTES_FILTERS; +import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.FILESYSTEM_METADATA_PROVIDER; import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.METADATA_SOURCES; /** @@ -30,6 +31,9 @@ public class JsonSchemaComponentsConfiguration { @Setter private String entityAttributesFiltersUiSchemaLocation = "classpath:entity-attributes-filters-ui-schema.json"; + @Setter + private String filesystemMetadtaProviderUiSchemaLocation = "classpath:file-system-metadata-provider.schema.json"; + @Bean public JsonSchemaResourceLocationRegistry jsonSchemaResourceLocationRegistry(ResourceLoader resourceLoader, ObjectMapper jacksonMapper) { return JsonSchemaResourceLocationRegistry.inMemory() @@ -44,6 +48,12 @@ public JsonSchemaResourceLocationRegistry jsonSchemaResourceLocationRegistry(Res .resourceLoader(resourceLoader) .jacksonMapper(jacksonMapper) .detectMalformedJson(true) + .build()) + .register(FILESYSTEM_METADATA_PROVIDER, JsonSchemaLocationBuilder.with() + .jsonSchemaLocation(filesystemMetadtaProviderUiSchemaLocation) + .resourceLoader(resourceLoader) + .jacksonMapper(jacksonMapper) + .detectMalformedJson(true) .build()); } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaLocationLookup.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaLocationLookup.java index b9d9ac1f1..1a055984c 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaLocationLookup.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaLocationLookup.java @@ -2,6 +2,9 @@ import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.ENTITY_ATTRIBUTES_FILTERS; import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.METADATA_SOURCES; +import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.FILESYSTEM_METADATA_PROVIDER; +import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.LOCAL_DYNAMIC_METADATA_PROVIDER; +import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.DYNAMIC_HTTP_METADATA_PROVIDER; /** * Utility methods for common JSON schema types lookups. @@ -35,4 +38,22 @@ public static JsonSchemaResourceLocation entityAttributesFiltersSchema(JsonSchem .lookup(ENTITY_ATTRIBUTES_FILTERS) .orElseThrow(() -> new IllegalStateException("JSON schema resource location for metadata sources is not registered.")); } + + public static JsonSchemaResourceLocation filesystemMetadataProviderSchema(JsonSchemaResourceLocationRegistry resourceLocationRegistry) { + return resourceLocationRegistry + .lookup(FILESYSTEM_METADATA_PROVIDER) + .orElseThrow(() -> new IllegalStateException("JSON schema resource location for metadata sources is not registered.")); + } + + public static JsonSchemaResourceLocation localDynamicMetadataProviderSchema(JsonSchemaResourceLocationRegistry resourceLocationRegistry) { + return resourceLocationRegistry + .lookup(LOCAL_DYNAMIC_METADATA_PROVIDER) + .orElseThrow(() -> new IllegalStateException("JSON schema resource location for metadata sources is not registered.")); + } + + public static JsonSchemaResourceLocation dynamicHttpMetadataProviderSchema(JsonSchemaResourceLocationRegistry resourceLocationRegistry) { + return resourceLocationRegistry + .lookup(DYNAMIC_HTTP_METADATA_PROVIDER) + .orElseThrow(() -> new IllegalStateException("JSON schema resource location for metadata sources is not registered.")); + } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaResourceLocation.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaResourceLocation.java index f08ac6069..e84d512d3 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaResourceLocation.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaResourceLocation.java @@ -91,6 +91,7 @@ public static JsonSchemaResourceLocation newSchemaLocation(String jsonSchemaLoca } public enum SchemaType { - METADATA_SOURCES, ENTITY_ATTRIBUTES_FILTERS + METADATA_SOURCES, ENTITY_ATTRIBUTES_FILTERS, + FILESYSTEM_METADATA_PROVIDER, LOCAL_DYNAMIC_METADATA_PROVIDER, DYNAMIC_HTTP_METADATA_PROVIDER } } \ No newline at end of file From ffe0fb948f9ada4125bbefc6eea64d8e791e0ef3 Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Wed, 7 Nov 2018 14:37:29 -0700 Subject: [PATCH 06/20] [SHIBUI-701] Updates to SchemaType enum to include resolvers. Updates to configuration to support filesystem metadata resolver Created new controller to handle resolver json schema retrieval. Also has commented-out code for 703 and 704. --- ...dataResolverUiDefinitionController.groovy} | 40 +++++++++---------- .../JsonSchemaComponentsConfiguration.java | 34 ++++++++++++++-- .../jsonschema/JsonSchemaLocationLookup.java | 35 +++++++++------- .../JsonSchemaResourceLocation.java | 19 ++++++++- 4 files changed, 86 insertions(+), 42 deletions(-) rename backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/{MetadataProviderUiDefinitionController.groovy => MetadataResolverUiDefinitionController.groovy} (66%) diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataProviderUiDefinitionController.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolverUiDefinitionController.groovy similarity index 66% rename from backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataProviderUiDefinitionController.groovy rename to backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolverUiDefinitionController.groovy index c68f1eedb..e8c383aeb 100644 --- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataProviderUiDefinitionController.groovy +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolverUiDefinitionController.groovy @@ -3,7 +3,6 @@ package edu.internet2.tier.shibboleth.admin.ui.controller import com.fasterxml.jackson.databind.ObjectMapper import edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation import edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocationRegistry -import edu.internet2.tier.shibboleth.admin.ui.service.JsonSchemaBuilderService import org.springframework.beans.factory.annotation.Autowired import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.GetMapping @@ -11,25 +10,22 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController -import javax.annotation.PostConstruct - -import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.dynamicHttpMetadataProviderSchema import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.filesystemMetadataProviderSchema -import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.localDynamicMetadataProviderSchema -import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.metadataSourcesSchema +//import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.localDynamicMetadataProviderSchema +//import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.dynamicHttpMetadataProviderSchema import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType /** - * Controller implementing REST resource responsible for exposing structure definition for metadata sources user + * Controller implementing REST resource responsible for exposing structure definition for metadata resolvers user * interface in terms of JSON schema. * * @author Dmitriy Kopylenko * @author Bill Smith (wsmith@unicon.net) */ @RestController -@RequestMapping('/api/ui/MetadataProvider') -class MetadataProviderUiDefinitionController { +@RequestMapping('/api/ui/MetadataResolver') +class MetadataResolverUiDefinitionController { @Autowired JsonSchemaResourceLocationRegistry jsonSchemaResourceLocationRegistry @@ -39,20 +35,20 @@ class MetadataProviderUiDefinitionController { @Autowired ObjectMapper jacksonObjectMapper - @GetMapping(value = "/{providerType}") - ResponseEntity getUiDefinitionJsonSchema(@PathVariable String providerType) { - switch (JsonSchemaResourceLocation.SchemaType.valueOf(providerType)) { - case SchemaType.LOCAL_DYNAMIC_METADATA_PROVIDER: - jsonSchemaLocation = localDynamicMetadataProviderSchema(this.jsonSchemaResourceLocationRegistry) - break - case SchemaType.FILESYSTEM_METADATA_PROVIDER: + @GetMapping(value = "/{resolverType}") + ResponseEntity getUiDefinitionJsonSchema(@PathVariable String resolverType) { + switch (SchemaType.valueOf(resolverType)) { + case SchemaType.FILESYSTEM_METADATA_RESOLVER: jsonSchemaLocation = filesystemMetadataProviderSchema(this.jsonSchemaResourceLocationRegistry) break - case SchemaType.DYNAMIC_HTTP_METADATA_PROVIDER: +/* case SchemaType.LOCAL_DYNAMIC_METADATA_RESOLVER: + jsonSchemaLocation = localDynamicMetadataProviderSchema(this.jsonSchemaResourceLocationRegistry) + break*/ +/* case SchemaType.DYNAMIC_HTTP_METADATA_RESOLVER: jsonSchemaLocation = dynamicHttpMetadataProviderSchema(this.jsonSchemaResourceLocationRegistry) - break + break*/ default: - throw new UnsupportedOperationException("Json schema for an unsupported metadata provider (" + providerType + ") was requested") + throw new UnsupportedOperationException("Json schema for an unsupported metadata resolver (" + resolverType + ") was requested") } try { def parsedJson = jacksonObjectMapper.readValue(this.jsonSchemaLocation.url, Map) @@ -66,8 +62,8 @@ class MetadataProviderUiDefinitionController { } } - @PostConstruct - void init() { - this.jsonSchemaLocation = metadataSourcesSchema(this.jsonSchemaResourceLocationRegistry) + @GetMapping(value = "/types") + ResponseEntity getResolverTypes() { + return ResponseEntity.ok(SchemaType.getResolverTypes()) } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/JsonSchemaComponentsConfiguration.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/JsonSchemaComponentsConfiguration.java index 326e6e4b5..4c4ad86db 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/JsonSchemaComponentsConfiguration.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/JsonSchemaComponentsConfiguration.java @@ -11,8 +11,10 @@ import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.*; import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.ENTITY_ATTRIBUTES_FILTERS; -import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.FILESYSTEM_METADATA_PROVIDER; import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.METADATA_SOURCES; +import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.FILESYSTEM_METADATA_RESOLVER; +//import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.LOCAL_DYNAMIC_METADATA_RESOLVER; +//import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.DYNAMIC_HTTP_METADATA_RESOLVER; /** * @author Dmitriy Kopylenko @@ -31,8 +33,20 @@ public class JsonSchemaComponentsConfiguration { @Setter private String entityAttributesFiltersUiSchemaLocation = "classpath:entity-attributes-filters-ui-schema.json"; + //Configured via @ConfigurationProperties (using setter method) with 'shibui.filesystem-metadata-provider-ui-schema-location' property and + // default value set here if that property is not explicitly set in application.properties + @Setter + private String filesystemMetadataResolverUiSchemaLocation = "classpath:file-system-metadata-provider.schema.json"; + +/* TODO: Will be added as part of SHIBUI-703 @Setter - private String filesystemMetadtaProviderUiSchemaLocation = "classpath:file-system-metadata-provider.schema.json"; + private String localDynamicMetadataResolverUiSchemaLocation = "classpath:local-dynamic-metadata-provider.schema.json"; +*/ + +/* TODO: Will be added as part of SHIBUI-704 + @Setter + private String dynamicHttpMetadataResolverUiSchemaLocation = "classpath:dynamic-http-metadata-provider.schema.json"; +*/ @Bean public JsonSchemaResourceLocationRegistry jsonSchemaResourceLocationRegistry(ResourceLoader resourceLoader, ObjectMapper jacksonMapper) { @@ -49,12 +63,24 @@ public JsonSchemaResourceLocationRegistry jsonSchemaResourceLocationRegistry(Res .jacksonMapper(jacksonMapper) .detectMalformedJson(true) .build()) - .register(FILESYSTEM_METADATA_PROVIDER, JsonSchemaLocationBuilder.with() - .jsonSchemaLocation(filesystemMetadtaProviderUiSchemaLocation) + .register(FILESYSTEM_METADATA_RESOLVER, JsonSchemaLocationBuilder.with() + .jsonSchemaLocation(filesystemMetadataResolverUiSchemaLocation) .resourceLoader(resourceLoader) .jacksonMapper(jacksonMapper) .detectMalformedJson(true) .build()); + /*.register(DYNAMIC_HTTP_METADATA_RESOLVER, JsonSchemaLocationBuilder.with() + .jsonSchemaLocation(dynamicHttpMetadataResolverUiSchemaLocation) + .resourceLoader(resourceLoader) + .jacksonMapper(jacksonMapper) + .detectMalformedJson(true) + .build()) + .register(LOCAL_DYNAMIC_METADATA_RESOLVER, JsonSchemaLocationBuilder.with() + .jsonSchemaLocation(localDynamicMetadataResolverUiSchemaLocation) + .resourceLoader(resourceLoader) + .jacksonMapper(jacksonMapper) + .detectMalformedJson(true) + .build());*/ } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaLocationLookup.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaLocationLookup.java index 1a055984c..62f46969e 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaLocationLookup.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaLocationLookup.java @@ -2,9 +2,9 @@ import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.ENTITY_ATTRIBUTES_FILTERS; import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.METADATA_SOURCES; -import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.FILESYSTEM_METADATA_PROVIDER; -import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.LOCAL_DYNAMIC_METADATA_PROVIDER; -import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.DYNAMIC_HTTP_METADATA_PROVIDER; +import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.FILESYSTEM_METADATA_RESOLVER; +//import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.LOCAL_DYNAMIC_METADATA_RESOLVER; +//import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.DYNAMIC_HTTP_METADATA_RESOLVER; /** * Utility methods for common JSON schema types lookups. @@ -30,7 +30,7 @@ public static JsonSchemaResourceLocation metadataSourcesSchema(JsonSchemaResourc * Searches entity attributes filters JSON schema resource location object in the given location registry. * * @param resourceLocationRegistry - * @returnentity attributes filters JSON schema resource location object + * @return entity attributes filters JSON schema resource location object * @throws IllegalStateException if schema is not found in the given registry */ public static JsonSchemaResourceLocation entityAttributesFiltersSchema(JsonSchemaResourceLocationRegistry resourceLocationRegistry) { @@ -39,21 +39,28 @@ public static JsonSchemaResourceLocation entityAttributesFiltersSchema(JsonSchem .orElseThrow(() -> new IllegalStateException("JSON schema resource location for metadata sources is not registered.")); } + /** + * Searches filesystem metadata resolver JSON schema resource location object in the given location registry. + * + * @param resourceLocationRegistry + * @return filesystem metadata resolver JSON schema resource location object + * @throws IllegalStateException if schema is not found in the given registry + */ public static JsonSchemaResourceLocation filesystemMetadataProviderSchema(JsonSchemaResourceLocationRegistry resourceLocationRegistry) { return resourceLocationRegistry - .lookup(FILESYSTEM_METADATA_PROVIDER) - .orElseThrow(() -> new IllegalStateException("JSON schema resource location for metadata sources is not registered.")); + .lookup(FILESYSTEM_METADATA_RESOLVER) + .orElseThrow(() -> new IllegalStateException("JSON schema resource location for filesystem metadata resolver is not registered.")); } - public static JsonSchemaResourceLocation localDynamicMetadataProviderSchema(JsonSchemaResourceLocationRegistry resourceLocationRegistry) { +/* public static JsonSchemaResourceLocation localDynamicMetadataProviderSchema(JsonSchemaResourceLocationRegistry resourceLocationRegistry) { return resourceLocationRegistry - .lookup(LOCAL_DYNAMIC_METADATA_PROVIDER) - .orElseThrow(() -> new IllegalStateException("JSON schema resource location for metadata sources is not registered.")); - } + .lookup(LOCAL_DYNAMIC_METADATA_RESOLVER) + .orElseThrow(() -> new IllegalStateException("JSON schema resource location for local dynamic metadata resolver is not registered.")); + }*/ - public static JsonSchemaResourceLocation dynamicHttpMetadataProviderSchema(JsonSchemaResourceLocationRegistry resourceLocationRegistry) { +/* public static JsonSchemaResourceLocation dynamicHttpMetadataProviderSchema(JsonSchemaResourceLocationRegistry resourceLocationRegistry) { return resourceLocationRegistry - .lookup(DYNAMIC_HTTP_METADATA_PROVIDER) - .orElseThrow(() -> new IllegalStateException("JSON schema resource location for metadata sources is not registered.")); - } + .lookup(DYNAMIC_HTTP_METADATA_RESOLVER) + .orElseThrow(() -> new IllegalStateException("JSON schema resource location for dynamic http metadata resolver is not registered.")); + }*/ } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaResourceLocation.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaResourceLocation.java index e84d512d3..61f6bbeff 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaResourceLocation.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaResourceLocation.java @@ -9,7 +9,10 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.util.List; import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * Encapsulates arbitrary JSON schema location. @@ -91,7 +94,19 @@ public static JsonSchemaResourceLocation newSchemaLocation(String jsonSchemaLoca } public enum SchemaType { - METADATA_SOURCES, ENTITY_ATTRIBUTES_FILTERS, - FILESYSTEM_METADATA_PROVIDER, LOCAL_DYNAMIC_METADATA_PROVIDER, DYNAMIC_HTTP_METADATA_PROVIDER + // common types + METADATA_SOURCES, + + // filter types + ENTITY_ATTRIBUTES_FILTERS, + + // resolver types + FILESYSTEM_METADATA_RESOLVER; +// LOCAL_DYNAMIC_METADATA_RESOLVER, +// DYNAMIC_HTTP_METADATA_RESOLVER; + + public static List getResolverTypes() { + return Stream.of(SchemaType.values()).map(SchemaType::name).filter(it -> it.endsWith("RESOLVER")).collect(Collectors.toList()); + } } } \ No newline at end of file From e785e68b8dad1ac66dfc00ca92a86febcd2f0100 Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Wed, 7 Nov 2018 14:58:47 -0700 Subject: [PATCH 07/20] [SHIBUI-701] Unit test fix. --- ...sUiDefinitionControllerIntegrationTests.groovy | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/BadJSONMetadataSourcesUiDefinitionControllerIntegrationTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/BadJSONMetadataSourcesUiDefinitionControllerIntegrationTests.groovy index 1da336ff2..5c4efc0b6 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/BadJSONMetadataSourcesUiDefinitionControllerIntegrationTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/BadJSONMetadataSourcesUiDefinitionControllerIntegrationTests.groovy @@ -12,6 +12,8 @@ import org.springframework.test.context.ActiveProfiles import spock.lang.Specification import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.* +import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.ENTITY_ATTRIBUTES_FILTERS +import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.FILESYSTEM_METADATA_RESOLVER import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.METADATA_SOURCES /** @@ -49,6 +51,19 @@ class BadJSONMetadataSourcesUiDefinitionControllerIntegrationTests extends Speci .jacksonMapper(jacksonMapper) .detectMalformedJson(false) .build()) + //TODO Maybe we need a separate test config here so we don't have to define all of the locations? + .register(ENTITY_ATTRIBUTES_FILTERS, JsonSchemaLocationBuilder.with() + .jsonSchemaLocation('classpath:entity-attributes-filters-ui-schema.json') + .resourceLoader(resourceLoader) + .jacksonMapper(jacksonMapper) + .detectMalformedJson(false) + .build()) + .register(FILESYSTEM_METADATA_RESOLVER, JsonSchemaLocationBuilder.with() + .jsonSchemaLocation('classpath:file-system-metadata-provider.schema.json') + .resourceLoader(resourceLoader) + .jacksonMapper(jacksonMapper) + .detectMalformedJson(false) + .build()) } } } \ No newline at end of file From e0fe40969e3e2e23a5532e4a469b9fa4df5240ce Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Fri, 9 Nov 2018 08:36:28 -0700 Subject: [PATCH 08/20] [SHIBUI-701] Added json types fo SchemaType so that the UI knows what @Type to pass along to the backend. --- .../JsonSchemaResourceLocation.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaResourceLocation.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaResourceLocation.java index 61f6bbeff..2f37723af 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaResourceLocation.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/JsonSchemaResourceLocation.java @@ -95,18 +95,29 @@ public static JsonSchemaResourceLocation newSchemaLocation(String jsonSchemaLoca public enum SchemaType { // common types - METADATA_SOURCES, + METADATA_SOURCES("MetadataSources"), // filter types - ENTITY_ATTRIBUTES_FILTERS, + ENTITY_ATTRIBUTES_FILTERS("EntityAttributesFilters"), // resolver types - FILESYSTEM_METADATA_RESOLVER; + FILE_BACKED_HTTP_METADATA_RESOLVER("FileBackedHttpMetadataResolver"), + FILESYSTEM_METADATA_RESOLVER("FilesystemMetadataResolver"); // LOCAL_DYNAMIC_METADATA_RESOLVER, // DYNAMIC_HTTP_METADATA_RESOLVER; + String jsonType; + + SchemaType(String jsonType) { + this.jsonType = jsonType; + } + + String getJsonType() { + return jsonType; + } + public static List getResolverTypes() { - return Stream.of(SchemaType.values()).map(SchemaType::name).filter(it -> it.endsWith("RESOLVER")).collect(Collectors.toList()); + return Stream.of(SchemaType.values()).map(SchemaType::getJsonType).filter(it -> it.endsWith("Resolver")).collect(Collectors.toList()); } } } \ No newline at end of file From 0fd30ce9290abd02f4ddc524ebf7ff9626fd1b84 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Fri, 9 Nov 2018 09:01:52 -0700 Subject: [PATCH 09/20] SHIBUI-701 integrated with schema endpoint for retrieving --- .../provider/effect/collection.effect.ts | 24 ++++++++++++++++++- .../model/file-system.provider.form.ts | 10 ++++---- .../widget/select/select.component.html | 11 ++++++++- .../widget/select/select.component.ts | 16 +++++++++++++ .../provider/metadata-provider.schema.json | 19 +++------------ 5 files changed, 57 insertions(+), 23 deletions(-) diff --git a/ui/src/app/metadata/provider/effect/collection.effect.ts b/ui/src/app/metadata/provider/effect/collection.effect.ts index 73ce52ea5..5ac47c647 100644 --- a/ui/src/app/metadata/provider/effect/collection.effect.ts +++ b/ui/src/app/metadata/provider/effect/collection.effect.ts @@ -37,6 +37,9 @@ import { ClearProvider, ResetChanges } from '../action/entity.action'; import { ShowContentionAction } from '../../../contention/action/contention.action'; import { ContentionService } from '../../../contention/service/contention.service'; import { MetadataProvider } from '../../domain/model'; +import { AddNotification } from '../../../notification/action/notification.action'; +import { Notification, NotificationType } from '../../../notification/model/notification'; +import { WizardActionTypes, SetDisabled } from '../../../wizard/action/wizard.action'; /* istanbul ignore next */ @@ -96,11 +99,30 @@ export class CollectionEffects { .save(provider) .pipe( map(p => new AddProviderSuccess(p)), - catchError((e) => of(new AddProviderFail(e))) + catchError((e) => of(new AddProviderFail(e.error))) ) ) ); + @Effect() + createProviderFailDispatchNotification$ = this.actions$.pipe( + ofType(ProviderCollectionActionTypes.ADD_PROVIDER_FAIL), + map(action => action.payload), + map(error => new AddNotification( + new Notification( + NotificationType.Danger, + `${error.errorCode}: ${ error.errorMessage }`, + 8000 + ) + )) + ); + @Effect() + createProviderFailEnableForm$ = this.actions$.pipe( + ofType(ProviderCollectionActionTypes.ADD_PROVIDER_FAIL), + map(action => action.payload), + map(error => new SetDisabled(false)) + ); + @Effect({ dispatch: false }) createProviderSuccessRedirect$ = this.actions$.pipe( ofType(ProviderCollectionActionTypes.ADD_PROVIDER_SUCCESS), diff --git a/ui/src/app/metadata/provider/model/file-system.provider.form.ts b/ui/src/app/metadata/provider/model/file-system.provider.form.ts index e84e79aa4..ea4713106 100644 --- a/ui/src/app/metadata/provider/model/file-system.provider.form.ts +++ b/ui/src/app/metadata/provider/model/file-system.provider.form.ts @@ -4,8 +4,8 @@ import { BaseMetadataProviderEditor } from './base.provider.form'; export const FileSystemMetadataProviderWizard: Wizard = { ...BaseMetadataProviderEditor, - label: 'FileSystemMetadataProvider', - type: 'FileSystemMetadataResolver', + label: 'FilesystemMetadataProvider', + type: 'FilesystemMetadataResolver', getValidators(namesList: string[] = [], xmlIdList: string[] = []): any { const validators = BaseMetadataProviderEditor.getValidators(namesList); validators['/xmlId'] = (value, property, form) => { @@ -25,7 +25,7 @@ export const FileSystemMetadataProviderWizard: Wizard{{ schema.placeholder }} {{ schema.title }} - + + + + + +