diff --git a/.gitignore b/.gitignore index 3d9ba1c8d..592c5acc3 100644 --- a/.gitignore +++ b/.gitignore @@ -385,3 +385,6 @@ gradle-app.setting # pac4j pac4j-module/out/ + +#Local run shell script wrapper +r diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/ModelRepresentationConversions.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/ModelRepresentationConversions.java index b1669d8a9..f6dea7f9f 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/ModelRepresentationConversions.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/ModelRepresentationConversions.java @@ -212,13 +212,19 @@ public static Attribute getAttributeFromObjectAndRelyingPartyOverrideProperty(Ob overrideProperty.getAttributeFriendlyName(), (String) o); case SET: - return ATTRIBUTE_UTILITY.createAttributeWithStringValues(overrideProperty.getAttributeName(), - overrideProperty.getAttributeFriendlyName(), - (List) o); + if(((List)o).size() > 0) { + return ATTRIBUTE_UTILITY.createAttributeWithStringValues(overrideProperty.getAttributeName(), + overrideProperty.getAttributeFriendlyName(), + (List) o); + } + return null; case LIST: - return ATTRIBUTE_UTILITY.createAttributeWithStringValues(overrideProperty.getAttributeName(), - overrideProperty.getAttributeFriendlyName(), - (List) o); + if(((List)o).size() > 0) { + return ATTRIBUTE_UTILITY.createAttributeWithStringValues(overrideProperty.getAttributeName(), + overrideProperty.getAttributeFriendlyName(), + (List) o); + } + return null; default: throw new UnsupportedOperationException("getAttributeListFromRelyingPartyOverridesRepresentation was called with an unsupported type (" + overrideProperty.getDisplayType() + ")!"); } diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImplTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImplTests.groovy index 1c1778c60..6b5fd4214 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImplTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImplTests.groovy @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper import edu.internet2.tier.shibboleth.admin.ui.ShibbolethUiApplication import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfiguration import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration +import edu.internet2.tier.shibboleth.admin.ui.domain.Attribute import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor import edu.internet2.tier.shibboleth.admin.ui.domain.XSAny import edu.internet2.tier.shibboleth.admin.ui.domain.XSAnyBuilder @@ -25,6 +26,7 @@ import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService import edu.internet2.tier.shibboleth.admin.ui.util.RandomGenerator import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator import edu.internet2.tier.shibboleth.admin.util.AttributeUtility +import org.opensaml.saml.ext.saml2mdattr.EntityAttributes import org.skyscreamer.jsonassert.JSONAssert import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest @@ -877,6 +879,31 @@ class JPAEntityDescriptorServiceImplTests extends Specification { assert representation.relyingPartyOverrides.get('ignoreAuthenticationMethod') instanceof Boolean } + def "SHIBUI-1522"() { + when: + EntityDescriptor inputEd = openSamlObjects.unmarshalFromXml this.class.getResource('/metadata/SHIBUI-1522.xml').bytes + EntityDescriptorRepresentation edr = service.createRepresentationFromDescriptor(inputEd) + edr.relyingPartyOverrides = [nameIdFormats: [], authenticationMethods: []] + EntityDescriptor outputEd = service.createDescriptorFromRepresentation(edr) + + then: + outputEd.getExtensions().unknownXMLObjects[0].attributes.size() == 0 + + when: + edr.relyingPartyOverrides = [nameIdFormats: ['format1', 'format2']] + outputEd = service.createDescriptorFromRepresentation(edr) + + then: + outputEd.getExtensions().unknownXMLObjects[0].attributes.size() == 1 + + when: + edr.relyingPartyOverrides = [nameIdFormats: ['format1', 'format2'], authenticationMethods: ['auth1', 'auth2']] + outputEd = service.createDescriptorFromRepresentation(edr) + + then: + outputEd.getExtensions().unknownXMLObjects[0].attributes.size() == 2 + } + EntityDescriptor generateRandomEntityDescriptor() { EntityDescriptor ed = new EntityDescriptor() diff --git a/backend/src/test/resources/metadata/SHIBUI-1522.xml b/backend/src/test/resources/metadata/SHIBUI-1522.xml new file mode 100644 index 000000000..aa22bd172 --- /dev/null +++ b/backend/src/test/resources/metadata/SHIBUI-1522.xml @@ -0,0 +1,16 @@ + + + + + + Concur Solutions + + https://www.concur.com/sites/all/themes/Concur6/images/Concur_logo.png + + + urn:oid:1.3.6.1.4.1.5923.1.1.1.6 + + + diff --git a/ui/package-lock.json b/ui/package-lock.json index 2266275d2..e563a1f26 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -1990,29 +1990,29 @@ } }, "@ngrx/effects": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-7.4.0.tgz", - "integrity": "sha512-YjgB17WnLCBDPjAkHduKWsLFSGLZryPaTjY3EIvMF+WTRPDlgC5SAv2n7p3YIei6g6IYcEvOwLWBqZHFUXTgBw==" + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-8.4.0.tgz", + "integrity": "sha512-LQv+NIYkFehXMSBMT9xL04RvmDmbzSbCbSCXbNSH2hN216TqX83L29u5T4I06oGhzQ3xN+SSQXGWQiZYJvKuEA==" }, "@ngrx/entity": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@ngrx/entity/-/entity-7.4.0.tgz", - "integrity": "sha512-aFRDTNp6IFkYFlP9gV6hgNgtDYot9KYF8WVbaQTao9ihmdPumMBOCeRttPPiHS/cU41w9nW3xF53NgxQPnEiQA==" + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@ngrx/entity/-/entity-8.4.0.tgz", + "integrity": "sha512-oJYBW9w0YXODeGpp03bvnAShHbwF+44OyPd1zURnYDtpd1r6W8qWIDr77aYViic5YTzISURiZ9rxE2n8pkNvqw==" }, "@ngrx/router-store": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@ngrx/router-store/-/router-store-7.4.0.tgz", - "integrity": "sha512-ZpwTO1/ha3pxO7NV3jIfnwipBN1A719IjAOgrcmI8Ut06VH3HY/7JVFTkwLN/FyuHvl4EOlAVYmMAblmrymUWA==" + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@ngrx/router-store/-/router-store-8.4.0.tgz", + "integrity": "sha512-VTs8O4mAzxbZDtPYaiBG7FV+k4UY5iaIRK7RMvaeBrWMMqD1St63qX1oF6s79R1qAV/fQ1svJNytsArLAI2sXw==" }, "@ngrx/store": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-7.4.0.tgz", - "integrity": "sha512-kwTUHgfgBeAL4RQBjZO46z9v4Xzg8PXAgY4WwXdt3zUk1tF4ZvijMleFvFRUoiJJfxF/UM6jgIZ/yGrX2dXQuA==" + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-8.4.0.tgz", + "integrity": "sha512-Z8+2hfGcynGrzJuU7ixxYxOI6M2E0H8Omni1u01h55vvaZeoTO8bRt6OWqbjxxEsSKQmBBZ1XyOuuZXSWjxvYw==" }, "@ngrx/store-devtools": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@ngrx/store-devtools/-/store-devtools-7.4.0.tgz", - "integrity": "sha512-ZmPpquprBYUozbLuLMLZzUhI+LnMNGMNg8x1ij9yDxXWQADcJm1Zu7kouYE1r5SoCYxKfwJ3Ia1VQfS3A5S8dw==" + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@ngrx/store-devtools/-/store-devtools-8.4.0.tgz", + "integrity": "sha512-622z0CNdmfmPy17LFcewf/7xU2quhun+G+D7FdF58DlwZDFPJp0UotER1HW+ApGmI8h6hjeQs/7flzX0H12sIg==" }, "@ngtools/webpack": { "version": "8.3.12", diff --git a/ui/package.json b/ui/package.json index 98f66faf1..b47cb0463 100644 --- a/ui/package.json +++ b/ui/package.json @@ -26,11 +26,11 @@ "@angular/platform-browser-dynamic": "8.2.11", "@angular/router": "8.2.11", "@ng-bootstrap/ng-bootstrap": "5.1.1", - "@ngrx/effects": "7.4.0", - "@ngrx/entity": "7.4.0", - "@ngrx/router-store": "7.4.0", - "@ngrx/store": "7.4.0", - "@ngrx/store-devtools": "7.4.0", + "@ngrx/effects": "8.4.0", + "@ngrx/entity": "8.4.0", + "@ngrx/router-store": "8.4.0", + "@ngrx/store": "8.4.0", + "@ngrx/store-devtools": "8.4.0", "bootstrap": "4.3.1", "core-js": "^2.4.1", "deep-object-diff": "^1.1.0", @@ -73,4 +73,4 @@ "typescript": "3.5.3", "webpack-bundle-analyzer": "^3.3.2" } -} +} \ No newline at end of file diff --git a/ui/src/app/app.module.ts b/ui/src/app/app.module.ts index 4e9b543c3..00123bf82 100644 --- a/ui/src/app/app.module.ts +++ b/ui/src/app/app.module.ts @@ -33,7 +33,13 @@ import { NavigationService } from './core/service/navigation.service'; ], imports: [ StoreModule.forRoot(reducers, { - metaReducers + metaReducers, + runtimeChecks: { + strictActionImmutability: false, + strictActionSerializability: false, + strictStateImmutability: false, + strictStateSerializability: false + } }), StoreDevtoolsModule.instrument({ maxAge: 25, // Retains last 25 states @@ -42,7 +48,7 @@ import { NavigationService } from './core/service/navigation.service'; EffectsModule.forRoot([]), BrowserModule, CoreModule.forRoot(), - StoreRouterConnectingModule, + StoreRouterConnectingModule.forRoot(), NgbDropdownModule, NgbModalModule, NgbPopoverModule,