From bdf79b9397876e6c574eda48bc7d2e39389d8ed6 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 4 Sep 2018 13:38:58 -0700 Subject: [PATCH 1/6] SHIBUI-823 Implemented notification for failed preview --- .../metadata/domain/effect/entity.effect.ts | 33 ++++++++++++++----- .../widget/button/icon-button.component.html | 2 +- .../widget/button/icon-button.component.ts | 15 +++++++-- .../filter-target.component.html | 6 +++- 4 files changed, 42 insertions(+), 14 deletions(-) diff --git a/ui/src/app/metadata/domain/effect/entity.effect.ts b/ui/src/app/metadata/domain/effect/entity.effect.ts index 2bf1825aa..ec722591f 100644 --- a/ui/src/app/metadata/domain/effect/entity.effect.ts +++ b/ui/src/app/metadata/domain/effect/entity.effect.ts @@ -1,6 +1,7 @@ import { Injectable } from '@angular/core'; import { Effect, Actions, ofType } from '@ngrx/effects'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import { map, tap } from 'rxjs/operators'; @@ -12,6 +13,10 @@ import { MetadataTypes } from '../domain.type'; import { EntityIdService } from '../service/entity-id.service'; import * as entityActions from '../action/entity.action'; +import * as fromRoot from '../../../app.reducer'; + +import { AddNotification } from '../../../notification/action/notification.action'; +import { Notification, NotificationType } from '../../../notification/model/notification'; @Injectable() export class EntityEffects { @@ -27,20 +32,30 @@ export class EntityEffects { private actions$: Actions, private modalService: NgbModal, private providerService: ResolverService, - private entityService: EntityIdService + private entityService: EntityIdService, + private store: Store ) { } openModal(prev: { id: string, entity: MetadataEntity }): void { let { id, entity } = prev, request: Observable = entity.kind === MetadataTypes.FILTER ? this.entityService.preview(id) : this.providerService.preview(id); - request.subscribe(xml => { - let modal = this.modalService.open(PreviewDialogComponent, { - size: 'lg', - windowClass: 'modal-xl' - }); - modal.componentInstance.entity = entity; - modal.componentInstance.xml = xml; - }); + request.subscribe( + xml => { + let modal = this.modalService.open(PreviewDialogComponent, { + size: 'lg', + windowClass: 'modal-xl' + }); + modal.componentInstance.entity = entity; + modal.componentInstance.xml = xml; + }, + err => { + this.store.dispatch(new AddNotification(new Notification( + NotificationType.Danger, + `Unable to preview entity.`, + 8000 + ))); + } + ); } } /* istanbul ignore next */ diff --git a/ui/src/app/schema-form/widget/button/icon-button.component.html b/ui/src/app/schema-form/widget/button/icon-button.component.html index 107a8eb7c..cb830c4df 100644 --- a/ui/src/app/schema-form/widget/button/icon-button.component.html +++ b/ui/src/app/schema-form/widget/button/icon-button.component.html @@ -1,4 +1,4 @@ - \ No newline at end of file diff --git a/ui/src/app/schema-form/widget/button/icon-button.component.ts b/ui/src/app/schema-form/widget/button/icon-button.component.ts index 2dcca890f..652490804 100644 --- a/ui/src/app/schema-form/widget/button/icon-button.component.ts +++ b/ui/src/app/schema-form/widget/button/icon-button.component.ts @@ -1,8 +1,9 @@ import { - Component, AfterViewInit, + Component, AfterViewInit, ChangeDetectorRef } from '@angular/core'; import { ButtonWidget } from 'ngx-schema-form'; import { ɵb as ActionRegistry } from 'ngx-schema-form'; +import { interval } from 'rxjs'; @Component({ selector: 'icon-button', @@ -10,9 +11,14 @@ import { ɵb as ActionRegistry } from 'ngx-schema-form'; }) export class IconButtonComponent extends ButtonWidget implements AfterViewInit { - action = ($event) => {}; + visible = false; - constructor(private actionRegistry: ActionRegistry) { + action = (e) => {}; + + constructor( + private actionRegistry: ActionRegistry, + private changeDetector: ChangeDetectorRef + ) { super(); } @@ -24,5 +30,8 @@ export class IconButtonComponent extends ButtonWidget implements AfterViewInit { } e.preventDefault(); }; + + this.visible = !!this.actionRegistry.get(this.button.id); + this.changeDetector.detectChanges(); } } diff --git a/ui/src/app/schema-form/widget/filter-target/filter-target.component.html b/ui/src/app/schema-form/widget/filter-target/filter-target.component.html index c234bc490..37bc19ca4 100644 --- a/ui/src/app/schema-form/widget/filter-target/filter-target.component.html +++ b/ui/src/app/schema-form/widget/filter-target/filter-target.component.html @@ -98,7 +98,11 @@
  • {{ id }} - + + From 683feca70ee2904a386e63cb306c698dd3c74bbb Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Wed, 5 Sep 2018 08:05:00 -0700 Subject: [PATCH 2/6] SHIBUI-823 Fixed test --- ui/src/app/metadata/domain/effect/entity.effect.spec.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ui/src/app/metadata/domain/effect/entity.effect.spec.ts b/ui/src/app/metadata/domain/effect/entity.effect.spec.ts index 07f7143e5..1a8c18a0d 100644 --- a/ui/src/app/metadata/domain/effect/entity.effect.spec.ts +++ b/ui/src/app/metadata/domain/effect/entity.effect.spec.ts @@ -10,6 +10,9 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { NgbModalStub } from '../../../../testing/modal.stub'; import { EntityAttributesFilterEntity, FileBackedHttpMetadataResolver } from '../entity'; +import * as fromRoot from '../../../app.reducer'; +import { StoreModule } from '@ngrx/store'; + describe('Entity Effects', () => { let effects: EntityEffects; let providerService: any; @@ -35,6 +38,9 @@ describe('Entity Effects', () => { }, { provide: Actions, useFactory: getActions } ], + imports: [ + StoreModule.forRoot(fromRoot.reducers) + ] }); effects = TestBed.get(EntityEffects); From 7d2040b5dc76ec41e6f7c6e5f74cb0f0c7cd80c8 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Wed, 5 Sep 2018 08:14:53 -0700 Subject: [PATCH 3/6] SHIBUI-806 fixed reversed check --- ui/src/app/metadata/provider/model/base.provider.form.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 e329e2605..7c78fe332 100644 --- a/ui/src/app/metadata/provider/model/base.provider.form.ts +++ b/ui/src/app/metadata/provider/model/base.provider.form.ts @@ -32,7 +32,7 @@ export const BaseMetadataProviderEditor: Wizard = { return err; }, '/metadataURL': (value, property, form) => { - return !!UriValidator.isUri(value) ? { + return !UriValidator.isUri(value) ? { code: 'INVALID_URI', path: `#${property.path}`, message: 'URI must be valid format.', From 46bc15b9bc499e91ef08e809c9dd8a46cd5dac2b Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Fri, 7 Sep 2018 11:22:18 -0400 Subject: [PATCH 4/6] SHIBUI-828: use correct mutable resolvers collection to search from --- .../OpenSamlChainingMetadataResolver.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlChainingMetadataResolver.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlChainingMetadataResolver.java index aa5f45745..38b032834 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlChainingMetadataResolver.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlChainingMetadataResolver.java @@ -4,14 +4,18 @@ import com.google.common.collect.Collections2; import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements; import net.shibboleth.utilities.java.support.component.ComponentInitializationException; +import net.shibboleth.utilities.java.support.component.ComponentSupport; +import net.shibboleth.utilities.java.support.resolver.CriteriaSet; import net.shibboleth.utilities.java.support.resolver.ResolverException; import org.opensaml.saml.metadata.resolver.ChainingMetadataResolver; import org.opensaml.saml.metadata.resolver.MetadataResolver; import org.opensaml.saml.metadata.resolver.RefreshableMetadataResolver; +import org.opensaml.saml.saml2.metadata.EntityDescriptor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -49,6 +53,26 @@ public List getResolvers() { return mutableResolvers; } + @Override + @Nonnull public Iterable resolve(@Nullable final CriteriaSet criteria) throws ResolverException { + ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this); + + for (final MetadataResolver resolver : mutableResolvers) { + try { + final Iterable descriptors = resolver.resolve(criteria); + if (descriptors != null && descriptors.iterator().hasNext()) { + return descriptors; + } + } catch (final ResolverException e) { + log.warn("Error retrieving metadata from resolver of type {}, proceeding to next resolver", + resolver.getClass().getName(), e); + continue; + } + } + + return Collections.emptyList(); + } + @Override protected void doInitialize() throws ComponentInitializationException { super.doInitialize(); From c6cc829a9a5bf62e989c987a203af9c5709f6c47 Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Mon, 10 Sep 2018 07:43:30 -0400 Subject: [PATCH 5/6] Add comment --- .../resolvers/opensaml/OpenSamlChainingMetadataResolver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlChainingMetadataResolver.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlChainingMetadataResolver.java index 38b032834..cfea6d89c 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlChainingMetadataResolver.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlChainingMetadataResolver.java @@ -56,7 +56,7 @@ public List getResolvers() { @Override @Nonnull public Iterable resolve(@Nullable final CriteriaSet criteria) throws ResolverException { ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this); - + //Our overridden method uses a collection of mutable resolvers instead of regular resolvers for (final MetadataResolver resolver : mutableResolvers) { try { final Iterable descriptors = resolver.resolve(criteria); From 64efd4edd8379e83a5504158e30c557b4c0a858c Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Mon, 10 Sep 2018 11:32:35 -0400 Subject: [PATCH 6/6] Add DirtiesContext --- .../MetadataResolversControllerIntegrationTests.groovy | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversControllerIntegrationTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversControllerIntegrationTests.groovy index 9775160bd..221c5010e 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversControllerIntegrationTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversControllerIntegrationTests.groovy @@ -21,6 +21,7 @@ import org.springframework.boot.test.web.client.TestRestTemplate import org.springframework.context.annotation.Bean import org.springframework.http.HttpEntity import org.springframework.http.HttpHeaders +import org.springframework.test.annotation.DirtiesContext import org.springframework.test.context.ActiveProfiles import spock.lang.Specification import spock.lang.Unroll @@ -150,6 +151,7 @@ class MetadataResolversControllerIntegrationTests extends Specification { } @Unroll + @DirtiesContext def "POST new concrete MetadataResolver of type #resolverType -> /api/MetadataResolvers"(String resolverType) { given: 'New MetadataResolver JSON representation' def resolver = generator.buildRandomMetadataResolverOfType(resolverType)