From d772007a55a0950826cfe4fc84f5d462c2171cb1 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Thu, 9 Jun 2022 13:46:08 -0700 Subject: [PATCH 01/88] SHIBUI-2262 Merge develop to branch with test fix --- .../envers/MetadataResolverEnversVersioningTests.groovy | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/enversTest/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/envers/MetadataResolverEnversVersioningTests.groovy b/backend/src/enversTest/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/envers/MetadataResolverEnversVersioningTests.groovy index 85e854d3d..6d976a033 100644 --- a/backend/src/enversTest/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/envers/MetadataResolverEnversVersioningTests.groovy +++ b/backend/src/enversTest/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/envers/MetadataResolverEnversVersioningTests.groovy @@ -268,7 +268,7 @@ class MetadataResolverEnversVersioningTests extends Specification { when: ResourceBackedMetadataResolver resolver = new ResourceBackedMetadataResolver(name: 'rbmr').with { it.reloadableMetadataResolverAttributes = new ReloadableMetadataResolverAttributes(taskTimerRef: 'taskTimerRef') - it.classpathMetadataResource = new ClasspathMetadataResource(setFileResource: 'metadata.xml') + it.classpathMetadataResource = new ClasspathMetadataResource(fileResource: 'metadata.xml') it } @@ -282,7 +282,7 @@ class MetadataResolverEnversVersioningTests extends Specification { resolverHistory.size() == 1 getTargetEntityForRevisionIndex(resolverHistory, 0).name == 'rbmr' getTargetEntityForRevisionIndex(resolverHistory, 0).reloadableMetadataResolverAttributes.taskTimerRef == 'taskTimerRef' - getTargetEntityForRevisionIndex(resolverHistory, 0).classpathMetadataResource.file == 'metadata.xml' + getTargetEntityForRevisionIndex(resolverHistory, 0).classpathMetadataResource.fileResource == 'metadata.xml' getRevisionEntityForRevisionIndex(resolverHistory, 0).principalUserName == 'anonymousUser' getRevisionEntityForRevisionIndex(resolverHistory, 0).timestamp > 0L getModifiedEntityNames(resolverHistory, 0).sort() == expectedModifiedPersistentEntities.sort() @@ -302,7 +302,7 @@ class MetadataResolverEnversVersioningTests extends Specification { resolverHistory.size() == 2 getTargetEntityForRevisionIndex(resolverHistory, 1).name == 'rbmrUPDATED' getTargetEntityForRevisionIndex(resolverHistory, 1).reloadableMetadataResolverAttributes.taskTimerRef == 'taskTimerRefUPDATED' - getTargetEntityForRevisionIndex(resolverHistory, 1).classpathMetadataResource.file == 'metadataUPDATED.xml' + getTargetEntityForRevisionIndex(resolverHistory, 1).classpathMetadataResource.fileResource == 'metadataUPDATED.xml' getRevisionEntityForRevisionIndex(resolverHistory, 1).principalUserName == 'anonymousUser' getRevisionEntityForRevisionIndex(resolverHistory, 1).timestamp > 0L getModifiedEntityNames(resolverHistory, 1).sort() == expectedModifiedPersistentEntities.sort() @@ -310,7 +310,7 @@ class MetadataResolverEnversVersioningTests extends Specification { //Check the original revision is intact getTargetEntityForRevisionIndex(resolverHistory, 0).name == 'rbmr' getTargetEntityForRevisionIndex(resolverHistory, 0).reloadableMetadataResolverAttributes.taskTimerRef == 'taskTimerRef' - getTargetEntityForRevisionIndex(resolverHistory, 0).classpathMetadataResource.file == 'metadata.xml' + getTargetEntityForRevisionIndex(resolverHistory, 0).classpathMetadataResource.fileResource == 'metadata.xml' getRevisionEntityForRevisionIndex(resolverHistory, 0).principalUserName == 'anonymousUser' getRevisionEntityForRevisionIndex(resolverHistory, 0).timestamp > 0L } From f87e1bc1027e7edcb1fe0d2119046e4ba6b4b8a1 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 14 Jun 2022 10:16:02 -0700 Subject: [PATCH 02/88] SHIBUI-2273 merging shibui-2262 --- backend/build.gradle | 8 ++++---- gradle.properties | 6 ++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/backend/build.gradle b/backend/build.gradle index 90cc83503..e2c4936e0 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -171,10 +171,10 @@ dependencies { runtimeOnly 'org.glassfish.jaxb:jaxb-runtime:2.3.0' compile "com.h2database:h2" - runtimeOnly 'org.postgresql:postgresql:42.3.4' - runtimeOnly 'org.mariadb.jdbc:mariadb-java-client:3.0.4' - runtimeOnly 'mysql:mysql-connector-java:8.0.29' - runtimeOnly 'com.microsoft.sqlserver:mssql-jdbc:9.4.1.jre11' + runtimeOnly "org.postgresql:postgresql:${project.'postgresVersion'}" + runtimeOnly "org.mariadb.jdbc:mariadb-java-client:${project.'mariadbVersion'}" + runtimeOnly "mysql:mysql-connector-java:${project.'mysqlVersion'}" + runtimeOnly "com.microsoft.sqlserver:mssql-jdbc:${project.'sqlserverVersion'}" //Swagger compile 'io.springfox:springfox-swagger2:2.9.2' diff --git a/gradle.properties b/gradle.properties index f645de2d4..9fb07eccf 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,6 +19,12 @@ springbootVersion=2.5.12 springSecurityVersion=5.6.3 # springSecurityVersion=5.7.1 +### DB Driver Versions ### +mariadbVersion=3.0.4 +mysqlVersion=8.0.29 +postgresVersion=42.3.4 +sqlserverVersion=9.4.1.jre11 + org.gradle.jvmargs=-Xmx1g -XX:-UseGCOverheadLimit # set token in personal global From 47bc15390879cae076c1ac2dc1cce2e36f89d1ee Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 14 Jun 2022 15:41:48 -0700 Subject: [PATCH 03/88] SHIBUI-2273 Setup liquidbase to run for SQL SERVER --- .../CustomEntityAttributeDefinition.java | 4 +-- .../admin/ui/domain/LocalizedName.java | 4 ++- .../admin/ui/domain/OrganizationURL.java | 2 +- .../src/main/resources/application.properties | 3 +- .../main/resources/db/changelog/changelog.sql | 29 +++++++++++++++++++ 5 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 backend/src/main/resources/db/changelog/changelog.sql diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/CustomEntityAttributeDefinition.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/CustomEntityAttributeDefinition.java index f1d14911a..6e7ced3e2 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/CustomEntityAttributeDefinition.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/CustomEntityAttributeDefinition.java @@ -35,7 +35,7 @@ public class CustomEntityAttributeDefinition implements IRelyingPartyOverridePro @ElementCollection @CollectionTable(name = "custom_entity_attr_list_items", joinColumns = @JoinColumn(name = "name")) @Fetch(FetchMode.JOIN) - @Column(name = "value", nullable = false) + @Column(name = "item_value", nullable = false) Set customAttrListDefinitions = new HashSet<>(); @Column(name = "default_value", nullable = true) @@ -114,4 +114,4 @@ public void setName(String name) { public void updateExamplesList() { examples = customAttrListDefinitions; } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/LocalizedName.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/LocalizedName.java index e0a54d494..3f7dcb48e 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/LocalizedName.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/LocalizedName.java @@ -3,6 +3,7 @@ import org.hibernate.envers.Audited; import javax.annotation.Nullable; +import javax.persistence.Column; import javax.persistence.MappedSuperclass; @MappedSuperclass @@ -11,6 +12,7 @@ public class LocalizedName extends AbstractXMLObject implements org.opensaml.sam private String xMLLang; + @Column(name = "name_value") private String value; @Nullable @@ -34,4 +36,4 @@ public String getValue() { public void setValue(@Nullable String value) { this.value = value; } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/OrganizationURL.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/OrganizationURL.java index c8e556695..625e96379 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/OrganizationURL.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/OrganizationURL.java @@ -14,7 +14,7 @@ public class OrganizationURL extends AbstractXMLObject implements org.opensaml.s private String xMLLang; - @Column(name="value") + @Column(name="uri_value") private String uri; @Nullable diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index 0556e5b45..a0d50725f 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -37,7 +37,8 @@ spring.jackson.mapper.accept-case-insensitive-enums=true #spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect # Liquibase properties -spring.liquibase.enabled=false +spring.liquibase.enabled=true +spring.liquibase.change-log=db/changelog/changelog.sql # Hibernate properties # for production never ever use create, create-drop. It's BEST to use validate diff --git a/backend/src/main/resources/db/changelog/changelog.sql b/backend/src/main/resources/db/changelog/changelog.sql new file mode 100644 index 000000000..cfdf5bc02 --- /dev/null +++ b/backend/src/main/resources/db/changelog/changelog.sql @@ -0,0 +1,29 @@ +-- liquibase formatted sql + +-- changeset liquibase:1.11.0 dbms:mariadb,mysql,postgresql +-- preconditions onFail:MARK_RAN +-- precondition-sql-check expectedResult:1 SELECT 1 FROM users +-- comment: /* we don't need to run this if the system is new */ +ALTER TABLE resource_backed_metadata_resolver + RENAME file TO file_resource; +GO +ALTER TABLE organizationurl + RENAME 'value' TO 'uri_value'; +GO + +-- changeset liquibase:1.11.0 dbms:mssql +-- preconditions onFail:MARK_RAN +-- precondition-sql-check expectedResult:1 SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'users' +-- comment: /* we don't need to run this if the system is new */ +EXEC sp_rename 'organizationurl.value', uri_value, 'COLUMN' +GO +EXEC sp_rename 'custom_entity_attr_list_items.value', item_value, 'COLUMN' +GO +EXEC sp_rename 'organization_name.value', name_value, 'COLUMN' +GO +EXEC sp_rename 'organization_display_name.value', name_value, 'COLUMN' +GO +EXEC sp_rename 'service_description.value', name_value, 'COLUMN' +GO +EXEC sp_rename 'service_name.value', name_value, 'COLUMN' +GO \ No newline at end of file From 7809cfed0aec68dadd3ecc728d740404f9a903ab Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 14 Jun 2022 16:45:04 -0700 Subject: [PATCH 04/88] SHIBUI-2273 Setup liquidbase to run for POSTGRES --- .../main/resources/db/changelog/changelog.sql | 18 +++++++++++++++--- testbed/postgres/docker-compose.yml | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/backend/src/main/resources/db/changelog/changelog.sql b/backend/src/main/resources/db/changelog/changelog.sql index cfdf5bc02..3b3c84fb3 100644 --- a/backend/src/main/resources/db/changelog/changelog.sql +++ b/backend/src/main/resources/db/changelog/changelog.sql @@ -2,13 +2,25 @@ -- changeset liquibase:1.11.0 dbms:mariadb,mysql,postgresql -- preconditions onFail:MARK_RAN --- precondition-sql-check expectedResult:1 SELECT 1 FROM users +-- precondition-sql-check expectedResult:1 SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'users' -- comment: /* we don't need to run this if the system is new */ ALTER TABLE resource_backed_metadata_resolver - RENAME file TO file_resource; + RENAME "file" TO "file_resource"; GO ALTER TABLE organizationurl - RENAME 'value' TO 'uri_value'; + RENAME "value" TO "uri_value"; +GO +ALTER TABLE organization_name + RENAME "value" TO "name_value"; +GO +ALTER TABLE organization_display_name + RENAME "value" TO "name_value"; +GO +ALTER TABLE service_description + RENAME "value" TO "name_value"; +GO +ALTER TABLE service_name + RENAME "value" TO "name_value"; GO -- changeset liquibase:1.11.0 dbms:mssql diff --git a/testbed/postgres/docker-compose.yml b/testbed/postgres/docker-compose.yml index 593ceb1fc..c66b591a8 100644 --- a/testbed/postgres/docker-compose.yml +++ b/testbed/postgres/docker-compose.yml @@ -11,7 +11,7 @@ services: networks: - front ports: - - 3306:3306 + - 5432:5432 shibui: image: unicon/shibui ports: From 2e8233dbc59b13eba67ce0b9c6cd29317fe83f80 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 14 Jun 2022 17:11:32 -0700 Subject: [PATCH 05/88] SHIBUI-2273 Readme for liquibase --- .../src/main/resources/db/changelog/README.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 backend/src/main/resources/db/changelog/README.txt diff --git a/backend/src/main/resources/db/changelog/README.txt b/backend/src/main/resources/db/changelog/README.txt new file mode 100644 index 000000000..2ebb5d59f --- /dev/null +++ b/backend/src/main/resources/db/changelog/README.txt @@ -0,0 +1,18 @@ +Understanding the liquidbase changelog.sql file + +" -- liquibase formatted sql" - this is required at the top of this file " + +" -- changeset liquibase:1.11.0 dbms:mariadb,mysql,postgresql " +This indicates a change set and the version - please use the release version that the change matches so that looking at the DB should +give a good indication of what has been run. + +The dbms section indicates which DBs the changeset that follows is valid to be run on. If this is not present, Liquidbase will try +to run the changeset always. + +" -- preconditions onFail:MARK_RAN " +" -- precondition-sql-check expectedResult:1 SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'users' " + +@see - https://docs.liquibase.com/concepts/changelogs/preconditions.html +The check here is looking to see if the schema has been built out yet. If it has not, then the db is new and will be created +correctly without needing to be updated, so MARK_RAN ensures that the given changeset will not be run, but will be added to the +liquibase changesetlog table indicating that it was checked. \ No newline at end of file From ef900fc628311365b7d5cae9e31b5cb45a1fab6f Mon Sep 17 00:00:00 2001 From: chasegawa Date: Wed, 15 Jun 2022 10:05:10 -0700 Subject: [PATCH 06/88] SHIBUI-2273 Updates: added missing tables and aud tables to the sql updates, updated the springboot and hibernate versions to newer versions, updated the settings to work with the newer version of springboot which uses a different library for path pattern matching. --- .../filters/EntityAttributesFilterTarget.java | 2 +- .../filters/NameIdFormatFilterTarget.java | 2 + .../src/main/resources/application.properties | 4 ++ .../main/resources/db/changelog/changelog.sql | 67 +++++++++++++++++-- gradle.properties | 8 +-- 5 files changed, 73 insertions(+), 10 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilterTarget.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilterTarget.java index a7959dbbf..e2ed028a0 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilterTarget.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilterTarget.java @@ -26,7 +26,7 @@ public class EntityAttributesFilterTarget extends AbstractAuditable implements I @ElementCollection (fetch = FetchType.EAGER) @OrderColumn - @Column(length = 760) + @Column(length = 760, name="target_value") private List value; public EntityAttributesFilterTargetType getEntityAttributesFilterTargetType() { diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/NameIdFormatFilterTarget.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/NameIdFormatFilterTarget.java index 90445ff75..3a5bfe9da 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/NameIdFormatFilterTarget.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/NameIdFormatFilterTarget.java @@ -8,6 +8,7 @@ import org.hibernate.envers.AuditOverride; import org.hibernate.envers.Audited; +import javax.persistence.Column; import javax.persistence.ElementCollection; import javax.persistence.Entity; import javax.persistence.OrderColumn; @@ -27,6 +28,7 @@ public class NameIdFormatFilterTarget extends AbstractAuditable implements IFilt @ElementCollection @OrderColumn + @Column(name="target_value") private List value; public NameIdFormatFilterTargetType getNameIdFormatFilterTargetType() { diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index b126439d5..dd02864b0 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -9,6 +9,9 @@ logging.level.org.springframework=INFO logging.level.edu.internet2.tier.shibboleth.admin.ui=INFO spring.main.allow-bean-definition-overriding=true +# "In Spring MVC, the path was previously analyzed by AntPathMatcher, but it was changed to use PathPatternParser introduced in WebFlux from Spring 5.3.0." +# we still have the option to use ant path matcher thus keeping existing configuration from having to change +spring.mvc.pathmatch.matching-strategy=ant_path_matcher # Database Credentials spring.datasource.username=shibui @@ -109,6 +112,7 @@ shibui.roles.authenticated=ADMIN,ENABLE,USER #docker container shibui.beacon-enabled=true +### Swagger/Springdoc patterns springdoc.use-management-port=true springdoc.swagger-ui.tagsSorter: alpha springdoc.writer-with-order-by-keys: true diff --git a/backend/src/main/resources/db/changelog/changelog.sql b/backend/src/main/resources/db/changelog/changelog.sql index 3b3c84fb3..911f36cb9 100644 --- a/backend/src/main/resources/db/changelog/changelog.sql +++ b/backend/src/main/resources/db/changelog/changelog.sql @@ -4,38 +4,95 @@ -- preconditions onFail:MARK_RAN -- precondition-sql-check expectedResult:1 SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'users' -- comment: /* we don't need to run this if the system is new */ -ALTER TABLE resource_backed_metadata_resolver - RENAME "file" TO "file_resource"; +ALTER TABLE custom_entity_attr_list_items + RENAME "value" TO "item_value"; +GO +ALTER TABLE custom_entity_attr_list_items_aud + RENAME "value" TO "item_value"; +GO +ALTER TABLE entity_attributes_filter_target_value + RENAME "value" TO "target_value"; +GO +ALTER TABLE entity_attributes_filter_target_value_aud + RENAME "value" TO "target_value"; +GO +ALTER TABLE name_id_format_filter_target_value + RENAME "value" TO "target_value"; +GO +ALTER TABLE name_id_format_filter_target_value_aud + RENAME "value" TO "target_value"; GO ALTER TABLE organizationurl RENAME "value" TO "uri_value"; GO +ALTER TABLE organizationurl_aud + RENAME "value" TO "uri_value"; +GO +ALTER TABLE organization_display_name + RENAME "value" TO "name_value"; +GO +ALTER TABLE organization_display_name_aud + RENAME "value" TO "name_value"; +GO ALTER TABLE organization_name RENAME "value" TO "name_value"; GO -ALTER TABLE organization_display_name +ALTER TABLE organization_name_aud RENAME "value" TO "name_value"; GO +ALTER TABLE resource_backed_metadata_resolver + RENAME "file" TO "file_resource"; +GO +ALTER TABLE resource_backed_metadata_resolver_aud + RENAME "file" TO "file_resource"; +GO ALTER TABLE service_description RENAME "value" TO "name_value"; GO +ALTER TABLE service_description_aud + RENAME "value" TO "name_value"; +GO ALTER TABLE service_name RENAME "value" TO "name_value"; GO +ALTER TABLE service_name_aud + RENAME "value" TO "name_value"; +GO + -- changeset liquibase:1.11.0 dbms:mssql -- preconditions onFail:MARK_RAN -- precondition-sql-check expectedResult:1 SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'users' -- comment: /* we don't need to run this if the system is new */ +EXEC sp_rename 'custom_entity_attr_list_items.value', item_value, 'COLUMN' +GO +EXEC sp_rename 'custom_entity_attr_list_items_aud.value', item_value, 'COLUMN' +GO +EXEC sp_rename 'entity_attributes_filter_target_value.value', target_value, 'COLUMN' +GO +EXEC sp_rename 'entity_attributes_filter_target_value_aud.value', target_value, 'COLUMN' +GO +EXEC sp_rename 'name_id_format_filter_target_value', target_value, 'COLUMN' +GO +EXEC sp_rename 'name_id_format_filter_target_value_aud', target_value, 'COLUMN' +GO EXEC sp_rename 'organizationurl.value', uri_value, 'COLUMN' GO -EXEC sp_rename 'custom_entity_attr_list_items.value', item_value, 'COLUMN' +EXEC sp_rename 'organizationurl_aud.value', uri_value, 'COLUMN' +GO +EXEC sp_rename 'organization_display_name.value', name_value, 'COLUMN' +GO +EXEC sp_rename 'organization_display_name_aud.value', name_value, 'COLUMN' GO EXEC sp_rename 'organization_name.value', name_value, 'COLUMN' GO -EXEC sp_rename 'organization_display_name.value', name_value, 'COLUMN' +EXEC sp_rename 'organization_name_aud.value', name_value, 'COLUMN' GO EXEC sp_rename 'service_description.value', name_value, 'COLUMN' GO +EXEC sp_rename 'service_description_aud.value', name_value, 'COLUMN' +GO EXEC sp_rename 'service_name.value', name_value, 'COLUMN' +GO +EXEC sp_rename 'service_name_aud.value', name_value, 'COLUMN' GO \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 9fb07eccf..fdbf3f56a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,8 +5,8 @@ version=1.11.0-SNAPSHOT ### library versions ### commonsCollections4Version=4.4 cryptacularVersion=1.2.4 -hibernateVersion=5.5.0.Final -#hibernateVersion=5.6.9.Final +#hibernateVersion=5.5.0.Final +hibernateVersion=5.6.9.Final luceneVersion=8.1.1 log4JVersion=2.17.2 lombokVersion=5.3.3.3 @@ -14,8 +14,8 @@ opensamlVersion=4.2.0 pac4JVersion=5.4.3 pac4jSpringSecurityVersion=7.0.3 shibbolethVersion=4.2.1 -springbootVersion=2.5.12 -#springbootVersion=2.7.0 +#springbootVersion=2.5.12 +springbootVersion=2.7.0 springSecurityVersion=5.6.3 # springSecurityVersion=5.7.1 From 3b5a6efe25fa0028f99063800dc5c47931ee832d Mon Sep 17 00:00:00 2001 From: chasegawa Date: Wed, 15 Jun 2022 10:55:04 -0700 Subject: [PATCH 07/88] SHIBUI-2273 update version of spring security properties file cleanup --- backend/src/main/resources/application.properties | 2 +- gradle.properties | 13 ++----------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index dd02864b0..ba1b8f20f 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -19,7 +19,7 @@ spring.datasource.password=shibui # Database Configuration H2 spring.datasource.url=jdbc:h2:mem:shibui;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE -spring.datasource.platform=h2 +spring.sql.init.platform=h2 spring.datasource.driverClassName=org.h2.Driver spring.jpa.database-platform=org.hibernate.dialect.H2Dialect spring.h2.console.enabled=true diff --git a/gradle.properties b/gradle.properties index fdbf3f56a..f891afd02 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,6 @@ version=1.11.0-SNAPSHOT ### library versions ### commonsCollections4Version=4.4 cryptacularVersion=1.2.4 -#hibernateVersion=5.5.0.Final hibernateVersion=5.6.9.Final luceneVersion=8.1.1 log4JVersion=2.17.2 @@ -14,10 +13,8 @@ opensamlVersion=4.2.0 pac4JVersion=5.4.3 pac4jSpringSecurityVersion=7.0.3 shibbolethVersion=4.2.1 -#springbootVersion=2.5.12 springbootVersion=2.7.0 -springSecurityVersion=5.6.3 -# springSecurityVersion=5.7.1 +springSecurityVersion=5.7.1 ### DB Driver Versions ### mariadbVersion=3.0.4 @@ -35,10 +32,4 @@ i2.github.apiEndpoint=https://github.internet2.edu/api/v3 ## NOTES # pac4j spring security 7.0.3 here uses the pac4j 5.4.3 core, thus differences in versions (they used use the same versions, now -# keeping them in sync takes paying attention -# -# Springboot 2.7.0 and Hibernate 5.6.9 are current, but don't like all the columns named "value" in the db (along with H2), so don't -# update to these versions until ready to migrate the database columns. (the tests fail under these versions because the test database -# doesn't work). -# -# Additionally, springbootsecurity for tests doesn't like 5.7.1 \ No newline at end of file +# keeping them in sync takes paying attention \ No newline at end of file From 9827498670843cac2d0b3d86626afaca028bb49e Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 21 Jun 2022 11:03:53 -0700 Subject: [PATCH 08/88] SHIBUI-2268 initial commit, no working state --- .../JPAMetadataResolverServiceImpl.groovy | 11 + .../filters/algorithm/AlgorithmFilter.java | 59 +++ .../ui/domain/filters/algorithm/Entity.java | 24 ++ .../admin/ui/opensaml/OpenSamlObjects.java | 26 +- ...XMLObjectProviderInitializerForTest.groovy | 12 + ...JPAMetadataResolverServiceImplTests.groovy | 26 +- .../admin/ui/util/TestObjectGenerator.groovy | 9 + .../org.opensaml.core.config.Initializer | 1 + .../src/test/resources/conf/2268-simple.xml | 7 + .../resources/jpa-saml2-metadata-config.xml | 372 ++++++++++++++++++ 10 files changed, 533 insertions(+), 14 deletions(-) create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AlgorithmFilter.java create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/Entity.java create mode 100644 backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializerForTest.groovy create mode 100644 backend/src/test/resources/META-INF/services/org.opensaml.core.config.Initializer create mode 100644 backend/src/test/resources/conf/2268-simple.xml create mode 100644 backend/src/test/resources/jpa-saml2-metadata-config.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 ed3f794c0..691828526 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 @@ -9,6 +9,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityRoleWhiteList import edu.internet2.tier.shibboleth.admin.ui.domain.filters.NameIdFormatFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.SignatureValidationFilter +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.AlgorithmFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.opensaml.OpenSamlNameIdFormatFilter import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetadataResolver import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FileBackedHttpMetadataResolver @@ -88,6 +89,16 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { } } + void constructXmlNodeForFilter(AlgorithmFilter filter, def markupBuilderDelegate) { + if (!filter.isFilterEnabled()) { return } + markupBuilderDelegate.MetadataFilter('xsi:type': 'Algorithm') { + // TODO: enhance. currently this does weird things with namespaces + filter.unknownXMLObjects.each { xmlObject -> + mkp.yieldUnescaped(openSamlObjects.marshalToXmlString(xmlObject, false)) + } + } + } + void constructXmlNodeForFilter(EntityAttributesFilter filter, def markupBuilderDelegate) { if (!filter.isFilterEnabled()) { return } markupBuilderDelegate.MetadataFilter('xsi:type': 'EntityAttributes') { diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AlgorithmFilter.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AlgorithmFilter.java new file mode 100644 index 000000000..85a4d9129 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AlgorithmFilter.java @@ -0,0 +1,59 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm; + +import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractXMLObject; +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter; +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.SignatureValidationFilter; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.hibernate.envers.Audited; +import org.opensaml.core.xml.ElementExtensibleXMLObject; +import org.opensaml.core.xml.XMLObject; + +import javax.annotation.Nonnull; +import javax.persistence.CascadeType; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.OneToMany; +import javax.persistence.OrderColumn; +import javax.xml.namespace.QName; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Following the pattern of AbstractElementExtensibleXMLObject - this XML type can hold a couple of different types of XML objects + */ +@Entity +@Audited +@Getter +@Setter +@ToString +@EqualsAndHashCode(callSuper = true) +public class AlgorithmFilter extends MetadataFilter { + @OneToMany(cascade = CascadeType.ALL) + @OrderColumn + private List unknownXMLObjects = new ArrayList<>(); + + public void addUnknownXMLObject(AbstractXMLObject xmlObject) { + this.unknownXMLObjects.add(xmlObject); + } + + @Nonnull + public List getUnknownXMLObjects() { + return (List) (List) this.unknownXMLObjects; + } + + private AlgorithmFilter updateConcreteFilterTypeData(AlgorithmFilter filterToBeUpdated) { + for (XMLObject o : getUnknownXMLObjects()) { + filterToBeUpdated.addUnknownXMLObject((AbstractXMLObject) o); + } + return filterToBeUpdated; + } + + @Override + public MetadataFilter updateConcreteFilterTypeData(MetadataFilter filterToBeUpdated) { + return updateConcreteFilterTypeData((AlgorithmFilter) filterToBeUpdated); + } +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/Entity.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/Entity.java new file mode 100644 index 000000000..9a741f6e8 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/Entity.java @@ -0,0 +1,24 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm; + +import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractXMLObject; + +import javax.annotation.Nullable; + +public class Entity extends AbstractXMLObject implements org.opensaml.core.xml.schema.XSString { + private String uri; + + private Entity(){ + setElementLocalName("Entity"); + } + + @Nullable + @Override + public String getValue() { + return this.uri; + } + + @Override + public void setValue(@Nullable String newValue) { + this.uri = newValue; + } +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/OpenSamlObjects.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/OpenSamlObjects.java index 8a25b0855..bd149c9ff 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/OpenSamlObjects.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/OpenSamlObjects.java @@ -88,11 +88,11 @@ public void init() throws ComponentInitializationException { this.unmarshallerFactory = registry.getUnmarshallerFactory(); } - public String marshalToXmlString(XMLObject ed, boolean includeXMLDeclaration) throws MarshallingException { - Marshaller marshaller = this.marshallerFactory.getMarshaller(ed); - ed.releaseDOM(); - ed.releaseChildrenDOM(true); - String entityDescriptorXmlString = null; + public String marshalToXmlString(XMLObject xmlObject, boolean includeXMLDeclaration) throws MarshallingException { + Marshaller marshaller = this.marshallerFactory.getMarshaller(xmlObject); + xmlObject.releaseDOM(); + xmlObject.releaseChildrenDOM(true); + String resultString = null; if (marshaller != null) { try (StringWriter writer = new StringWriter()) { Transformer transformer = TransformerFactory.newInstance().newTransformer(); @@ -101,22 +101,22 @@ public String marshalToXmlString(XMLObject ed, boolean includeXMLDeclaration) th if (!includeXMLDeclaration) { transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); } - transformer.transform(new DOMSource(marshaller.marshall(ed)), new StreamResult(writer)); - entityDescriptorXmlString = writer.toString(); + transformer.transform(new DOMSource(marshaller.marshall(xmlObject)), new StreamResult(writer)); + resultString = writer.toString(); } catch (TransformerException | IOException e) { logger.error(e.getMessage(), e); } } - if (entityDescriptorXmlString == null) { + if (resultString == null) { //Figure out the best way to deal with this case - throw new RuntimeException("Unable to marshal EntityDescriptor"); + throw new RuntimeException("Unable to marshal xmlObject"); } - return entityDescriptorXmlString; + return resultString; } - public String marshalToXmlString(XMLObject ed) throws MarshallingException { - return this.marshalToXmlString(ed, true); + public String marshalToXmlString(XMLObject xmlObject) throws MarshallingException { + return this.marshalToXmlString(xmlObject, true); } public EntityDescriptor unmarshalFromXml(byte[] entityDescriptorXml) throws Exception { @@ -152,4 +152,4 @@ public T buildDefaultInstanceOfType(Class type) { throw new RuntimeException("there was a problem building an instance", e); } } -} +} \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializerForTest.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializerForTest.groovy new file mode 100644 index 000000000..0a56abe54 --- /dev/null +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializerForTest.groovy @@ -0,0 +1,12 @@ +package edu.internet2.tier.shibboleth.admin.ui.opensaml.config + +import org.opensaml.core.xml.config.AbstractXMLObjectProviderInitializer + +class JPAXMLObjectProviderInitializerForTest extends AbstractXMLObjectProviderInitializer { + @Override + protected String[] getConfigResources() { + return new String[]{ + "/jpa-saml2-metadata-config.xml", + } + } +} \ No newline at end of file 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 594ee6750..010ee9310 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 @@ -3,10 +3,12 @@ package edu.internet2.tier.shibboleth.admin.ui.service import edu.internet2.tier.shibboleth.admin.ui.AbstractBaseDataJpaTest import edu.internet2.tier.shibboleth.admin.ui.configuration.PlaceholderResolverComponentsConfiguration import edu.internet2.tier.shibboleth.admin.ui.configuration.ShibUIConfiguration +import edu.internet2.tier.shibboleth.admin.ui.domain.EncryptionMethod import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilFilter +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.Entity import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ClasspathMetadataResource import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetadataResolver import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.LocalDynamicMetadataResolver @@ -16,6 +18,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.SvnMetadataResour import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.TemplateScheme import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlChainingMetadataResolver import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects +import edu.internet2.tier.shibboleth.admin.ui.opensaml.config.JPAXMLObjectProviderInitializerForTest import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator import groovy.xml.DOMBuilder @@ -40,7 +43,7 @@ import java.time.Instant import static edu.internet2.tier.shibboleth.admin.ui.util.TestHelpers.generatedXmlIsTheSameAsExpectedXml -@ContextConfiguration(classes=[ JPAMRSIConfig, PlaceholderResolverComponentsConfiguration ]) +@ContextConfiguration(classes=[ JPAMRSIConfig, PlaceholderResolverComponentsConfiguration, JPAXMLObjectProviderInitializerForTest ]) class JPAMetadataResolverServiceImplTests extends AbstractBaseDataJpaTest { @Autowired @@ -137,6 +140,27 @@ class JPAMetadataResolverServiceImplTests extends AbstractBaseDataJpaTest { !diff.hasDifferences() } + def 'test generating AlgorithmFilter xml snippet'() { + given: + def filter = TestObjectGenerator.algorithmFilter() + EncryptionMethod encryptionMethod = new EncryptionMethod() + encryptionMethod.setAlgorithm("http://www.w3.org/2001/04/xmlenc#aes128-cbc") + encryptionMethod.setElementLocalName("EncryptionMethod") + filter.addUnknownXMLObject(encryptionMethod) + Entity entity = new Entity() + entity.setValue("https://broken.example.org/sp") + filter.addUnknownXMLObject(entity) + Entity entity2 = new Entity() + entity2.setValue("https://also-broken.example.org/sp") + filter.addUnknownXMLObject(entity2) + + when: + genXmlSnippet(markupBuilder) { JPAMetadataResolverServiceImpl.cast(metadataResolverService).constructXmlNodeForFilter(filter, it) } + + then: + generatedXmlIsTheSameAsExpectedXml('/conf/2268-simple.xml', domBuilder.parseText(writer.toString())) + } + def 'test generating EntityAttributesFilter xml snippet with condition script'() { given: def filter = testObjectGenerator.entityAttributesFilterWithConditionScript() 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 bf17b107e..276bbc17f 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 @@ -17,6 +17,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.filters.NameIdFormatFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.NameIdFormatFilterTarget import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.SignatureValidationFilter +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.AlgorithmFilter import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.FilterRepresentation import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.FilterTargetRepresentation import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ClasspathMetadataResource @@ -183,6 +184,14 @@ class TestObjectGenerator { randomFilter } + static AlgorithmFilter algorithmFilter() { + return new AlgorithmFilter().with { + it.name = "Algorithm" + it.enabled = true; + it + } + } + SignatureValidationFilter signatureValidationFilter() { new SignatureValidationFilter().with { it.name = 'SignatureValidation' diff --git a/backend/src/test/resources/META-INF/services/org.opensaml.core.config.Initializer b/backend/src/test/resources/META-INF/services/org.opensaml.core.config.Initializer new file mode 100644 index 000000000..c7c2e7cb3 --- /dev/null +++ b/backend/src/test/resources/META-INF/services/org.opensaml.core.config.Initializer @@ -0,0 +1 @@ +edu.internet2.tier.shibboleth.admin.ui.opensaml.config.JPAXMLObjectProviderInitializerForTest \ No newline at end of file diff --git a/backend/src/test/resources/conf/2268-simple.xml b/backend/src/test/resources/conf/2268-simple.xml new file mode 100644 index 000000000..2ffe731f1 --- /dev/null +++ b/backend/src/test/resources/conf/2268-simple.xml @@ -0,0 +1,7 @@ + + + + https://broken.example.org/sp + https://also-broken.example.org/sp + + \ No newline at end of file diff --git a/backend/src/test/resources/jpa-saml2-metadata-config.xml b/backend/src/test/resources/jpa-saml2-metadata-config.xml new file mode 100644 index 000000000..b008809ce --- /dev/null +++ b/backend/src/test/resources/jpa-saml2-metadata-config.xml @@ -0,0 +1,372 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From fcd4ea1b59f701ccdbd86a3615c7760660eac41b Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Wed, 22 Jun 2022 10:54:47 -0700 Subject: [PATCH 09/88] Initial commit for Algorithm filter in UI --- .../schema/filter/algorithm.schema.json | 53 +++++++++++++++++ .../component/fields/FilterTargetField.js | 3 +- .../definition/AlgorithmFilterDefinition.js | 59 +++++++++++++++++++ ui/src/app/metadata/domain/filter/index.js | 7 ++- 4 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 ui/public/assets/schema/filter/algorithm.schema.json create mode 100644 ui/src/app/metadata/domain/filter/definition/AlgorithmFilterDefinition.js diff --git a/ui/public/assets/schema/filter/algorithm.schema.json b/ui/public/assets/schema/filter/algorithm.schema.json new file mode 100644 index 000000000..0c0c74444 --- /dev/null +++ b/ui/public/assets/schema/filter/algorithm.schema.json @@ -0,0 +1,53 @@ +{ + "type": "object", + "required": ["name"], + "properties": { + "name": { + "title": "label.filter-name", + "description": "tooltip.filter-name", + "type": "string" + }, + "filterEnabled": { + "title": "label.enable-filter", + "description": "tooltip.enable-filter", + "type": "boolean", + "default": false + }, + "algorithmFilterTarget": { + "title": "label.search-criteria", + "description": "tooltip.search-criteria", + "type": "object", + "properties": { + "algorithmFilterTargetType": { + "title": "label.filter-target-type", + "type": "string", + "default": "ENTITY", + "enum": ["ENTITY", "REGEX", "CONDITION_SCRIPT"], + "enumNames": [ + "value.entity-id", + "value.regex", + "value.script" + ] + }, + "value": { + "title": "label.filter-target-value", + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "type": "string" + } + } + }, + "required": ["value", "algorithmFilterTargetType"] + }, + "@type": { + "type": "string", + "default": "NameIDFormat" + }, + "version": { + "type": "integer" + } + }, + "definitions": {} +} diff --git a/ui/src/app/form/component/fields/FilterTargetField.js b/ui/src/app/form/component/fields/FilterTargetField.js index 2ce8f3ccc..125b26b0d 100644 --- a/ui/src/app/form/component/fields/FilterTargetField.js +++ b/ui/src/app/form/component/fields/FilterTargetField.js @@ -251,7 +251,8 @@ const FilterTargetField = ({ diff --git a/ui/src/app/metadata/domain/filter/definition/AlgorithmFilterDefinition.js b/ui/src/app/metadata/domain/filter/definition/AlgorithmFilterDefinition.js new file mode 100644 index 000000000..e0c15bf80 --- /dev/null +++ b/ui/src/app/metadata/domain/filter/definition/AlgorithmFilterDefinition.js @@ -0,0 +1,59 @@ +import defaultsDeep from "lodash/defaultsDeep"; +// import API_BASE_PATH from "../../../../App.constant"; +import { BASE_PATH } from '../../../../App.constant'; +import { BaseFilterDefinition } from "./BaseFilterDefinition"; + +export const AlgorithmFilterWizard = { + ...BaseFilterDefinition, + uiSchema: defaultsDeep({ + algorithmFilterTarget: { + 'ui:field': 'FilterTargetField', + api: '' + }, + formats: { + "ui:options": { + orderable: false + }, + items: { + 'ui:widget': 'OptionWidget' + } + } + }, BaseFilterDefinition.uiSchema), + label: 'Algorithm', + type: 'Algorithm', + // schema: `${API_BASE_PATH}/ui/AlgorithmFilter`, + schema: `${BASE_PATH}assets/schema/filter/algorithm.schema.json`, + steps: [], + validator: (data = [], current = { resourceId: null }, group) => { + return BaseFilterDefinition.validator(data, current, group, 'algorithmFilterTarget', 'algorithmFilterTargetType') + }, + formatter: (changes) => ({ + ...changes, + '@type': AlgorithmFilterWizard.type + }) +}; + +export const AlgorithmFilterEditor = { + ...AlgorithmFilterWizard, + steps: [ + { + id: 'common', + label: 'label.target', + index: 1, + fields: [ + 'name', + '@type', + 'resourceId', + 'algorithmFilterTarget', + 'filterEnabled' + ] + }, + { + id: 'options', + label: 'label.options', + index: 2, + initialValues: [], + fields: [] + } + ] +}; \ No newline at end of file diff --git a/ui/src/app/metadata/domain/filter/index.js b/ui/src/app/metadata/domain/filter/index.js index 9f5326ba9..fe4af7fd1 100644 --- a/ui/src/app/metadata/domain/filter/index.js +++ b/ui/src/app/metadata/domain/filter/index.js @@ -1,14 +1,17 @@ import { EntityAttributesFilterEditor } from './definition/EntityAttributesFilterDefinition'; import { NameIDFilterEditor } from './definition/NameIdFilterDefinition'; +import { AlgorithmFilterEditor } from './definition/AlgorithmFilterDefinition'; export const MetadataFilterWizardTypes = { EntityAttributes: EntityAttributesFilterEditor, - NameIDFormat: NameIDFilterEditor + NameIDFormat: NameIDFilterEditor, + Algorithm: AlgorithmFilterEditor, }; export const MetadataFilterEditorTypes = [ EntityAttributesFilterEditor, - NameIDFilterEditor + NameIDFilterEditor, + AlgorithmFilterEditor, ]; export const MetadataFilterTypes = [ From 478e20900b9b0f6aeacb531afed522136b845c6a Mon Sep 17 00:00:00 2001 From: chasegawa Date: Thu, 23 Jun 2022 09:22:57 -0700 Subject: [PATCH 10/88] SHIBUI-2273 Corrections for MySQL --- .../main/resources/db/changelog/changelog.sql | 62 ++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/backend/src/main/resources/db/changelog/changelog.sql b/backend/src/main/resources/db/changelog/changelog.sql index 911f36cb9..561280f58 100644 --- a/backend/src/main/resources/db/changelog/changelog.sql +++ b/backend/src/main/resources/db/changelog/changelog.sql @@ -1,6 +1,66 @@ -- liquibase formatted sql --- changeset liquibase:1.11.0 dbms:mariadb,mysql,postgresql +-- changeset liquibase:1.11.0 dbms:mysql +-- preconditions onFail:MARK_RAN +-- precondition-sql-check expectedResult:1 SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'users' +-- comment: /* we don't need to run this if the system is new */ +ALTER TABLE custom_entity_attr_list_items + CHANGE value item_value varchar(255); +GO +ALTER TABLE custom_entity_attr_list_items_aud + CHANGE value item_value varchar(255); +GO +ALTER TABLE entity_attributes_filter_target_value + CHANGE value target_value varchar(255); +GO +ALTER TABLE entity_attributes_filter_target_value_aud + CHANGE value target_value varchar(255); +GO +ALTER TABLE name_id_format_filter_target_value + CHANGE value target_value varchar(255); +GO +ALTER TABLE name_id_format_filter_target_value_aud + CHANGE value target_value varchar(255); +GO +ALTER TABLE organizationurl + CHANGE value uri_value varchar(255); +GO +ALTER TABLE organizationurl_aud + CHANGE value uri_value varchar(255); +GO +ALTER TABLE organization_display_name + CHANGE value name_value varchar(255); +GO +ALTER TABLE organization_display_name_aud + CHANGE value name_value varchar(255); +GO +ALTER TABLE organization_name + CHANGE value name_value varchar(255); +GO +ALTER TABLE organization_name_aud + CHANGE value name_value varchar(255); +GO +ALTER TABLE resource_backed_metadata_resolver + CHANGE file file_resource varchar(255); +GO +ALTER TABLE resource_backed_metadata_resolver_aud + CHANGE file file_resource varchar(255); +GO +ALTER TABLE service_description + CHANGE value name_value varchar(255); +GO +ALTER TABLE service_description_aud + CHANGE value name_value varchar(255); +GO +ALTER TABLE service_name + CHANGE value name_value varchar(255); +GO +ALTER TABLE service_name_aud + CHANGE value name_value varchar(255); +GO + + +-- changeset liquibase:1.11.0 dbms:mariadb,postgresql -- preconditions onFail:MARK_RAN -- precondition-sql-check expectedResult:1 SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'users' -- comment: /* we don't need to run this if the system is new */ From 7d808b46fd31626a8d852f21245806331ad18c10 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 23 Jun 2022 09:57:02 -0700 Subject: [PATCH 11/88] Updated min/max refresh for providers --- .../file-system-metadata-provider.schema.json | 16 +++++++-------- .../main/resources/i18n/messages.properties | 2 +- .../resources/i18n/messages_en.properties | 2 +- .../schema/provider/file-system.schema.json | 20 +++++++++---------- .../provider/filebacked-http.schema.json | 10 ++++++++-- ui/src/app/metadata/domain/data.js | 14 +++++++++++++ ...ileBackedHttpMetadataProviderDefinition.js | 6 +++--- .../FileSystemMetadataProviderDefinition.js | 6 +++--- .../metadata/wizard/MetadataProviderWizard.js | 2 +- 9 files changed, 47 insertions(+), 31 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 7969495f2..a4db5a52d 100644 --- a/backend/src/main/resources/file-system-metadata-provider.schema.json +++ b/backend/src/main/resources/file-system-metadata-provider.schema.json @@ -1,11 +1,6 @@ { "type": "object", - "required": [ - "name", - "@type", - "xmlId", - "metadataFile" - ], + "required": ["name", "@type", "xmlId", "metadataFile"], "properties": { "name": { "title": "label.metadata-provider-name-dashboard-display-only", @@ -47,18 +42,21 @@ }, "reloadableMetadataResolverAttributes": { "type": "object", + "required": ["minRefreshDelay", "maxRefreshDelay"], "properties": { "minRefreshDelay": { "title": "label.min-refresh-delay", "description": "tooltip.min-refresh-delay", "type": "string", - "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)?)?$" + "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)?)?$", + "default": "PT5M" }, "maxRefreshDelay": { "title": "label.max-refresh-delay", "description": "tooltip.max-refresh-delay", "type": "string", - "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)?)?$" + "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)?)?$", + "default": "PT4H" }, "refreshDelayFactor": { "title": "label.refresh-delay-factor", @@ -71,4 +69,4 @@ } } } -} \ No newline at end of file +} diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index 0a7880b36..2513a7c87 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -684,7 +684,7 @@ tooltip.retained-roles=Note that property replacement cannot be used on this ele tooltip.remove-roleless-entity-descriptors=Controls whether to keep entity descriptors that contain no roles. Note: If this attribute is set to false, the resulting output may not be schema-valid since an element must include at least one role descriptor. tooltip.remove-empty-entities-descriptors=Controls whether to keep entities descriptors that contain no entity descriptors. Note: If this attribute is set to false, the resulting output may not be schema-valid since an element must include at least one child element, either an element or an element. -tooltip.min-refresh-delay=Lower bound on the next refresh from the time calculated based on the metadata\u0027s expiration. +tooltip.min-refresh-delay=Lower bound on the next refresh from the time calculated based on the metadata\u0027s expiration. Setting this to 0 will result in the default value being used. tooltip.max-refresh-delay=Upper bound on the next refresh from the time calculated based on the metadata\u0027s expiration. tooltip.refresh-delay-factor=A factor applied to the initially determined refresh time in order to determine the next refresh time (typically to ensure refresh takes place prior to the metadata\u0027s expiration). Attempts to refresh metadata will generally begin around the product of this number and the maximum refresh delay. tooltip.resolve-via-predicates-only=Flag indicating whether resolution may be performed solely by applying predicates to the entire metadata collection, when an entityID input criterion is not supplied. diff --git a/backend/src/main/resources/i18n/messages_en.properties b/backend/src/main/resources/i18n/messages_en.properties index f9f64d4d2..40d17ae7e 100644 --- a/backend/src/main/resources/i18n/messages_en.properties +++ b/backend/src/main/resources/i18n/messages_en.properties @@ -531,7 +531,7 @@ tooltip.retained-roles=Note that property replacement cannot be used on this ele tooltip.remove-roleless-entity-descriptors=Controls whether to keep entity descriptors that contain no roles. Note: If this attribute is set to false, the resulting output may not be schema-valid since an element must include at least one role descriptor. tooltip.remove-empty-entities-descriptors=Controls whether to keep entities descriptors that contain no entity descriptors. Note: If this attribute is set to false, the resulting output may not be schema-valid since an element must include at least one child element, either an element or an element. -tooltip.min-refresh-delay=Lower bound on the next refresh from the time calculated based on the metadata\u0027s expiration. +tooltip.min-refresh-delay=Lower bound on the next refresh from the time calculated based on the metadata\u0027s expiration. Setting this to 0 will result in the default value being used. tooltip.max-refresh-delay=Upper bound on the next refresh from the time calculated based on the metadata\u0027s expiration. tooltip.refresh-delay-factor=A factor applied to the initially determined refresh time in order to determine the next refresh time (typically to ensure refresh takes place prior to the metadata\u0027s expiration). Attempts to refresh metadata will generally begin around the product of this number and the maximum refresh delay. tooltip.resolve-via-predicates-only=Flag indicating whether resolution may be performed solely by applying predicates to the entire metadata collection, when an entityID input criterion is not supplied. diff --git a/ui/public/assets/schema/provider/file-system.schema.json b/ui/public/assets/schema/provider/file-system.schema.json index 38d0d90e3..a4db5a52d 100644 --- a/ui/public/assets/schema/provider/file-system.schema.json +++ b/ui/public/assets/schema/provider/file-system.schema.json @@ -1,15 +1,10 @@ { "type": "object", - "required": [ - "name", - "@type", - "xmlId", - "metadataFile" - ], + "required": ["name", "@type", "xmlId", "metadataFile"], "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", @@ -20,7 +15,7 @@ "title": "label.metadata-provider-type", "description": "tooltip.metadata-provider-type", "type": "string", - "const": "FilesystemMetadataResolver" + "default": "FilesystemMetadataResolver" }, "xmlId": { "title": "label.xml-id", @@ -47,18 +42,21 @@ }, "reloadableMetadataResolverAttributes": { "type": "object", + "required": ["minRefreshDelay", "maxRefreshDelay"], "properties": { "minRefreshDelay": { "title": "label.min-refresh-delay", "description": "tooltip.min-refresh-delay", "type": "string", - "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)?)?$" + "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)?)?$", + "default": "PT5M" }, "maxRefreshDelay": { "title": "label.max-refresh-delay", "description": "tooltip.max-refresh-delay", "type": "string", - "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)?)?$" + "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)?)?$", + "default": "PT4H" }, "refreshDelayFactor": { "title": "label.refresh-delay-factor", @@ -71,4 +69,4 @@ } } } -} \ No newline at end of file +} diff --git a/ui/public/assets/schema/provider/filebacked-http.schema.json b/ui/public/assets/schema/provider/filebacked-http.schema.json index 860733486..77f415b43 100644 --- a/ui/public/assets/schema/provider/filebacked-http.schema.json +++ b/ui/public/assets/schema/provider/filebacked-http.schema.json @@ -252,18 +252,24 @@ "reloadableMetadataResolverAttributes": { "$id": "reloadableMetadataResolverAttributes", "type": "object", + "required": [ + "minRefreshDelay", + "maxRefreshDelay" + ], "properties": { "minRefreshDelay": { "title": "label.min-refresh-delay", "description": "tooltip.min-refresh-delay", "type": "string", - "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)?)?$" + "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)?)?$", + "default": "PT5M" }, "maxRefreshDelay": { "title": "label.max-refresh-delay", "description": "tooltip.max-refresh-delay", "type": "string", - "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)?)?$" + "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)?)?$", + "default": "PT4H" }, "refreshDelayFactor": { "title": "label.refresh-delay-factor", diff --git a/ui/src/app/metadata/domain/data.js b/ui/src/app/metadata/domain/data.js index 45412d300..b97afbddb 100644 --- a/ui/src/app/metadata/domain/data.js +++ b/ui/src/app/metadata/domain/data.js @@ -9,4 +9,18 @@ export const DurationOptions = [ "PT8H", "PT12H", "PT24H" +]; + +export const RefreshOptions = [ + "PT1S", + "PT30S", + "PT1M", + "PT5M", + "PT10M", + "PT30M", + "PT1H", + "PT4H", + "PT8H", + "PT12H", + "PT24H", ]; \ No newline at end of file diff --git a/ui/src/app/metadata/domain/provider/definition/FileBackedHttpMetadataProviderDefinition.js b/ui/src/app/metadata/domain/provider/definition/FileBackedHttpMetadataProviderDefinition.js index 106edfa55..e4e4be5b6 100644 --- a/ui/src/app/metadata/domain/provider/definition/FileBackedHttpMetadataProviderDefinition.js +++ b/ui/src/app/metadata/domain/provider/definition/FileBackedHttpMetadataProviderDefinition.js @@ -1,7 +1,7 @@ import defaultsDeep from 'lodash/defaultsDeep'; import { BaseProviderDefinition, HttpMetadataResolverAttributesSchema, MetadataFilterPluginsSchema } from './BaseProviderDefinition'; -import { DurationOptions } from '../../data'; +import { DurationOptions, RefreshOptions } from '../../data'; import { BASE_PATH } from '../../../../App.constant'; export const FileBackedHttpMetadataProviderWizard = { @@ -155,12 +155,12 @@ export const FileBackedHttpMetadataProviderWizard = { reloadableMetadataResolverAttributes: { minRefreshDelay: { 'ui:widget': 'OptionWidget', - options: DurationOptions, + options: RefreshOptions, 'ui:placeholder': 'label.duration' }, maxRefreshDelay: { 'ui:widget': 'OptionWidget', - options: DurationOptions, + options: RefreshOptions, 'ui:placeholder': 'label.duration' }, refreshDelayFactor: { diff --git a/ui/src/app/metadata/domain/provider/definition/FileSystemMetadataProviderDefinition.js b/ui/src/app/metadata/domain/provider/definition/FileSystemMetadataProviderDefinition.js index d97b8e041..5e9d617fe 100644 --- a/ui/src/app/metadata/domain/provider/definition/FileSystemMetadataProviderDefinition.js +++ b/ui/src/app/metadata/domain/provider/definition/FileSystemMetadataProviderDefinition.js @@ -1,7 +1,7 @@ import defaultsDeep from 'lodash/defaultsDeep'; import API_BASE_PATH from "../../../../App.constant"; import { BaseProviderDefinition } from "./BaseProviderDefinition"; -import { DurationOptions } from '../../data'; +import { RefreshOptions } from '../../data'; export const FileSystemMetadataProviderWizard = { ...BaseProviderDefinition, @@ -74,12 +74,12 @@ export const FileSystemMetadataProviderWizard = { reloadableMetadataResolverAttributes: { minRefreshDelay: { 'ui:widget': 'OptionWidget', - options: DurationOptions, + options: RefreshOptions, 'ui:placeholder': 'label.duration' }, maxRefreshDelay: { 'ui:widget': 'OptionWidget', - options: DurationOptions, + options: RefreshOptions, 'ui:placeholder': 'label.duration' }, refreshDelayFactor: { diff --git a/ui/src/app/metadata/wizard/MetadataProviderWizard.js b/ui/src/app/metadata/wizard/MetadataProviderWizard.js index d2cbc0864..8dcbf73cd 100644 --- a/ui/src/app/metadata/wizard/MetadataProviderWizard.js +++ b/ui/src/app/metadata/wizard/MetadataProviderWizard.js @@ -49,7 +49,6 @@ export function MetadataProviderWizard({onSave, loading, block}) { return ( <> -
} +
{JSON.stringify(errors, null, 4)}
); } From 383002d3fc4f48f360a2742a5bb2dbe325ce742e Mon Sep 17 00:00:00 2001 From: chasegawa Date: Thu, 23 Jun 2022 12:07:34 -0700 Subject: [PATCH 12/88] SHIBUI-2273 "Resetting" the min and max refresh values to match the open saml code --- .../main/resources/db/changelog/changelog.sql | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/backend/src/main/resources/db/changelog/changelog.sql b/backend/src/main/resources/db/changelog/changelog.sql index 561280f58..2653cdd64 100644 --- a/backend/src/main/resources/db/changelog/changelog.sql +++ b/backend/src/main/resources/db/changelog/changelog.sql @@ -1,6 +1,6 @@ -- liquibase formatted sql --- changeset liquibase:1.11.0 dbms:mysql +-- changeset liquibase:1.11.0.1 dbms:mysql -- preconditions onFail:MARK_RAN -- precondition-sql-check expectedResult:1 SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'users' -- comment: /* we don't need to run this if the system is new */ @@ -60,7 +60,7 @@ ALTER TABLE service_name_aud GO --- changeset liquibase:1.11.0 dbms:mariadb,postgresql +-- changeset liquibase:1.11.0.1 dbms:mariadb,postgresql -- preconditions onFail:MARK_RAN -- precondition-sql-check expectedResult:1 SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'users' -- comment: /* we don't need to run this if the system is new */ @@ -120,7 +120,7 @@ ALTER TABLE service_name_aud GO --- changeset liquibase:1.11.0 dbms:mssql +-- changeset liquibase:1.11.0.1 dbms:mssql -- preconditions onFail:MARK_RAN -- precondition-sql-check expectedResult:1 SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'users' -- comment: /* we don't need to run this if the system is new */ @@ -155,4 +155,24 @@ GO EXEC sp_rename 'service_name.value', name_value, 'COLUMN' GO EXEC sp_rename 'service_name_aud.value', name_value, 'COLUMN' -GO \ No newline at end of file +GO + +-- changeset liquibase:1.11.0.2 dbms:mariadb,postgresql,mssql,mysql +-- preconditions onFail:MARK_RAN +-- precondition-sql-check expectedResult:1 SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'users' +-- comment: /* we don't need to run this if the system is new */ + +update filesystem_metadata_resolver set min_refresh_delay ='PT5M'; +update filesystem_metadata_resolver_aud set min_refresh_delay ='PT5M'; +update filesystem_metadata_resolver set max_refresh_delay ='PT4H'; +update filesystem_metadata_resolver_aud set max_refresh_delay ='PT4H'; + +update file_backed_http_metadata_resolver set min_refresh_delay ='PT5M'; +update file_backed_http_metadata_resolver_aud set min_refresh_delay ='PT5M'; +update file_backed_http_metadata_resolver set max_refresh_delay ='PT4H'; +update file_backed_http_metadata_resolver_aud set max_refresh_delay ='PT4H'; + +update resource_backed_metadata_resolver set min_refresh_delay ='PT5M'; +update resource_backed_metadata_resolver_aud set min_refresh_delay ='PT5M'; +update resource_backed_metadata_resolver set max_refresh_delay ='PT4H'; +update resource_backed_metadata_resolver_aud set max_refresh_delay ='PT4H'; \ No newline at end of file From 987208a97691beabb478f696226ba085bbdeab29 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Thu, 23 Jun 2022 15:23:31 -0700 Subject: [PATCH 13/88] SHIBUI-2273 Overriding calls that were getting made that break things. Those methods don't need to be used by the shibui functionality --- .../OpenSamlFileBackedHTTPMetadataResolver.java | 13 +++++++++++++ .../OpenSamlFilesystemMetadataResolver.java | 12 ++++++++++++ 2 files changed, 25 insertions(+) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlFileBackedHTTPMetadataResolver.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlFileBackedHTTPMetadataResolver.java index c5d64dc5b..4b642e52a 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlFileBackedHTTPMetadataResolver.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlFileBackedHTTPMetadataResolver.java @@ -15,6 +15,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.io.File; import java.time.Duration; import java.time.Instant; @@ -135,4 +136,16 @@ public synchronized void refresh() throws ResolverException { } } } + + @Override + public void validateBackupFile(final File backupFile) throws ResolverException { + // NOPE, not going to validate this because the file reference is likely not to exist on the shibui server nor even be a + // valid path on the running server. The file is needed for the XML, but we shouldn't be validating it. + } + + @Override + protected byte[] fetchMetadata() throws ResolverException { + // NOPE, we don't need to try and fetch the metadata from either the URI nor the file + return null; + } } \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlFilesystemMetadataResolver.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlFilesystemMetadataResolver.java index c247e7b53..f8b9a856f 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlFilesystemMetadataResolver.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlFilesystemMetadataResolver.java @@ -88,4 +88,16 @@ public void refilter() { logger.error("An error occurred while attempting to filter metadata!", e); } } + + @Override + public void validateMetadataFile(@Nonnull final File file) throws ResolverException { + // NOPE, not going to validate this because the file reference is likely not to exist on the shibui server nor even be a + // valid path on the running server. The file is needed for the XML, but we shouldn't be validating it. + } + + @Override + protected byte[] fetchMetadata() throws ResolverException { + // NOPE, we don't need to try and fetch the metadata + return null; + } } \ No newline at end of file From b2b3ad9ae902259ec4d31e30758846f505834ebc Mon Sep 17 00:00:00 2001 From: chasegawa Date: Wed, 29 Jun 2022 14:24:04 -0700 Subject: [PATCH 14/88] SHIBUI-2273 slight change for mariadb --- backend/src/main/resources/db/changelog/changelog.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/main/resources/db/changelog/changelog.sql b/backend/src/main/resources/db/changelog/changelog.sql index 2653cdd64..5bece9633 100644 --- a/backend/src/main/resources/db/changelog/changelog.sql +++ b/backend/src/main/resources/db/changelog/changelog.sql @@ -1,6 +1,6 @@ -- liquibase formatted sql --- changeset liquibase:1.11.0.1 dbms:mysql +-- changeset liquibase:1.11.0.1 dbms:mysql,mariadb -- preconditions onFail:MARK_RAN -- precondition-sql-check expectedResult:1 SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'users' -- comment: /* we don't need to run this if the system is new */ @@ -60,7 +60,7 @@ ALTER TABLE service_name_aud GO --- changeset liquibase:1.11.0.1 dbms:mariadb,postgresql +-- changeset liquibase:1.11.0.1 dbms:postgresql -- preconditions onFail:MARK_RAN -- precondition-sql-check expectedResult:1 SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'users' -- comment: /* we don't need to run this if the system is new */ From 71cbdc52c7888141e84e8b137b2ae44aea47030a Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 1 Jul 2022 10:50:47 -0700 Subject: [PATCH 15/88] NOJIRA Fixing the footer version information --- backend/src/main/resources/application.properties | 8 +++++--- ui/src/app/App.constant.js | 10 ++++++++++ ui/src/app/core/components/VersionInfo.js | 14 +++++++++----- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index ba1b8f20f..f6af0610e 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -48,7 +48,7 @@ spring.liquibase.change-log=db/changelog/changelog.sql spring.jpa.hibernate.ddl-auto=update spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl spring.jpa.show-sql=false -spring.jpa.properties.hibernate.format_sql=false +spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.check_nullability=true spring.jpa.hibernate.use-new-id-generator-mappings=true @@ -118,5 +118,7 @@ springdoc.swagger-ui.tagsSorter: alpha springdoc.writer-with-order-by-keys: true springdoc.pathsToMatch=/entities, /api/** # This property enables the openapi and swagger-ui endpoints to be exposed beneath the actuator base path. -management.endpoints.web.exposure.include=openapi, swagger-ui -management.server.port=9090 \ No newline at end of file +management.endpoints.web.exposure.include=openapi, swagger-ui, info +management.server.port=9090 +management.endpoints.web.cors.allowed-origins=* +management.endpoints.web.cors.allowed-headers=* \ No newline at end of file diff --git a/ui/src/app/App.constant.js b/ui/src/app/App.constant.js index 3b6af7f89..afa7a688c 100644 --- a/ui/src/app/App.constant.js +++ b/ui/src/app/App.constant.js @@ -5,8 +5,18 @@ export const getBasePath = () => { //replace(/^\/|\/$/g, '') }; +export const getActuatorPath = () => { + const url = new URL(document.getElementsByTagName('base')[0].href); + + var foo = document.createElement("a"); + foo.href = url.pathname?.replace(/^\/+/g, ''); + foo.port = "9090" + return foo.href; +} + export const BASE_PATH = getBasePath(); export const API_BASE_PATH = `${BASE_PATH}api`; +export const ACTUATOR_PATH = getActuatorPath(); export const FILTER_PLUGIN_TYPES = ['RequiredValidUntil', 'SignatureValidation', 'EntityRoleWhiteList']; diff --git a/ui/src/app/core/components/VersionInfo.js b/ui/src/app/core/components/VersionInfo.js index 1c6badfc1..1c88ad271 100644 --- a/ui/src/app/core/components/VersionInfo.js +++ b/ui/src/app/core/components/VersionInfo.js @@ -1,7 +1,7 @@ import React from 'react'; import useFetch from 'use-http'; -import { BASE_PATH } from '../../App.constant'; +import { ACTUATOR_PATH } from '../../App.constant'; import Translate from '../../i18n/components/translate'; @@ -11,11 +11,15 @@ const year = new Date().getFullYear(); const params = { year }; export function VersionInfo () { - - const { data = {} } = useFetch(`${BASE_PATH}actuator/info`, {}, []); + var opts = { + headers: { + 'mode':'no-cors' + } + } + const { data = {} } = useFetch(`${ACTUATOR_PATH}actuator/info`, opts, []); const [ versionData, setVersionData ] = React.useState(''); - + React.useEffect(() => { setVersionData(formatter(data)); }, [data]); @@ -29,4 +33,4 @@ export function VersionInfo () { ); } -export default VersionInfo; \ No newline at end of file +export default VersionInfo; From 7ee47095d75c433e1642f416927823f0da3314ba Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 5 Jul 2022 15:05:36 -0700 Subject: [PATCH 16/88] NOJIRA --- testbed/postgres/conf/application.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/testbed/postgres/conf/application.yml b/testbed/postgres/conf/application.yml index 2173107e1..56fd5e709 100644 --- a/testbed/postgres/conf/application.yml +++ b/testbed/postgres/conf/application.yml @@ -8,9 +8,11 @@ spring: username: shibui password: shibui jpa: + show-sql: false properties: hibernate: - dialect: org.hibernate.dialect.PostgreSQLDialect + dialect: org.hibernate.dialect.PostgreSQL95Dialect + format_sql: true server: port: 8443 ssl: @@ -135,4 +137,4 @@ custom: logging: level: org.pac4j: "TRACE" - org.opensaml: "INFO" + org.opensaml: "INFO" \ No newline at end of file From 48b93d31dd1c469a1bd2d3e4cb0ce2ee2d01fd9b Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 5 Jul 2022 16:45:21 -0700 Subject: [PATCH 17/88] SHIBUI-2273 Updating dialects --- backend/src/main/resources/application.yml | 9 +++++++++ testbed/mariadb/conf/application.yml | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index 671000aa6..ffeab970c 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -1,3 +1,12 @@ +#spring: +# jpa: +# show-sql: false +# properties: +# hibernate: +# format_sql: true +# dialect: org.hibernate.dialect.PostgreSQL95Dialect +# OR SEE: https://access.redhat.com/webassets/avalon/d/red-hat-jboss-enterprise-application-platform/7.2/javadocs/org/hibernate/dialect/package-summary.html + #shibui: ## Default password must be set for the default user to be configured and setup # default-rootuser:root diff --git a/testbed/mariadb/conf/application.yml b/testbed/mariadb/conf/application.yml index 68018a4b9..82fe6fec7 100644 --- a/testbed/mariadb/conf/application.yml +++ b/testbed/mariadb/conf/application.yml @@ -10,7 +10,7 @@ spring: jpa: properties: hibernate: - dialect: org.hibernate.dialect.MariaDBDialect + dialect: org.hibernate.dialect.MariaDB103Dialect server: port: 8443 ssl: @@ -135,4 +135,4 @@ custom: logging: level: org.pac4j: "TRACE" - org.opensaml: "INFO" + org.opensaml: "INFO" \ No newline at end of file From 3c4526ca2bc0d6b5bd92d93c8ef585854525b353 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Wed, 6 Jul 2022 13:13:28 -0700 Subject: [PATCH 18/88] Fixed access to non-admin pages --- ui/src/app/App.js | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/ui/src/app/App.js b/ui/src/app/App.js index 20331e4e8..546241f10 100644 --- a/ui/src/app/App.js +++ b/ui/src/app/App.js @@ -33,6 +33,7 @@ import { SessionModal } from './core/user/SessionModal'; import { Roles } from './admin/Roles'; import { Groups } from './admin/Groups'; import { BASE_PATH } from './App.constant'; +import { ProtectRoute } from './core/components/ProtectRoute'; function App() { @@ -81,12 +82,32 @@ function App() { - - - + + + + + } /> + + + + + } /> + + + + + } /> - - + + + + + } /> + + + + + } /> From 4cf79c36cb66029d4d88ada3264f868ef657d7fc Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 7 Jul 2022 08:29:04 -0700 Subject: [PATCH 19/88] Fixed cosmetic issues --- .../main/resources/i18n/messages.properties | 1 + ui/public/unsecured/error.html | 21 +++++++++++++----- ui/public/unsecured/favicon-96x96.png | Bin 0 -> 12383 bytes ui/public/unsecured/favicon.ico | Bin 0 -> 1150 bytes .../shibboleth_icon_color_130x130.png | Bin 0 -> 11665 bytes ui/src/app/metadata/new/NewProvider.js | 4 ++-- .../wizard/MetadataFilterTypeSelector.js | 8 +++---- .../wizard/MetadataProviderTypeSelector.js | 12 ++++++---- 8 files changed, 31 insertions(+), 15 deletions(-) create mode 100644 ui/public/unsecured/favicon-96x96.png create mode 100644 ui/public/unsecured/favicon.ico create mode 100644 ui/public/unsecured/shibboleth_icon_color_130x130.png diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index e25a7e5b9..88aea4835 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -409,6 +409,7 @@ label.remove-roleless-entity-descriptors=Remove Roleless Entity Descriptors? label.remove-empty-entities-descriptors=Remove Empty Entities Descriptors? label.select-metadata-provider-type=Select Metadata Provider Type +label.select-metadata-filter-type=Select Metadata Filter Type label.filter-list=Filter List label.common-attributes=Common Attributes label.reloading-attributes=Reloading Attributes diff --git a/ui/public/unsecured/error.html b/ui/public/unsecured/error.html index 4d200efa8..910a81b61 100644 --- a/ui/public/unsecured/error.html +++ b/ui/public/unsecured/error.html @@ -4,20 +4,31 @@ Shibboleth Metadata Management - - + +
-
- +
+
+ + + +
User request received

Your request has been received and is being reviewed. You will be notified with access status.

diff --git a/ui/public/unsecured/favicon-96x96.png b/ui/public/unsecured/favicon-96x96.png new file mode 100644 index 0000000000000000000000000000000000000000..e19516fff44f2ee7d0a432dc542424d98bf30aac GIT binary patch literal 12383 zcmZ{~1yEc~&^EfbyGw9)*97pQ8xYMu%gX@X|N9j6R;EJlptvaLxj}1%|0!}{2QdJEeL+!1Qrr92MZTB6 z(NcO`=x2U|%2 znb^E5-mww=a?`aP$Uk}dYJBp?ZRYn?A}f*7@6Vx@!+tG+{iXG8k9u4B4h_AYol?x@ zPimdO5~EARmv@eLlx?2LBMJ#V(u3pq($@BNlgo-1quWlTxrK!xJhhL5hts)DY-g^5 zN6s0upMtx(L?$K$@BXYioSd9=ZcIPt9=Ksp5ypPoAIEv=y&xAimUML7JaAgrVhe+% z!i~m`mqY5k+1%VbUu%g)KtmlL*FN9s51JcFN=vDzU=R@zAs(L!7=Te=X6EEPs;(?B z|M%wuA0Hofw9H$*pKPfHYzUx9_Z%QDb}5w6tM3v=O{+hsv6ono)A4z+d+qJ|v%} zNDHSf9mTpt){`|CHaFvEk1USoifw;YwlqDR0e73mC`#+=6S^8 zTwQtUzYFj*&o-OwQFL{)_x#p2RK+rOrooI1lc16iB8N`l@87?TY+>q5!Db_k>p!2u zSiML<@}Z|FiJkSEFPsi*as`U-B%KggTXuV@|3UI z0O&OIdVTrTKHjh

K)c3A>F?OpvMvV8kHdrLG60h|X6)*2y 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 CAw)L- literal 0 HcmV?d00001 diff --git a/ui/public/unsecured/shibboleth_icon_color_130x130.png b/ui/public/unsecured/shibboleth_icon_color_130x130.png new file mode 100644 index 0000000000000000000000000000000000000000..313df313ec23714f1b1724665d7b731864523f1b GIT binary patch literal 11665 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 be*p#nPjC|=r4$7j00000NkvXXu0mjfIC%Fk literal 0 HcmV?d00001 diff --git a/ui/src/app/metadata/new/NewProvider.js b/ui/src/app/metadata/new/NewProvider.js index 43a9ed715..13d0d1061 100644 --- a/ui/src/app/metadata/new/NewProvider.js +++ b/ui/src/app/metadata/new/NewProvider.js @@ -7,7 +7,7 @@ import { MetadataProviderTypeSelector } from '../wizard/MetadataProviderTypeSele export function NewProvider() { - const { data } = useMetadataProviderTypes({}, []); + const { data, loading } = useMetadataProviderTypes({}, []); return (

- + {(data, onRestart) => - - + + - + {types.map(t => )} diff --git a/ui/src/app/metadata/wizard/MetadataProviderTypeSelector.js b/ui/src/app/metadata/wizard/MetadataProviderTypeSelector.js index fbc890fb9..e53f06b13 100644 --- a/ui/src/app/metadata/wizard/MetadataProviderTypeSelector.js +++ b/ui/src/app/metadata/wizard/MetadataProviderTypeSelector.js @@ -1,5 +1,5 @@ import React from 'react'; -import { faArrowCircleRight, faSpinner } from '@fortawesome/free-solid-svg-icons'; +import { faArrowCircleRight, faAsterisk, faSpinner } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { useForm } from 'react-hook-form'; @@ -10,11 +10,11 @@ import { InfoIcon } from '../../form/component/InfoIcon'; import { useTranslator } from '../../i18n/hooks'; import { useMetadataProviders } from '../hooks/api'; -export function MetadataProviderTypeSelector({ type, types = [], children}) { +export function MetadataProviderTypeSelector({ type, types = [], loading, children}) { const translator = useTranslator(); - const { data = [], loading } = useMetadataProviders({cachePolicy: 'no-cache'}, []); + const { data = [] } = useMetadataProviders({cachePolicy: 'no-cache'}, []); const [showSelector, setShowSelector] = React.useState(true); @@ -81,7 +81,10 @@ export function MetadataProviderTypeSelector({ type, types = [], children}) {
- + + + + + {loading && } From 0cd83bcd3acac8031ccf952ba6abdd5e528c26ea Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 7 Jul 2022 10:39:32 -0700 Subject: [PATCH 20/88] Fixed caching of source xml --- ui/src/app/metadata/hoc/MetadataXmlLoader.js | 10 +++++++--- ui/src/app/metadata/view/MetadataXml.js | 7 ++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/ui/src/app/metadata/hoc/MetadataXmlLoader.js b/ui/src/app/metadata/hoc/MetadataXmlLoader.js index ffc1c8bcf..e5453a519 100644 --- a/ui/src/app/metadata/hoc/MetadataXmlLoader.js +++ b/ui/src/app/metadata/hoc/MetadataXmlLoader.js @@ -13,7 +13,7 @@ export function MetadataXmlLoader({ children }) { const [xml, setXml] = React.useState(); async function loadMetadataXml(id) { - const data = await get(`/${id}`) + const data = await get(`/${id}`); if (response.ok) { setXml(data); } @@ -22,12 +22,16 @@ export function MetadataXmlLoader({ children }) { /*eslint-disable react-hooks/exhaustive-deps*/ React.useEffect(() => { if (type === 'source') { - loadMetadataXml(id) + reload() } }, [id]); + function reload() { + loadMetadataXml(id); + } + return ( - + {children} ); diff --git a/ui/src/app/metadata/view/MetadataXml.js b/ui/src/app/metadata/view/MetadataXml.js index 5144b14af..17e79d26a 100644 --- a/ui/src/app/metadata/view/MetadataXml.js +++ b/ui/src/app/metadata/view/MetadataXml.js @@ -12,12 +12,17 @@ import { MetadataViewToggle } from '../component/MetadataViewToggle'; import { downloadAsXml } from '../../core/utility/download_as_xml'; export function MetadataXml () { - const xml = React.useContext(MetadataXmlContext); + const { xml, reload } = React.useContext(MetadataXmlContext); const entity = React.useContext(MetadataObjectContext); const { type } = useParams(); const download = () => downloadAsXml(entity.name ? entity.name : entity.serviceProviderName, xml); + /*eslint-disable react-hooks/exhaustive-deps*/ + React.useEffect(() => { + reload(); + }, []); + return ( <>

From 7684867a3cf49cf7fb473a504e02eed8f280b9a8 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 7 Jul 2022 12:27:36 -0700 Subject: [PATCH 21/88] Added success alert for custom entity attributes --- ui/public/assets/schema/attribute/attribute.schema.json | 2 +- ui/src/app/metadata/new/NewAttribute.js | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ui/public/assets/schema/attribute/attribute.schema.json b/ui/public/assets/schema/attribute/attribute.schema.json index 0514703f0..84590e08e 100644 --- a/ui/public/assets/schema/attribute/attribute.schema.json +++ b/ui/public/assets/schema/attribute/attribute.schema.json @@ -64,7 +64,7 @@ "title": "label.entity-attribute-help", "description": "tooltip.entity-attribute-help", "type": "string", - "minLength": 1, + "minLength": 0, "maxLength": 255 } }, diff --git a/ui/src/app/metadata/new/NewAttribute.js b/ui/src/app/metadata/new/NewAttribute.js index 3648942bb..0db6847cb 100644 --- a/ui/src/app/metadata/new/NewAttribute.js +++ b/ui/src/app/metadata/new/NewAttribute.js @@ -11,7 +11,7 @@ import { useMetadataAttribute } from '../hooks/api'; import {CustomAttributeDefinition} from '../domain/attribute/CustomAttributeDefinition'; import MetadataSchema from '../hoc/MetadataSchema'; import { MetadataForm } from '../hoc/MetadataFormContext'; -import { createNotificationAction, useNotificationDispatcher } from '../../notifications/hoc/Notifications'; +import { createNotificationAction, NotificationTypes, useNotificationDispatcher } from '../../notifications/hoc/Notifications'; export function NewAttribute() { const history = useHistory(); @@ -25,11 +25,16 @@ export function NewAttribute() { const [blocking, setBlocking] = React.useState(false); async function save(metadata) { + let toast; const resp = await post(``, definition.parser(metadata)); if (response.ok) { + toast = createNotificationAction(`Added attribute successfully.`, NotificationTypes.SUCCESS); gotoDetail({ refresh: true }); } else { - dispatch(createNotificationAction(`${resp.errorCode}: Unable to create attribute ... ${resp.errorMessage}`, 'danger', 5000)); + toast = createNotificationAction(`${resp.errorCode}: Unable to create attribute ... ${resp.errorMessage}`, 'danger', 5000); + } + if (toast) { + dispatch(toast); } }; From be660ed0c48a542fe61796f8f5e2704f5ea84fee Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 7 Jul 2022 12:34:44 -0700 Subject: [PATCH 22/88] Added success notifcation for editing/deleting attributes --- ui/src/app/metadata/hoc/MetadataAttributes.js | 4 ++++ ui/src/app/metadata/view/MetadataAttributeEdit.js | 9 +++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ui/src/app/metadata/hoc/MetadataAttributes.js b/ui/src/app/metadata/hoc/MetadataAttributes.js index c4c59d3c0..e4cf57a2d 100644 --- a/ui/src/app/metadata/hoc/MetadataAttributes.js +++ b/ui/src/app/metadata/hoc/MetadataAttributes.js @@ -1,8 +1,11 @@ import React from 'react'; +import { createNotificationAction, NotificationTypes, useNotificationDispatcher } from '../../notifications/hoc/Notifications'; import { useMetadataAttribute, useMetadataAttributes } from '../hooks/api'; export function MetadataAttributes ({children}) { + const dispatch = useNotificationDispatcher(); + const { get, response } = useMetadataAttributes({ cachePolicy: 'no-cache' }); @@ -24,6 +27,7 @@ export function MetadataAttributes ({children}) { await del(`/${id}`); if (attrApi.response.ok) { loadAttributes(); + dispatch(createNotificationAction(`Attribute deleted successfully`, NotificationTypes.SUCCESS, 5000)); } } diff --git a/ui/src/app/metadata/view/MetadataAttributeEdit.js b/ui/src/app/metadata/view/MetadataAttributeEdit.js index b45dfeaa5..84670d467 100644 --- a/ui/src/app/metadata/view/MetadataAttributeEdit.js +++ b/ui/src/app/metadata/view/MetadataAttributeEdit.js @@ -11,7 +11,7 @@ import { useMetadataAttribute } from '../hooks/api'; import { CustomAttributeDefinition, CustomAttributeEditor } from '../domain/attribute/CustomAttributeDefinition'; import MetadataSchema from '../hoc/MetadataSchema'; import { MetadataForm } from '../hoc/MetadataFormContext'; -import { createNotificationAction, useNotificationDispatcher } from '../../notifications/hoc/Notifications'; +import { createNotificationAction, NotificationTypes, useNotificationDispatcher } from '../../notifications/hoc/Notifications'; export function MetadataAttributeEdit() { const { id } = useParams(); @@ -35,11 +35,16 @@ export function MetadataAttributeEdit() { } async function save(metadata) { + let toast; const resp = await put(``, definition.parser(metadata)); if (response.ok) { + toast = createNotificationAction(`Updated attribute successfully.`, NotificationTypes.SUCCESS); gotoDetail({ refresh: true }); } else { - dispatch(createNotificationAction(`${resp.errorCode}: Unable to edit attribute ... ${resp.errorMessage}`, 'danger', 5000)); + toast = createNotificationAction(`${resp.errorCode}: Unable to edit attribute ... ${resp.errorMessage}`, 'danger', 5000); + } + if (toast) { + dispatch(toast); } }; From b50795880f3657b2ed72d6165cc0fc488e9f59c8 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Thu, 7 Jul 2022 12:40:23 -0700 Subject: [PATCH 23/88] SHIBUI-2273 Fixing postgres lob issue --- .../tier/shibboleth/admin/ui/domain/X509Certificate.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/X509Certificate.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/X509Certificate.java index b1db21b72..cff1a3c9d 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/X509Certificate.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/X509Certificate.java @@ -1,6 +1,7 @@ package edu.internet2.tier.shibboleth.admin.ui.domain; import lombok.EqualsAndHashCode; +import org.hibernate.annotations.Type; import org.hibernate.envers.Audited; import javax.annotation.Nullable; @@ -14,6 +15,7 @@ public class X509Certificate extends AbstractXMLObject implements org.opensaml.xmlsec.signature.X509Certificate { @Column(name = "x509CertificateValue") @Lob + @Type(type = "org.hibernate.type.TextType") private String value; @Nullable @@ -26,4 +28,4 @@ public String getValue() { public void setValue(@Nullable String value) { this.value = value; } -} +} \ No newline at end of file From c7cd06fa66dd829cf396d438f8ac12fcc0c0c7d4 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 12 Jul 2022 09:56:11 -0700 Subject: [PATCH 24/88] SHIBUI-2268 intermediate checkin - tests not correct --- .../JPAMetadataResolverServiceImpl.groovy | 24 +++++++++++++++---- .../admin/ui/domain/EncryptionMethod.java | 4 +++- ...XMLObjectProviderInitializerForTest.groovy | 2 +- ...JPAMetadataResolverServiceImplTests.groovy | 10 ++++++-- .../src/test/resources/conf/2268-simple.xml | 8 ++++++- 5 files changed, 39 insertions(+), 9 deletions(-) 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 691828526..ffe491eec 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 @@ -10,6 +10,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.filters.NameIdFormatFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.SignatureValidationFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.AlgorithmFilter +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.Entity import edu.internet2.tier.shibboleth.admin.ui.domain.filters.opensaml.OpenSamlNameIdFormatFilter import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetadataResolver import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FileBackedHttpMetadataResolver @@ -90,11 +91,26 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { } void constructXmlNodeForFilter(AlgorithmFilter filter, def markupBuilderDelegate) { - if (!filter.isFilterEnabled()) { return } - markupBuilderDelegate.MetadataFilter('xsi:type': 'Algorithm') { - // TODO: enhance. currently this does weird things with namespaces + if (!filter.isFilterEnabled()) { + return + } + markupBuilderDelegate.MetadataFilter( + 'xsi:type': 'Algorithm', + 'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', + 'xsi:schemaLocation': 'urn:mace:shibboleth:2.0:metadata http://shibboleth.net/schema/idp/shibboleth-metadata.xsd urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd urn:oasis:names:tc:SAML:2.0:assertion http://docs.oasis-open.org/security/saml/v2.0/saml-schema-assertion-2.0.xsd urn:oasis:names:tc:SAML:2.0:metadata http://docs.oasis-open.org/security/saml/v2.0/saml-schema-metadata-2.0.xsd', + 'xmlns:md': 'urn:oasis:names:tc:SAML:2.0:metadata', + 'xmlns': 'urn:mace:shibboleth:2.0:metadata', + 'xmlns:security': 'urn:mace:shibboleth:2.0:security', + 'xmlns:saml2': 'urn:oasis:names:tc:SAML:2.0:assertion' + ) { filter.unknownXMLObjects.each { xmlObject -> - mkp.yieldUnescaped(openSamlObjects.marshalToXmlString(xmlObject, false)) + { + if (xmlObject instanceof Entity) { + Entity(xmlObject.getValue()) + } else { + mkp.yieldUnescaped(openSamlObjects.marshalToXmlString(xmlObject, false)) + } + } } } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/EncryptionMethod.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/EncryptionMethod.java index 06a47da63..be8da1f0c 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/EncryptionMethod.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/EncryptionMethod.java @@ -55,4 +55,6 @@ public org.opensaml.xmlsec.encryption.OAEPparams getOAEPparams() { public void setOAEPparams(@Nullable org.opensaml.xmlsec.encryption.OAEPparams oaePparams) { this.oaePparams = oaePparams; } -} + + +} \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializerForTest.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializerForTest.groovy index 0a56abe54..b4df893ab 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializerForTest.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializerForTest.groovy @@ -6,7 +6,7 @@ class JPAXMLObjectProviderInitializerForTest extends AbstractXMLObjectProviderIn @Override protected String[] getConfigResources() { return new String[]{ - "/jpa-saml2-metadata-config.xml", + "/jpa-saml2-metadata-config.xml" } } } \ No newline at end of file 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 010ee9310..80acbdad3 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 @@ -4,6 +4,7 @@ import edu.internet2.tier.shibboleth.admin.ui.AbstractBaseDataJpaTest import edu.internet2.tier.shibboleth.admin.ui.configuration.PlaceholderResolverComponentsConfiguration import edu.internet2.tier.shibboleth.admin.ui.configuration.ShibUIConfiguration import edu.internet2.tier.shibboleth.admin.ui.domain.EncryptionMethod +import edu.internet2.tier.shibboleth.admin.ui.domain.EncryptionMethodBuilder import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter @@ -26,6 +27,7 @@ import groovy.xml.MarkupBuilder import net.shibboleth.ext.spring.resource.ResourceHelper import net.shibboleth.utilities.java.support.resolver.CriteriaSet import org.opensaml.core.criterion.EntityIdCriterion +import org.opensaml.saml.common.xml.SAMLConstants import org.opensaml.saml.metadata.resolver.MetadataResolver import org.opensaml.saml.metadata.resolver.filter.MetadataFilterChain import org.opensaml.saml.metadata.resolver.impl.ResourceBackedMetadataResolver @@ -143,10 +145,14 @@ class JPAMetadataResolverServiceImplTests extends AbstractBaseDataJpaTest { def 'test generating AlgorithmFilter xml snippet'() { given: def filter = TestObjectGenerator.algorithmFilter() - EncryptionMethod encryptionMethod = new EncryptionMethod() + EncryptionMethod encryptionMethod = new EncryptionMethod() + encryptionMethod.setElementLocalName(EncryptionMethod.DEFAULT_ELEMENT_LOCAL_NAME) + encryptionMethod.setNamespacePrefix(SAMLConstants.SAML20MD_PREFIX) + encryptionMethod.setNamespaceURI(SAMLConstants.SAML20MD_NS) + encryptionMethod.setSchemaLocation(SAMLConstants.SAML20MD_SCHEMA_LOCATION) encryptionMethod.setAlgorithm("http://www.w3.org/2001/04/xmlenc#aes128-cbc") - encryptionMethod.setElementLocalName("EncryptionMethod") filter.addUnknownXMLObject(encryptionMethod) + Entity entity = new Entity() entity.setValue("https://broken.example.org/sp") filter.addUnknownXMLObject(entity) diff --git a/backend/src/test/resources/conf/2268-simple.xml b/backend/src/test/resources/conf/2268-simple.xml index 2ffe731f1..f9b0ea14a 100644 --- a/backend/src/test/resources/conf/2268-simple.xml +++ b/backend/src/test/resources/conf/2268-simple.xml @@ -1,4 +1,10 @@ - + https://broken.example.org/sp From 362a51d7a9fb7a63826a351f0667cbf06bd36234 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 12 Jul 2022 11:28:05 -0700 Subject: [PATCH 25/88] SHIBUI-2273 fixes for sqlserver docker --- testbed/sqlServer/conf/application.yml | 16 ++++++++-------- testbed/sqlServer/docker-compose.yml | 9 ++++++++- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/testbed/sqlServer/conf/application.yml b/testbed/sqlServer/conf/application.yml index 1e48abf4d..f69ccb318 100644 --- a/testbed/sqlServer/conf/application.yml +++ b/testbed/sqlServer/conf/application.yml @@ -1,6 +1,6 @@ spring: profiles: - include: + include: dev datasource: platform: sqlserver driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver @@ -11,13 +11,13 @@ spring: properties: hibernate: dialect: org.hibernate.dialect.SQLServerDialect -#server: -# port: 8443 -# ssl: -# key-store: "/conf/keystore.p12" -# key-store-password: "changeit" -# keyStoreType: "PKCS12" -# keyAlias: "tomcat" +server: + port: 8443 + ssl: + key-store: "/conf/keystore.p12" + key-store-password: "changeit" + keyStoreType: "PKCS12" + keyAlias: "tomcat" shibui: user-bootstrap-resource: file:/conf/users.csv roles: ROLE_ADMIN,ROLE_NONE,ROLE_USER,ROLE_PONY diff --git a/testbed/sqlServer/docker-compose.yml b/testbed/sqlServer/docker-compose.yml index a7509fe37..68276f256 100644 --- a/testbed/sqlServer/docker-compose.yml +++ b/testbed/sqlServer/docker-compose.yml @@ -23,7 +23,14 @@ services: - db networks: - front - + mailhog: + image: mailhog/mailhog:latest + ports: + - 1025:1025 + - 8025:8025 + container_name: mailhog + networks: + - front networks: front: driver: bridge \ No newline at end of file From b6ba7ef2a91adcc506429187503489fb90eaec2d Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Wed, 13 Jul 2022 15:19:10 -0700 Subject: [PATCH 26/88] SHIBUI-944 Base copy off of JSON Schema --- ui/src/app/metadata/copy/CopySource.js | 17 +++------- .../source/definition/SourceDefinition.js | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/ui/src/app/metadata/copy/CopySource.js b/ui/src/app/metadata/copy/CopySource.js index 83a8591e8..f3ae6b142 100644 --- a/ui/src/app/metadata/copy/CopySource.js +++ b/ui/src/app/metadata/copy/CopySource.js @@ -9,18 +9,9 @@ import { Translate } from '../../i18n/components/translate'; import { EntityTypeahead } from './EntityTypeahead'; import kebabCase from 'lodash/kebabCase'; import { useMetadataSources } from '../hooks/api'; +import { useMetadataSourceSections } from '../domain/source/definition/SourceDefinition'; + -const sections = [ - { i18nKey: 'organizationInformation', property: 'organization' }, - { i18nKey: 'contacts', property: 'contacts' }, - { i18nKey: 'uiMduiInfo', property: 'mdui' }, - { i18nKey: 'spSsoDescriptorInfo', property: 'serviceProviderSsoDescriptor' }, - { i18nKey: 'logoutEndpoints', property: 'logoutEndpoints' }, - { i18nKey: 'securityDescriptorInfo', property: 'securityInfo' }, - { i18nKey: 'assertionConsumerServices', property: 'assertionConsumerServices' }, - { i18nKey: 'relyingPartyOverrides', property: 'relyingPartyOverrides' }, - { i18nKey: 'attributeRelease', property: 'attributeRelease' } -]; export function CopySource({ copy, onNext }) { @@ -64,6 +55,8 @@ export function CopySource({ copy, onNext }) { const sourceIds = data.map(p => p.entityId); + const sections = useMetadataSourceSections(); + return ( <>
@@ -162,7 +155,7 @@ export function CopySource({ copy, onNext }) { onSelect(item, checked)} diff --git a/ui/src/app/metadata/domain/source/definition/SourceDefinition.js b/ui/src/app/metadata/domain/source/definition/SourceDefinition.js index a448d2d03..41d409907 100644 --- a/ui/src/app/metadata/domain/source/definition/SourceDefinition.js +++ b/ui/src/app/metadata/domain/source/definition/SourceDefinition.js @@ -6,6 +6,7 @@ import API_BASE_PATH from '../../../../App.constant'; import {removeNull} from '../../../../core/utility/remove_null'; import { detailedDiff } from 'deep-object-diff'; import isNil from 'lodash/isNil'; +import { useMetadataSchemaContext } from '../../../hoc/MetadataSchema'; export const SourceBase = { label: 'Metadata Source', @@ -534,4 +535,35 @@ export const SourceWizard = { fields: [] } ] +} + +export const sections = [ + { i18nKey: 'organizationInformation', property: 'organization' }, + { i18nKey: 'contacts', property: 'contacts' }, + { i18nKey: 'uiMduiInfo', property: 'mdui' }, + { i18nKey: 'spSsoDescriptorInfo', property: 'serviceProviderSsoDescriptor' }, + { i18nKey: 'logoutEndpoints', property: 'logoutEndpoints' }, + { i18nKey: 'securityDescriptorInfo', property: 'securityInfo' }, + { i18nKey: 'assertionConsumerServices', property: 'assertionConsumerServices' }, + { i18nKey: 'relyingPartyOverrides', property: 'relyingPartyOverrides' }, + { i18nKey: 'attributeRelease', property: 'attributeRelease' } +]; + +export function useMetadataSourceSections() { + const schema = useMetadataSchemaContext(); + + const keys = Object.keys(schema.properties); + const properties = sections.map((s) => s.property); + + const reduced = keys.reduce( + (collection, key) => { + if (properties.indexOf(key) > -1) { + collection.push(sections.find(s => s.property === key)); + } + return collection; + }, + [] + ); + + return reduced; } \ No newline at end of file From 4388dfa2a01054fb5be51f16dd5f70af970d3a5e Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Fri, 15 Jul 2022 09:48:16 -0700 Subject: [PATCH 27/88] Added spinner to dashboard pages --- ui/src/app/core/components/Spinner.js | 9 +++++++++ ui/src/app/dashboard/view/ActionsTab.js | 11 ++++++++--- ui/src/app/dashboard/view/AdminTab.js | 5 ++++- ui/src/app/dashboard/view/Dashboard.js | 14 ++++++++++---- ui/src/app/dashboard/view/ProvidersTab.js | 7 +++++-- ui/src/app/dashboard/view/SourcesTab.js | 8 ++++++-- .../domain/provider/component/ProviderList.js | 3 ++- .../metadata/domain/source/component/SourceList.js | 3 ++- 8 files changed, 46 insertions(+), 14 deletions(-) create mode 100644 ui/src/app/core/components/Spinner.js diff --git a/ui/src/app/core/components/Spinner.js b/ui/src/app/core/components/Spinner.js new file mode 100644 index 000000000..880f53d2a --- /dev/null +++ b/ui/src/app/core/components/Spinner.js @@ -0,0 +1,9 @@ +import React from 'react'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faSpinner } from '@fortawesome/free-solid-svg-icons'; + +export function Spinner ({ size, className }) { + return () +} + +export default Spinner; \ No newline at end of file diff --git a/ui/src/app/dashboard/view/ActionsTab.js b/ui/src/app/dashboard/view/ActionsTab.js index 30bc9e371..eda40b751 100644 --- a/ui/src/app/dashboard/view/ActionsTab.js +++ b/ui/src/app/dashboard/view/ActionsTab.js @@ -1,11 +1,12 @@ import React from 'react'; import { MetadataActions } from '../../admin/container/MetadataActions'; import UserActions from '../../admin/container/UserActions'; +import Spinner from '../../core/components/Spinner'; import Translate from '../../i18n/components/translate'; import SourceList from '../../metadata/domain/source/component/SourceList'; -export function ActionsTab({ sources, users, reloadSources, reloadUsers }) { +export function ActionsTab({ sources, users, reloadSources, reloadUsers, loadingSources, loadingUsers }) { return ( <> @@ -21,7 +22,9 @@ export function ActionsTab({ sources, users, reloadSources, reloadUsers }) {
{(enable) => - enable(s, e, reloadSources)} /> + enable(s, e, reloadSources)}> + {loadingSources &&
} +
}
@@ -36,7 +39,9 @@ export function ActionsTab({ sources, users, reloadSources, reloadUsers }) {

- + + {loadingUsers &&
} +
diff --git a/ui/src/app/dashboard/view/AdminTab.js b/ui/src/app/dashboard/view/AdminTab.js index 5c116c242..ba71e0685 100644 --- a/ui/src/app/dashboard/view/AdminTab.js +++ b/ui/src/app/dashboard/view/AdminTab.js @@ -5,12 +5,13 @@ import UserMaintenance from '../../admin/component/UserMaintenance'; import API_BASE_PATH from '../../App.constant'; import Translate from '../../i18n/components/translate'; +import Spinner from '../../core/components/Spinner'; export function AdminTab () { const [users, setUsers] = React.useState([]); - const { get, response } = useFetch(`${API_BASE_PATH}/admin/users`, { + const { get, response, loading } = useFetch(`${API_BASE_PATH}/admin/users`, { cachePolicy: 'no-cache' }, []); @@ -46,7 +47,9 @@ export function AdminTab () { onChangeUserRole={onChangeUserRole} onDeleteUser={onDeleteUser} onChangeUserGroup={onChangeUserGroup} />} + + {loading &&
}
diff --git a/ui/src/app/dashboard/view/Dashboard.js b/ui/src/app/dashboard/view/Dashboard.js index e5f145572..49cba4079 100644 --- a/ui/src/app/dashboard/view/Dashboard.js +++ b/ui/src/app/dashboard/view/Dashboard.js @@ -26,13 +26,13 @@ export function Dashboard () { const isAdmin = useIsAdmin(); - const loading = useCurrentUserLoading(); + const loadingUser = useCurrentUserLoading(); const [actions, setActions] = React.useState(0); const [users, setUsers] = React.useState([]); const [sources, setSources] = React.useState([]); - const { get, response } = useFetch(`${API_BASE_PATH}`, { + const { get, response, loading } = useFetch(`${API_BASE_PATH}`, { cachePolicy: 'no-cache' }); @@ -64,7 +64,7 @@ export function Dashboard () { return (
- {loading ? + {loadingUser ?
@@ -109,7 +109,13 @@ export function Dashboard () { } /> - + } /> diff --git a/ui/src/app/dashboard/view/ProvidersTab.js b/ui/src/app/dashboard/view/ProvidersTab.js index 023a7f78a..d986f3f68 100644 --- a/ui/src/app/dashboard/view/ProvidersTab.js +++ b/ui/src/app/dashboard/view/ProvidersTab.js @@ -8,13 +8,14 @@ import { Ordered } from '../component/Ordered'; import { useIsAdmin } from '../../core/user/UserContext'; import Alert from 'react-bootstrap/Alert'; import { MetadataActions } from '../../admin/container/MetadataActions'; +import Spinner from '../../core/components/Spinner'; const searchProps = ['name', '@type', 'createdBy']; export function ProvidersTab () { const [providers, setProviders] = React.useState([]); - const { get, response } = useMetadataEntities('provider', { + const { get, response, loading } = useMetadataEntities('provider', { cachePolicy: 'no-cache' }); @@ -54,7 +55,9 @@ export function ProvidersTab () { last={last} onEnable={(p, e) => enable(p, e, loadProviders)} onOrderUp={onOrderUp} - onOrderDown={onOrderDown}> + onOrderDown={onOrderDown}> + {loading &&
} + } } diff --git a/ui/src/app/dashboard/view/SourcesTab.js b/ui/src/app/dashboard/view/SourcesTab.js index b564a3872..40ff4dd4f 100644 --- a/ui/src/app/dashboard/view/SourcesTab.js +++ b/ui/src/app/dashboard/view/SourcesTab.js @@ -5,9 +5,11 @@ import Translate from '../../i18n/components/translate'; import SourceList from '../../metadata/domain/source/component/SourceList'; import { useMetadataEntities, useMetadataEntity } from '../../metadata/hooks/api'; import { Search } from '../component/Search'; +import { Spinner } from '../../core/components/Spinner'; import { NotificationContext, createNotificationAction, NotificationTypes } from '../../notifications/hoc/Notifications'; + const searchProps = ['serviceProviderName', 'entityId', 'createdBy']; export function SourcesTab () { @@ -16,7 +18,7 @@ export function SourcesTab () { const [sources, setSources] = React.useState([]); - const { get, response } = useMetadataEntities('source', { + const { get, response, loading } = useMetadataEntities('source', { cachePolicy: 'no-cache' }); @@ -68,7 +70,9 @@ export function SourcesTab () { entities={searched} onDelete={(id) => remove(id, loadSources)} onEnable={(s, e) => enable(s, e, loadSources) } - onChangeGroup={changeSourceGroup} /> + onChangeGroup={changeSourceGroup}> + {loading &&
} + } } diff --git a/ui/src/app/metadata/domain/provider/component/ProviderList.js b/ui/src/app/metadata/domain/provider/component/ProviderList.js index 3e559eb2a..1b367a69d 100644 --- a/ui/src/app/metadata/domain/provider/component/ProviderList.js +++ b/ui/src/app/metadata/domain/provider/component/ProviderList.js @@ -12,7 +12,7 @@ import { Scroller } from '../../../../dashboard/component/Scroller'; import { useIsAdmin } from '../../../../core/user/UserContext'; import { useTranslator } from '../../../../i18n/hooks'; -export function ProviderList({ entities, reorder = true, first, last, onEnable, onOrderUp, onOrderDown }) { +export function ProviderList({ children, entities, reorder = true, first, last, onEnable, onOrderUp, onOrderDown }) { const isAdmin = useIsAdmin(); const translator = useTranslator(); @@ -91,6 +91,7 @@ export function ProviderList({ entities, reorder = true, first, last, onEnable, )} + {children}
} diff --git a/ui/src/app/metadata/domain/source/component/SourceList.js b/ui/src/app/metadata/domain/source/component/SourceList.js index 109396c2c..42af027dd 100644 --- a/ui/src/app/metadata/domain/source/component/SourceList.js +++ b/ui/src/app/metadata/domain/source/component/SourceList.js @@ -16,7 +16,7 @@ import { useTranslator } from '../../../../i18n/hooks'; import { useCanEnable, useIsAdmin } from '../../../../core/user/UserContext'; import { GroupsProvider } from '../../../../admin/hoc/GroupsProvider'; -export default function SourceList({ entities, onDelete, onEnable, onChangeGroup }) { +export default function SourceList({ entities, onDelete, onEnable, onChangeGroup, children }) { const translator = useTranslator(); const isAdmin = useIsAdmin(); @@ -122,6 +122,7 @@ export default function SourceList({ entities, onDelete, onEnable, onChangeGroup + {children}
} From dfc098bcb2b1611ddd01afe7195de7f2b8e6d0cc Mon Sep 17 00:00:00 2001 From: Sean Porth Date: Fri, 15 Jul 2022 13:11:18 -0400 Subject: [PATCH 28/88] SHIBUI-2316 fixed sqlserver upgrade migration --- backend/src/main/resources/db/changelog/changelog.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/main/resources/db/changelog/changelog.sql b/backend/src/main/resources/db/changelog/changelog.sql index 5bece9633..0a63846a3 100644 --- a/backend/src/main/resources/db/changelog/changelog.sql +++ b/backend/src/main/resources/db/changelog/changelog.sql @@ -132,9 +132,9 @@ EXEC sp_rename 'entity_attributes_filter_target_value.value', target_value, 'COL GO EXEC sp_rename 'entity_attributes_filter_target_value_aud.value', target_value, 'COLUMN' GO -EXEC sp_rename 'name_id_format_filter_target_value', target_value, 'COLUMN' +EXEC sp_rename 'name_id_format_filter_target_value.value', target_value, 'COLUMN' GO -EXEC sp_rename 'name_id_format_filter_target_value_aud', target_value, 'COLUMN' +EXEC sp_rename 'name_id_format_filter_target_value_aud.value', target_value, 'COLUMN' GO EXEC sp_rename 'organizationurl.value', uri_value, 'COLUMN' GO From 6694ec4a7c12992228708752e920d004dc7698c7 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Fri, 15 Jul 2022 10:27:04 -0700 Subject: [PATCH 29/88] Added spinner to history pages --- .../app/metadata/hoc/MetadataVersionsLoader.js | 16 +++++++++++++--- ui/src/app/metadata/view/MetadataHistory.js | 6 ++---- ui/src/app/metadata/view/MetadataWizard.js | 2 ++ 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/ui/src/app/metadata/hoc/MetadataVersionsLoader.js b/ui/src/app/metadata/hoc/MetadataVersionsLoader.js index 025cea743..f552db8c4 100644 --- a/ui/src/app/metadata/hoc/MetadataVersionsLoader.js +++ b/ui/src/app/metadata/hoc/MetadataVersionsLoader.js @@ -4,12 +4,15 @@ import { getMetadataPath } from '../hooks/api'; import API_BASE_PATH from '../../App.constant'; import useFetch from 'use-http'; import { last } from 'lodash'; +import Spinner from '../../core/components/Spinner'; export function MetadataVersionsLoader ({versions, children}) { const ref = React.useRef({}); const [list, setList] = React.useState({}); + const [loading, setLoading] = React.useState(false); + const { type, id } = useParams(); const { get, response } = useFetch(`/${API_BASE_PATH}${getMetadataPath(type)}/${id}/Versions`, { @@ -22,6 +25,8 @@ export function MetadataVersionsLoader ({versions, children}) { addToList(v, l); if (last(versions) !== v) { loadNext(versions[versions.indexOf(v) + 1]); + } else { + setLoading(false); } } } @@ -36,14 +41,19 @@ export function MetadataVersionsLoader ({versions, children}) { function loadNext (v) { loadVersion(v); + } /*eslint-disable react-hooks/exhaustive-deps*/ React.useEffect(() => { loadNext(versions[0]); + setLoading(true); }, [versions]); - return ( - {children(versions.map(v => list[v]).filter(v => !!v))} - ); + return ( + + {children(versions.map(v => list[v]).filter(v => !!v))} + {loading &&
} +
+ ); } \ No newline at end of file diff --git a/ui/src/app/metadata/view/MetadataHistory.js b/ui/src/app/metadata/view/MetadataHistory.js index 719ce8dc3..6df6a7c2e 100644 --- a/ui/src/app/metadata/view/MetadataHistory.js +++ b/ui/src/app/metadata/view/MetadataHistory.js @@ -9,6 +9,7 @@ import Translate from '../../i18n/components/translate'; import { useMetadataHistory } from '../hooks/api'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faUndo } from '@fortawesome/free-solid-svg-icons'; +import Spinner from '../../core/components/Spinner'; const sortVersionsByDate = (versions) => { return versions.sort((a, b) => { @@ -107,16 +108,13 @@ export function MetadataHistory () { )} + {loading &&
} } - {loading &&
- - Loading... -
} ); } \ No newline at end of file diff --git a/ui/src/app/metadata/view/MetadataWizard.js b/ui/src/app/metadata/view/MetadataWizard.js index a95ca777c..8dc5a9d51 100644 --- a/ui/src/app/metadata/view/MetadataWizard.js +++ b/ui/src/app/metadata/view/MetadataWizard.js @@ -8,6 +8,7 @@ import { useMetadataEntity } from '../hooks/api'; import { createNotificationAction, NotificationTypes, useNotificationDispatcher } from '../../notifications/hoc/Notifications'; import { Prompt, useHistory } from 'react-router-dom'; import { useTranslator } from '../../i18n/hooks'; +import Spinner from '../../core/components/Spinner'; export function MetadataWizard ({type, data, onCallback}) { @@ -61,6 +62,7 @@ export function MetadataWizard ({type, data, onCallback}) { : } + {loading &&
} ); From dc368e697d9db6c3ce70ab97f4bab845b17b0f3c Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Wed, 20 Jul 2022 08:10:36 -0700 Subject: [PATCH 30/88] Added filter scroll link to comparison view --- .../app/metadata/view/MetadataComparison.js | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/ui/src/app/metadata/view/MetadataComparison.js b/ui/src/app/metadata/view/MetadataComparison.js index de0022ce0..2e9307acf 100644 --- a/ui/src/app/metadata/view/MetadataComparison.js +++ b/ui/src/app/metadata/view/MetadataComparison.js @@ -4,13 +4,14 @@ import { ArrayParam, withDefault } from 'use-query-params'; +import { scroller } from 'react-scroll'; import { MetadataDefinitionContext, MetadataSchemaContext } from '../hoc/MetadataSchema'; import { MetadataVersionsLoader } from '../hoc/MetadataVersionsLoader'; import { Configuration } from '../hoc/Configuration'; import { MetadataConfiguration } from '../component/MetadataConfiguration'; import { Link, useParams } from 'react-router-dom'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faHistory } from '@fortawesome/free-solid-svg-icons'; +import { faArrowDown, faHistory } from '@fortawesome/free-solid-svg-icons'; import Translate from '../../i18n/components/translate'; import Form from 'react-bootstrap/Form'; import { useTranslation } from '../../i18n/hooks'; @@ -18,6 +19,14 @@ import { MetadataFilterVersionList } from '../domain/filter/component/MetadataFi import { MetadataFilterVersionContext } from '../domain/filter/component/MetadataFilterVersionContext'; import { useMetadataSchema } from '../hooks/schema'; import { FilterableProviders } from '../domain/provider'; +import Button from 'react-bootstrap/Button'; +const onScrollTo = (element, offset = 0) => { + scroller.scrollTo(element, { + duration: 500, + smooth: true, + offset + }); + }; export function MetadataComparison () { @@ -54,6 +63,12 @@ export function MetadataComparison () {   Version History + {type === 'provider' && canFilter && + + } {type === 'provider' && canFilter && v && - +

Metadata Filter @@ -74,7 +89,7 @@ export function MetadataComparison () { {(c) => } - +

}
} From 186e617ef2c571e5763e0446d3b153c02dd30be7 Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Fri, 22 Jul 2022 10:04:40 -0400 Subject: [PATCH 31/88] SHIBUI-2269 Added automated test that checks XML endpoint for filters. --- .../admin/ui/SeleniumSIDETest.groovy | 2 +- .../integration/resources/SHIBUI-2269.side | 545 ++++++++++++++++++ 2 files changed, 546 insertions(+), 1 deletion(-) create mode 100644 backend/src/integration/resources/SHIBUI-2269.side diff --git a/backend/src/integration/groovy/edu/internet2/tier/shibboleth/admin/ui/SeleniumSIDETest.groovy b/backend/src/integration/groovy/edu/internet2/tier/shibboleth/admin/ui/SeleniumSIDETest.groovy index 3c73bfbbf..14a65b52b 100644 --- a/backend/src/integration/groovy/edu/internet2/tier/shibboleth/admin/ui/SeleniumSIDETest.groovy +++ b/backend/src/integration/groovy/edu/internet2/tier/shibboleth/admin/ui/SeleniumSIDETest.groovy @@ -153,6 +153,6 @@ class SeleniumSIDETest extends Specification { 'SHIBUI-1744: Verify attribute bundles in entity attribute filters' | '/SHIBUI-1744-3.side' 'SHIBUI-2052: Logged in user & role appear on dashboard' | '/SHIBUI-2052.side' 'SHIBUI-2116: Verify entity attribute bundle highlights' | '/SHIBUI-2116.side' // Note that this script WILL NOT PASS in the Selenium IDE due to ${driver} not being set (it is provided by this groovy script). - + 'SHIBUI-2269: Verify XML generation of external filters' | '/SHIBUI-2269.side' } } diff --git a/backend/src/integration/resources/SHIBUI-2269.side b/backend/src/integration/resources/SHIBUI-2269.side new file mode 100644 index 000000000..f2848dddb --- /dev/null +++ b/backend/src/integration/resources/SHIBUI-2269.side @@ -0,0 +1,545 @@ +{ + "id": "1b31a551-eb09-4bd4-8db9-694bf1539a46", + "version": "2.0", + "name": "SHIBUI-2269", + "url": "http://localhost:10101", + "tests": [{ + "id": "841ade0e-83bd-4a4b-94f2-de6bd5c536b2", + "name": "SHIBUI-2269", + "commands": [{ + "id": "d6b23986-6d14-4b10-be7b-a7e6f576e3b2", + "comment": "", + "command": "open", + "target": "/login", + "targets": [], + "value": "" + }, { + "id": "f77ecd77-01c2-4463-944e-1a69600f5297", + "comment": "", + "command": "type", + "target": "name=username", + "targets": [ + ["name=username", "name"], + ["css=tr:nth-child(1) input", "css:finder"], + ["xpath=//input[@name='username']", "xpath:attributes"], + ["xpath=//input", "xpath:position"] + ], + "value": "admin" + }, { + "id": "c9bf0a22-faa9-494c-b2ed-6c9653248551", + "comment": "", + "command": "type", + "target": "name=password", + "targets": [ + ["name=password", "name"], + ["css=tr:nth-child(2) input", "css:finder"], + ["xpath=//input[@name='password']", "xpath:attributes"], + ["xpath=//tr[2]/td[2]/input", "xpath:position"] + ], + "value": "adminpass" + }, { + "id": "7ab1d854-3582-4101-bd19-f94b8f438090", + "comment": "", + "command": "sendKeys", + "target": "name=password", + "targets": [ + ["name=password", "name"], + ["css=tr:nth-child(2) input", "css:finder"], + ["xpath=//input[@name='password']", "xpath:attributes"], + ["xpath=//tr[2]/td[2]/input", "xpath:position"] + ], + "value": "${KEY_ENTER}" + }, { + "id": "4059cae7-b9f9-49d0-a213-343bcaba66d1", + "comment": "", + "command": "waitForElementVisible", + "target": "id=metadata-nav-dropdown-toggle", + "targets": [], + "value": "30000" + }, { + "id": "f03af8d5-5875-4a2c-b93a-c3ddcbd4b16a", + "comment": "", + "command": "open", + "target": "/api/heheheheheheheWipeout", + "targets": [], + "value": "" + }, { + "id": "081f495b-4d84-4758-824c-1e85b6311e7f", + "comment": "", + "command": "assertText", + "target": "css=body", + "targets": [], + "value": "yes, you did it" + }, { + "id": "9e912dd5-6ace-45be-bafd-2d1655906575", + "comment": "", + "command": "open", + "target": "/", + "targets": [], + "value": "" + }, { + "id": "3bb52950-667c-4852-a98f-6a6fb5632ba5", + "comment": "", + "command": "waitForElementEditable", + "target": "id=metadata-nav-dropdown-toggle", + "targets": [], + "value": "30000" + }, { + "id": "6af18279-b5ed-47d0-932b-cba97881b9bb", + "comment": "", + "command": "click", + "target": "id=metadata-nav-dropdown-toggle", + "targets": [ + ["id=metadata-nav-dropdown-toggle", "id"], + ["css=#metadata-nav-dropdown-toggle", "css:finder"], + ["xpath=//button[@id='metadata-nav-dropdown-toggle']", "xpath:attributes"], + ["xpath=//div[@id='metadata-nav-dropdown']/button", "xpath:idRelative"], + ["xpath=//div[2]/button", "xpath:position"], + ["xpath=//button[contains(.,'Add New')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "b07230f3-c268-4680-943f-5f8f81414002", + "comment": "", + "command": "click", + "target": "id=metadata-nav-dropdown-provider", + "targets": [ + ["id=metadata-nav-dropdown-provider", "id"], + ["linkText=Add a new metadata provider", "linkText"], + ["css=#metadata-nav-dropdown-provider", "css:finder"], + ["xpath=//a[contains(text(),'Add a new metadata provider')]", "xpath:link"], + ["xpath=//a[@id='metadata-nav-dropdown-provider']", "xpath:attributes"], + ["xpath=//div[@id='metadata-nav-dropdown']/div/a[2]", "xpath:idRelative"], + ["xpath=//a[contains(@href, '/metadata/provider/new')]", "xpath:href"], + ["xpath=//a[2]", "xpath:position"], + ["xpath=//a[contains(.,'Add a new metadata provider')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "004dbab9-263e-4f90-9c5f-9d2948d80ab5", + "comment": "", + "command": "waitForElementEditable", + "target": "name=type", + "targets": [], + "value": "30000" + }, { + "id": "d77381c8-2164-499d-91fa-e762792644ec", + "comment": "", + "command": "select", + "target": "name=type", + "targets": [], + "value": "label=ExternalMetadataResolver" + }, { + "id": "8edf9e5e-188e-435d-acbd-a0ee770df39d", + "comment": "", + "command": "type", + "target": "name=name", + "targets": [ + ["name=name", "name"], + ["css=.form-control", "css:finder"], + ["xpath=//input[@name='name']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div/div/form/div/input", "xpath:idRelative"], + ["xpath=//input", "xpath:position"] + ], + "value": "ExternalTest" + }, { + "id": "d652c1d5-44d2-448a-8dae-85d266b51638", + "comment": "", + "command": "click", + "target": "css=.direction", + "targets": [ + ["css=.direction", "css:finder"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/nav/ul/li[2]/button/span[2]", "xpath:idRelative"], + ["xpath=//span[2]", "xpath:position"], + ["xpath=//span[contains(.,'Next')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "d1294ac3-d91c-495a-ab0b-cc3183cc08d5", + "comment": "", + "command": "pause", + "target": "5000", + "targets": [], + "value": "" + }, { + "id": "b15dcd2a-9360-4831-a95c-8797eb235972", + "comment": "", + "command": "type", + "target": "id=root_xmlId", + "targets": [ + ["id=root_xmlId", "id"], + ["css=#root_xmlId", "css:finder"], + ["xpath=//input[@id='root_xmlId']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div[2]/div/div/form/div/div/div/div/div[2]/div/div/div/input", "xpath:idRelative"], + ["xpath=//input", "xpath:position"] + ], + "value": "1" + }, { + "id": "657ee88c-4777-485b-b3de-a467657e6fe4", + "comment": "", + "command": "type", + "target": "id=root_description", + "targets": [ + ["id=root_description", "id"], + ["css=#root_description", "css:finder"], + ["xpath=//textarea[@id='root_description']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div[2]/div/div/form/div/div/div/div/div[2]/div[2]/div/div/textarea", "xpath:idRelative"], + ["xpath=//textarea", "xpath:position"] + ], + "value": "External Test" + }, { + "id": "5548997c-2f3a-4376-89a9-606b5b948ef1", + "comment": "", + "command": "click", + "target": "css=.label:nth-child(1)", + "targets": [ + ["css=.label:nth-child(1)", "css:finder"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div/nav/ul/li[3]/button/span", "xpath:idRelative"], + ["xpath=//li[3]/button/span", "xpath:position"], + ["xpath=//span[contains(.,'2. Finished!')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "826e7804-88f0-436e-9951-11e8065671ed", + "comment": "", + "command": "click", + "target": "css=.save", + "targets": [ + ["css=.save", "css:finder"], + ["xpath=(//button[@type='button'])[6]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div/nav/ul/li[3]/button", "xpath:idRelative"], + ["xpath=//li[3]/button", "xpath:position"] + ], + "value": "" + }, { + "id": "ab15e915-02b9-4616-9f92-ffcb0386918c", + "comment": "", + "command": "click", + "target": "linkText=ExternalTest", + "targets": [ + ["linkText=ExternalTest", "linkText"], + ["css=.align-middle > a", "css:finder"], + ["xpath=//a[contains(text(),'ExternalTest')]", "xpath:link"], + ["xpath=//div[@id='root']/div/main/div/section/div/div[2]/div/div/div/table/tbody/tr/td[2]/a", "xpath:idRelative"], + ["xpath=//a[contains(@href, '/metadata/provider/0e237f9c-3ffe-49da-a60d-289733126d92/configuration/options')]", "xpath:href"], + ["xpath=//td[2]/a", "xpath:position"], + ["xpath=//a[contains(.,'ExternalTest')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "3ece6089-c462-437e-9384-62cede8afc7d", + "comment": "", + "command": "click", + "target": "linkText=Add Filter", + "targets": [ + ["linkText=Add Filter", "linkText"], + ["css=#filters .btn", "css:finder"], + ["xpath=//div[@id='filters']/div/div/a", "xpath:idRelative"], + ["xpath=//a[contains(@href, '/metadata/provider/0e237f9c-3ffe-49da-a60d-289733126d92/filter/new')]", "xpath:href"], + ["xpath=//div[3]/div/div/a", "xpath:position"], + ["xpath=//a[contains(.,' Add Filter')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "b409c3ea-3066-4d06-a660-4702cdace6ec", + "comment": "", + "command": "waitForElementEditable", + "target": "name=type", + "targets": [], + "value": "30000" + }, { + "id": "84111b1d-6927-4536-b883-0b057f13d898", + "comment": "", + "command": "select", + "target": "name=type", + "targets": [], + "value": "label=EntityAttributes" + }, { + "id": "ec27be24-7951-4d76-9457-4a5dbe5866ef", + "comment": "", + "command": "waitForElementEditable", + "target": "id=root_name", + "targets": [], + "value": "30000" + }, { + "id": "bea341ae-4cdf-432e-8032-c827e9c8a7b8", + "comment": "", + "command": "type", + "target": "id=root_name", + "targets": [ + ["id=root_name", "id"], + ["css=#root_name", "css:finder"], + ["xpath=//input[@id='root_name']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div[2]/div[2]/div[2]/div/form/div/div/div/div/div/div/div/div/input", "xpath:idRelative"], + ["xpath=//input", "xpath:position"] + ], + "value": "1" + }, { + "id": "79f5b0a9-57e9-4f6b-8980-4af6258a5aa4", + "comment": "", + "command": "click", + "target": "id=dropdown-label.filter-target-type", + "targets": [ + ["id=dropdown-label.filter-target-type", "id"], + ["css=#dropdown-label\\.filter-target-type", "css:finder"], + ["xpath=//button[@id='dropdown-label.filter-target-type']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div[2]/div[2]/div[2]/div/form/div/div/div/div[6]/div/div/div/fieldset/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//fieldset/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Entity ID ')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "d01e44ab-802b-4d85-ac2e-e2e03a00c1c0", + "comment": "", + "command": "click", + "target": "css=.dropdown-item:nth-child(3)", + "targets": [ + ["css=.dropdown-item:nth-child(3)", "css:finder"], + ["xpath=(//button[@type='button'])[17]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div[2]/div[2]/div[2]/div/form/div/div/div/div[6]/div/div/div/fieldset/div/div/div/div/div/button[3]", "xpath:idRelative"], + ["xpath=//div/button[3]", "xpath:position"], + ["xpath=//button[contains(.,'Script')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "f401438a-0154-4610-be40-580829ba76a9", + "comment": "", + "command": "type", + "target": "css=.npm__react-simple-code-editor__textarea", + "targets": [ + ["css=.npm__react-simple-code-editor__textarea", "css:finder"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div[2]/div[2]/div[2]/div/form/div/div/div/div[6]/div/div/div/fieldset/div/div/div[2]/div/div/div/div/textarea", "xpath:idRelative"], + ["xpath=//textarea", "xpath:position"] + ], + "value": "true;" + }, { + "id": "75563d4f-487d-4c08-81d9-26a8ef989711", + "comment": "", + "command": "click", + "target": "css=.btn-info", + "targets": [ + ["css=.btn-info", "css:finder"], + ["xpath=(//button[@type='button'])[7]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div[2]/div/div[2]/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/button", "xpath:position"], + ["xpath=//button[contains(.,' Save')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "21f5c73b-0aa2-41cd-a97c-35c05a892275", + "comment": "", + "command": "click", + "target": "linkText=Add Filter", + "targets": [ + ["linkText=Add Filter", "linkText"], + ["css=#filters > .numbered-header .btn", "css:finder"], + ["xpath=//div[@id='filters']/div/div/a", "xpath:idRelative"], + ["xpath=//a[contains(@href, '/metadata/provider/0e237f9c-3ffe-49da-a60d-289733126d92/filter/new')]", "xpath:href"], + ["xpath=//div[3]/div/div/a", "xpath:position"], + ["xpath=//a[contains(.,' Add Filter')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "6eb76a2f-370a-4547-b05e-f0dc8bdb60ba", + "comment": "", + "command": "select", + "target": "name=type", + "targets": [], + "value": "label=NameIDFormat" + }, { + "id": "fcacadd8-7b9e-4878-b1cc-3d5da56e6660", + "comment": "", + "command": "click", + "target": "css=.col-12 > .mb-3 > div > div", + "targets": [ + ["css=.col-12 > .mb-3 > div > div", "css:finder"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div[2]/div[2]/div[2]/div/form/div/div/div/div/div/div/div/div", "xpath:idRelative"], + ["xpath=//div/div/div/div/div/div/div/div", "xpath:position"] + ], + "value": "" + }, { + "id": "4d206821-ace7-483e-876e-99c7a0490144", + "comment": "", + "command": "waitForElementEditable", + "target": "id=root_name", + "targets": [], + "value": "30000" + }, { + "id": "62afd5f1-e565-4bb8-a142-9eda83e98a1c", + "comment": "", + "command": "type", + "target": "id=root_name", + "targets": [ + ["id=root_name", "id"], + ["css=#root_name", "css:finder"], + ["xpath=//input[@id='root_name']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div[2]/div[2]/div[2]/div/form/div/div/div/div/div/div/div/div/input", "xpath:idRelative"], + ["xpath=//input", "xpath:position"] + ], + "value": "2" + }, { + "id": "da90db0c-c7e6-4dc5-b643-13a3c2029f05", + "comment": "", + "command": "click", + "target": "id=dropdown-label.filter-target-type", + "targets": [ + ["id=dropdown-label.filter-target-type", "id"], + ["css=#dropdown-label\\.filter-target-type", "css:finder"], + ["xpath=//button[@id='dropdown-label.filter-target-type']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div[2]/div[2]/div[2]/div/form/div/div/div/div[3]/div/div/div/fieldset/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//fieldset/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Entity ID ')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "bce0cd29-246e-4f6e-a860-0eade5c73850", + "comment": "", + "command": "click", + "target": "css=.dropdown-item:nth-child(3)", + "targets": [ + ["css=.dropdown-item:nth-child(3)", "css:finder"], + ["xpath=(//button[@type='button'])[16]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div[2]/div[2]/div[2]/div/form/div/div/div/div[3]/div/div/div/fieldset/div/div/div/div/div/button[3]", "xpath:idRelative"], + ["xpath=//button[3]", "xpath:position"], + ["xpath=//button[contains(.,'Script')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "2923ab38-d8ff-4d3f-b247-1d977d06a0dd", + "comment": "", + "command": "click", + "target": "id=dropdown-label.filter-target-type", + "targets": [ + ["id=dropdown-label.filter-target-type", "id"], + ["css=#dropdown-label\\.filter-target-type", "css:finder"], + ["xpath=//button[@id='dropdown-label.filter-target-type']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div[2]/div[2]/div[2]/div/form/div/div/div/div[3]/div/div/div/fieldset/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//fieldset/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Script ')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "7141ca97-429a-4d1f-9efb-68a23fc92748", + "comment": "", + "command": "click", + "target": "css=.show > .dropdown-item:nth-child(2)", + "targets": [ + ["css=.show > .dropdown-item:nth-child(2)", "css:finder"], + ["xpath=(//button[@type='button'])[15]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div[2]/div[2]/div[2]/div/form/div/div/div/div[3]/div/div/div/fieldset/div/div/div/div/div/button[2]", "xpath:idRelative"], + ["xpath=//fieldset/div/div/div/div/div/button[2]", "xpath:position"], + ["xpath=//button[contains(.,'Regex')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "e15eab26-07bd-45e9-ba8e-ee2a400baee9", + "comment": "", + "command": "type", + "target": "id=targetInput", + "targets": [ + ["id=targetInput", "id"], + ["name=script", "name"], + ["css=#targetInput", "css:finder"], + ["xpath=//input[@id='targetInput']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div[2]/div[2]/div[2]/div/form/div/div/div/div[3]/div/div/div/fieldset/div/div/div[2]/div/div/input", "xpath:idRelative"], + ["xpath=//div[2]/div/div/input", "xpath:position"] + ], + "value": ".*unicon.*" + }, { + "id": "55cc5ef6-1b05-48a9-bc9d-58551b751feb", + "comment": "", + "command": "click", + "target": "css=.fa-floppy-disk > path", + "targets": [ + ["css=.fa-floppy-disk > path", "css:finder"] + ], + "value": "" + }, { + "id": "802be014-0d04-4bda-93d1-ca7a5d7f802d", + "comment": "", + "command": "waitForElementVisible", + "target": "css=.text:nth-child(2)", + "targets": [ + ["css=.text:nth-child(2)", "css:finder"], + ["xpath=//div[@id='root']/div/main/div/section/div/div/section/div/div/h2/span[2]", "xpath:idRelative"], + ["xpath=//h2/span[2]", "xpath:position"], + ["xpath=//span[contains(.,'Common Attributes')]", "xpath:innerText"] + ], + "value": "30000" + }, { + "id": "7e3e7d65-e0ff-4a2d-a0e9-5080bfefd4df", + "comment": "", + "command": "click", + "target": "css=.btn-outline-secondary", + "targets": [ + ["css=.btn-outline-secondary", "css:finder"], + ["xpath=(//button[@type='button'])[5]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div/div/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Enable')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "42929ec9-7860-467a-a52b-946df9965de5", + "comment": "", + "command": "click", + "target": "xpath=//div[@id='filters']/ul/li/div/span[3]/div/input", + "targets": [ + ["id=customSwitch-df84f9b7-6cbe-4727-b71e-733eb9b46ca0", "id"], + ["css=#customSwitch-df84f9b7-6cbe-4727-b71e-733eb9b46ca0", "css:finder"], + ["xpath=//input[@id='customSwitch-df84f9b7-6cbe-4727-b71e-733eb9b46ca0']", "xpath:attributes"], + ["xpath=//div[@id='filters']/ul/li/div/span[3]/div/input", "xpath:idRelative"], + ["xpath=//input", "xpath:position"] + ], + "value": "" + }, { + "id": "3bb95cdd-23aa-425d-af75-e4d69b819235", + "comment": "", + "command": "click", + "target": "xpath=//div[@id='filters']/ul/li[2]/div/span[3]/div/input", + "targets": [ + ["id=customSwitch-be9ce5a5-1242-4884-882a-7a977cd7bbd5", "id"], + ["css=#customSwitch-be9ce5a5-1242-4884-882a-7a977cd7bbd5", "css:finder"], + ["xpath=//input[@id='customSwitch-be9ce5a5-1242-4884-882a-7a977cd7bbd5']", "xpath:attributes"], + ["xpath=//div[@id='filters']/ul/li[2]/div/span[3]/div/input", "xpath:idRelative"], + ["xpath=//li[2]/div/span[3]/div/input", "xpath:position"] + ], + "value": "" + }, { + "id": "038ab74e-cab9-486e-bbfc-25a7c1cfad82", + "comment": "", + "command": "open", + "target": "/api/MetadataResolvers/External", + "targets": [], + "value": "" + }, { + "id": "9e6390c9-3122-4038-8dce-61ae0c157e4a", + "comment": "", + "command": "assertText", + "target": "css=#folder4 > .opened > .line > span", + "targets": [ + ["css=#folder4 > .opened > .line > span", "css:finder"] + ], + "value": "" + }, { + "id": "8c32b412-dc63-4be5-98fb-8c3cd67895af", + "comment": "", + "command": "assertText", + "target": "css=#folder7 > .opened > .line > span", + "targets": [ + ["css=#folder7 > .opened > .line > span", "css:finder"] + ], + "value": "" + }] + }], + "suites": [{ + "id": "d2caeac4-7520-4e3c-96b1-840610b6983c", + "name": "Default Suite", + "persistSession": false, + "parallel": false, + "timeout": 300, + "tests": ["841ade0e-83bd-4a4b-94f2-de6bd5c536b2"] + }], + "urls": ["http://localhost:10101/"], + "plugins": [] +} \ No newline at end of file From 5abc51a4815c3e3afc2617cc21b1126511b8324d Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 22 Jul 2022 10:39:01 -0700 Subject: [PATCH 32/88] SHIBUI-2268 intermediate update (non-passing tests / working code) --- backend/build.gradle | 6 ++ .../JPAMetadataResolverServiceImpl.groovy | 6 +- .../ui/domain/AlgorithmDigestMethod.java | 29 ++++++++ .../admin/ui/domain/EncryptionMethod.java | 14 ++-- ...Method.java => SignatureDigestMethod.java} | 9 +-- .../AbstractAlgorithmIdentifierType.java | 20 ++++++ .../ui/domain/filters/algorithm/Entity.java | 13 +++- .../ui/domain/filters/algorithm/MGF.java | 24 +++++++ .../domain/filters/algorithm/OtherSource.java | 26 +++++++ .../ui/domain/filters/algorithm/PRF.java | 24 +++++++ .../JPAXMLObjectProviderInitializer.java | 3 +- .../jpa-saml2-metadata-algorithm-config.xml | 6 +- .../jpa-saml2-metadata-ds-config.xml | 23 +++++++ .../templates/SignatureBuilderTemplate.java | 22 ++++++ ...XMLObjectProviderInitializerForTest.groovy | 2 +- ...JPAMetadataResolverServiceImplTests.groovy | 69 ++++++++++++++++++- .../admin/ui/util/TestHelpers.groovy | 17 ++++- .../src/test/resources/conf/2268-complex.xml | 36 ++++++++++ .../src/test/resources/conf/2268-simple.xml | 30 +++++--- .../jpa-saml2-metadata-algorithm-config.xml | 34 +++++++++ .../jpa-saml2-metadata-ds-config.xml | 23 +++++++ 21 files changed, 407 insertions(+), 29 deletions(-) create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AlgorithmDigestMethod.java rename backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/{DigestMethod.java => SignatureDigestMethod.java} (66%) create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AbstractAlgorithmIdentifierType.java create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/MGF.java create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/OtherSource.java create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/PRF.java create mode 100644 backend/src/main/resources/jpa-saml2-metadata-ds-config.xml create mode 100644 backend/src/main/templates/SignatureBuilderTemplate.java create mode 100644 backend/src/test/resources/conf/2268-complex.xml create mode 100644 backend/src/test/resources/jpa-saml2-metadata-algorithm-config.xml create mode 100644 backend/src/test/resources/jpa-saml2-metadata-ds-config.xml diff --git a/backend/build.gradle b/backend/build.gradle index 71ab2c763..cfd16a65a 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -331,6 +331,12 @@ task generateSources { processLine(it['@className'].toString(), 'src/main/templates/AlgorithmBuilderTemplate.java') } } + + new XmlSlurper().parse(file('src/main/resources/jpa-saml2-metadata-ds-config.xml')).with { builders -> + builders.ObjectProviders.ObjectProvider.BuilderClass.each { + processLine(it['@className'].toString(), 'src/main/templates/SignatureBuilderTemplate.java') + } + } } } 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 a8108cbc1..7efc18e47 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 @@ -97,11 +97,13 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { markupBuilderDelegate.MetadataFilter( 'xsi:type': 'Algorithm', 'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', - 'xsi:schemaLocation': 'urn:mace:shibboleth:2.0:metadata http://shibboleth.net/schema/idp/shibboleth-metadata.xsd urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd urn:oasis:names:tc:SAML:2.0:assertion http://docs.oasis-open.org/security/saml/v2.0/saml-schema-assertion-2.0.xsd urn:oasis:names:tc:SAML:2.0:metadata http://docs.oasis-open.org/security/saml/v2.0/saml-schema-metadata-2.0.xsd', + 'xsi:schemaLocation': 'urn:mace:shibboleth:2.0:metadata http://shibboleth.net/schema/idp/shibboleth-metadata.xsd urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd urn:oasis:names:tc:SAML:2.0:assertion http://docs.oasis-open.org/security/saml/v2.0/saml-schema-assertion-2.0.xsd urn:oasis:names:tc:SAML:2.0:metadata http://docs.oasis-open.org/security/saml/v2.0/saml-schema-metadata-2.0.xsd urn:oasis:names:tc:SAML:metadata:algsupport https://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-metadata-algsupport-v1.0.xsd http://www.w3.org/2000/09/xmldsig# https://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd http://www.w3.org/2009/xmlenc11# https://www.w3.org/TR/xmlenc-core1/xenc-schema-11.xsd', 'xmlns:md': 'urn:oasis:names:tc:SAML:2.0:metadata', 'xmlns': 'urn:mace:shibboleth:2.0:metadata', 'xmlns:security': 'urn:mace:shibboleth:2.0:security', - 'xmlns:saml2': 'urn:oasis:names:tc:SAML:2.0:assertion' + 'xmlns:saml2': 'urn:oasis:names:tc:SAML:2.0:assertion', + 'xmlns:xenc11': 'http://www.w3.org/2009/xmlenc11#', + 'xmlns:alg': 'urn:oasis:names:tc:SAML:metadata:algsupport' ) { filter.unknownXMLObjects.each { xmlObject -> { diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AlgorithmDigestMethod.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AlgorithmDigestMethod.java new file mode 100644 index 000000000..509f9613d --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AlgorithmDigestMethod.java @@ -0,0 +1,29 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain; + +import lombok.EqualsAndHashCode; + +import javax.annotation.Nullable; +import javax.persistence.Entity; + +@Entity(name = "DigestMethod") // for backwards compatibility instead of dealing with renaming the table +@EqualsAndHashCode(callSuper = true) +public class AlgorithmDigestMethod extends AbstractElementExtensibleXMLObject implements org.opensaml.saml.ext.saml2alg.DigestMethod { + private String algorithm; + + public AlgorithmDigestMethod() {} + + public AlgorithmDigestMethod(String algorithm) { + this.algorithm = algorithm; + } + + @Nullable + @Override + public String getAlgorithm() { + return this.algorithm; + } + + @Override + public void setAlgorithm(@Nullable String value) { + this.algorithm = value; + } +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/EncryptionMethod.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/EncryptionMethod.java index be8da1f0c..16a122883 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/EncryptionMethod.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/EncryptionMethod.java @@ -2,12 +2,14 @@ import lombok.EqualsAndHashCode; import org.hibernate.envers.Audited; +import org.opensaml.core.xml.XMLObject; import org.opensaml.xmlsec.encryption.KeySize; import org.opensaml.xmlsec.encryption.OAEPparams; import javax.annotation.Nullable; import javax.persistence.Embedded; import javax.persistence.Entity; +import java.util.List; @Entity @EqualsAndHashCode(callSuper = true) @@ -16,12 +18,9 @@ public class EncryptionMethod extends AbstractElementExtensibleXMLObject impleme private String algorithm; - @Embedded - private KeySize keySize; - - @Embedded - private OAEPparams oaePparams; + @Embedded private KeySize keySize; + @Embedded private OAEPparams oaePparams; @Nullable @Override @@ -56,5 +55,8 @@ public void setOAEPparams(@Nullable org.opensaml.xmlsec.encryption.OAEPparams oa this.oaePparams = oaePparams; } - + @Override + public List getOrderedChildren() { + return this.getUnknownXMLObjects(); + } } \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/DigestMethod.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SignatureDigestMethod.java similarity index 66% rename from backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/DigestMethod.java rename to backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SignatureDigestMethod.java index 199947f88..519df1faf 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/DigestMethod.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SignatureDigestMethod.java @@ -1,18 +1,19 @@ package edu.internet2.tier.shibboleth.admin.ui.domain; import lombok.EqualsAndHashCode; +import org.opensaml.xmlsec.signature.DigestMethod; import javax.annotation.Nullable; import javax.persistence.Entity; @Entity @EqualsAndHashCode(callSuper = true) -public class DigestMethod extends AbstractElementExtensibleXMLObject implements org.opensaml.saml.ext.saml2alg.DigestMethod { +public class SignatureDigestMethod extends AbstractElementExtensibleXMLObject implements DigestMethod { private String algorithm; - public DigestMethod() {} + public SignatureDigestMethod() {} - public DigestMethod(String algorithm) { + public SignatureDigestMethod(String algorithm) { this.algorithm = algorithm; } @@ -26,4 +27,4 @@ public String getAlgorithm() { public void setAlgorithm(@Nullable String value) { this.algorithm = value; } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AbstractAlgorithmIdentifierType.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AbstractAlgorithmIdentifierType.java new file mode 100644 index 000000000..fcca2dd08 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AbstractAlgorithmIdentifierType.java @@ -0,0 +1,20 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm; + +import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractXMLObject; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.hibernate.envers.Audited; + +import javax.persistence.Entity; + +@Entity +@Audited +@Getter +@Setter +@ToString +@EqualsAndHashCode(callSuper = true) +public abstract class AbstractAlgorithmIdentifierType extends AbstractXMLObject { + private String algorithm; +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/Entity.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/Entity.java index 9a741f6e8..b15ec2ca1 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/Entity.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/Entity.java @@ -1,13 +1,24 @@ package edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm; import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractXMLObject; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.hibernate.envers.Audited; import javax.annotation.Nullable; +@javax.persistence.Entity +@Audited +@Getter +@Setter +@ToString +@EqualsAndHashCode(callSuper = true) public class Entity extends AbstractXMLObject implements org.opensaml.core.xml.schema.XSString { private String uri; - private Entity(){ + public Entity(){ setElementLocalName("Entity"); } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/MGF.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/MGF.java new file mode 100644 index 000000000..f78eaaf00 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/MGF.java @@ -0,0 +1,24 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.hibernate.envers.Audited; +import org.opensaml.xmlsec.encryption.support.EncryptionConstants; + +import javax.persistence.Entity; + +@Entity +@Audited +@Getter +@Setter +@ToString +@EqualsAndHashCode(callSuper = true) +public class MGF extends AbstractAlgorithmIdentifierType { + public MGF() { + setElementLocalName("MGF"); + setNamespaceURI(EncryptionConstants.XMLENC11_NS); + setNamespacePrefix(EncryptionConstants.XMLENC11_PREFIX); + } +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/OtherSource.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/OtherSource.java new file mode 100644 index 000000000..b57e0c82c --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/OtherSource.java @@ -0,0 +1,26 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.hibernate.envers.Audited; +import org.opensaml.xmlsec.encryption.support.EncryptionConstants; + +import javax.persistence.Entity; + +@Entity +@Audited +@Getter +@Setter +@ToString +@EqualsAndHashCode(callSuper = true) +public class OtherSource extends AbstractAlgorithmIdentifierType { + public OtherSource() { + { + setElementLocalName("OtherSource"); + setNamespaceURI(EncryptionConstants.XMLENC11_NS); + setNamespacePrefix(EncryptionConstants.XMLENC11_PREFIX); + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/PRF.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/PRF.java new file mode 100644 index 000000000..3ee2dabec --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/PRF.java @@ -0,0 +1,24 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.hibernate.envers.Audited; +import org.opensaml.xmlsec.encryption.support.EncryptionConstants; + +import javax.persistence.Entity; + +@Entity +@Audited +@Getter +@Setter +@ToString +@EqualsAndHashCode(callSuper = true) +public class PRF extends AbstractAlgorithmIdentifierType { + public PRF() { + setElementLocalName("PRF"); + setNamespaceURI(EncryptionConstants.XMLENC11_NS); + setNamespacePrefix(EncryptionConstants.XMLENC11_PREFIX); + } +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializer.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializer.java index 25000ae67..d1413b87f 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializer.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializer.java @@ -15,10 +15,11 @@ protected String[] getConfigResources() { "/jpa-saml2-metadata-ui-config.xml", "/jpa-signature-config.xml", "/jpa-saml2-metadata-algorithm-config.xml", + "/jpa-saml2-metadata-ds-config.xml", "/encryption-config.xml", "/jpa-saml2-metadata-reqinit-config.xml", "/saml2-protocol-config.xml", "/modified-saml2-assertion-config.xml" }; } -} +} \ No newline at end of file diff --git a/backend/src/main/resources/jpa-saml2-metadata-algorithm-config.xml b/backend/src/main/resources/jpa-saml2-metadata-algorithm-config.xml index f6432a71a..c37c788c1 100644 --- a/backend/src/main/resources/jpa-saml2-metadata-algorithm-config.xml +++ b/backend/src/main/resources/jpa-saml2-metadata-algorithm-config.xml @@ -6,13 +6,13 @@ - + - + @@ -31,4 +31,4 @@ - + \ No newline at end of file diff --git a/backend/src/main/resources/jpa-saml2-metadata-ds-config.xml b/backend/src/main/resources/jpa-saml2-metadata-ds-config.xml new file mode 100644 index 000000000..3a0eed8f0 --- /dev/null +++ b/backend/src/main/resources/jpa-saml2-metadata-ds-config.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/backend/src/main/templates/SignatureBuilderTemplate.java b/backend/src/main/templates/SignatureBuilderTemplate.java new file mode 100644 index 000000000..d8ba87cb1 --- /dev/null +++ b/backend/src/main/templates/SignatureBuilderTemplate.java @@ -0,0 +1,22 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain; + +import edu.internet2.tier.shibboleth.admin.ui.opensaml.xml.AbstractXMLObjectBuilder; +import org.opensaml.xmlsec.signature.support.SignatureConstants; + +public class {{TOKEN}}Builder extends AbstractXMLObjectBuilder<{{TOKEN}}> { + public {{TOKEN}}Builder() { + } + + public {{TOKEN}} buildObject() { + return buildObject(SignatureConstants.XMLSIG_NS, {{TOKEN}}.DEFAULT_ELEMENT_LOCAL_NAME, + SignatureConstants.XMLSIG_PREFIX); + } + + public {{TOKEN}} buildObject(final String namespaceURI, final String localName, final String namespacePrefix) { + {{TOKEN}} o = new {{TOKEN}}(); + o.setNamespaceURI(namespaceURI); + o.setElementLocalName(localName); + o.setNamespacePrefix(namespacePrefix); + return o; + } +} \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializerForTest.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializerForTest.groovy index b4df893ab..4ac1ba2b1 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializerForTest.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializerForTest.groovy @@ -6,7 +6,7 @@ class JPAXMLObjectProviderInitializerForTest extends AbstractXMLObjectProviderIn @Override protected String[] getConfigResources() { return new String[]{ - "/jpa-saml2-metadata-config.xml" + "/jpa-saml2-metadata-config.xml", "jpa-saml2-metadata-algorithm-config.xml", "jpa-saml2-metadata-ds-config.xml" } } } \ No newline at end of file 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 d5d8c5a23..524a03f78 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 @@ -3,13 +3,16 @@ package edu.internet2.tier.shibboleth.admin.ui.service import edu.internet2.tier.shibboleth.admin.ui.AbstractBaseDataJpaTest import edu.internet2.tier.shibboleth.admin.ui.configuration.PlaceholderResolverComponentsConfiguration import edu.internet2.tier.shibboleth.admin.ui.configuration.ShibUIConfiguration +import edu.internet2.tier.shibboleth.admin.ui.domain.AlgorithmDigestMethod import edu.internet2.tier.shibboleth.admin.ui.domain.EncryptionMethod -import edu.internet2.tier.shibboleth.admin.ui.domain.EncryptionMethodBuilder +import edu.internet2.tier.shibboleth.admin.ui.domain.SignatureDigestMethod +import edu.internet2.tier.shibboleth.admin.ui.domain.SigningMethod import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.Entity +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.MGF import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ClasspathMetadataResource import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetadataResolver import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.LocalDynamicMetadataResolver @@ -31,6 +34,7 @@ import org.opensaml.saml.common.xml.SAMLConstants import org.opensaml.saml.metadata.resolver.MetadataResolver import org.opensaml.saml.metadata.resolver.filter.MetadataFilterChain import org.opensaml.saml.metadata.resolver.impl.ResourceBackedMetadataResolver +import org.opensaml.xmlsec.signature.support.SignatureConstants import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.TestConfiguration import org.springframework.context.annotation.Bean @@ -167,6 +171,41 @@ class JPAMetadataResolverServiceImplTests extends AbstractBaseDataJpaTest { generatedXmlIsTheSameAsExpectedXml('/conf/2268-simple.xml', domBuilder.parseText(writer.toString())) } + def 'test generating complex AlgorithmFilter xml snippet'() { + given: + def filter = TestObjectGenerator.algorithmFilter() + EncryptionMethod encryptionMethod = getEncryptionMethod("http://www.w3.org/2001/04/xmlenc#aes128-cbc") + filter.addUnknownXMLObject(encryptionMethod) + + EncryptionMethod encryptionMethod2 = getEncryptionMethod("http://www.w3.org/2009/xmlenc11#rsa-oaep") +// MGF mgf = new MGF() +// mgf.setAlgorithm("http://www.w3.org/2009/xmlenc11#mgf1sha256") +// encryptionMethod2.addUnknownXMLObject(mgf) + SignatureDigestMethod dm = getSignatureDigestMethod("http://www.w3.org/2001/04/xmlenc#sha256") + encryptionMethod2.addUnknownXMLObject(dm) + filter.addUnknownXMLObject(encryptionMethod2) + + AlgorithmDigestMethod dm2 = getDigestMethod("http://www.w3.org/2001/04/xmlenc#sha51") + filter.addUnknownXMLObject(dm2) + + SigningMethod sm = new SigningMethod() + sm.setNamespaceURI(SAMLConstants.SAML20ALG_NS) + sm.setElementLocalName(SigningMethod.DEFAULT_ELEMENT_LOCAL_NAME) + sm.setNamespacePrefix(SAMLConstants.SAML20ALG_PREFIX) + sm.setAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512") + filter.addUnknownXMLObject(sm) + + Entity entity = new Entity() + entity.setValue("https://broken.example.org/sp") + filter.addUnknownXMLObject(entity) + + when: + genXmlSnippet(markupBuilder) { JPAMetadataResolverServiceImpl.cast(metadataResolverService).constructXmlNodeForFilter(filter, it) } + + then: + generatedXmlIsTheSameAsExpectedXml('/conf/2268-complex.xml', domBuilder.parseText(writer.toString())) + } + def 'test generating EntityAttributesFilter xml snippet with condition script'() { given: def filter = testObjectGenerator.entityAttributesFilterWithConditionScript() @@ -489,6 +528,34 @@ class JPAMetadataResolverServiceImplTests extends AbstractBaseDataJpaTest { !DiffBuilder.compare(Input.fromStream(this.class.getResourceAsStream('/metadata/984-3-expected.xml'))).withTest(Input.fromString(openSamlObjects.marshalToXmlString(ed))).ignoreComments().ignoreWhitespace().build().hasDifferences() } + private EncryptionMethod getEncryptionMethod(String algorithm){ + EncryptionMethod encryptionMethod = new EncryptionMethod() + encryptionMethod.setElementLocalName(EncryptionMethod.DEFAULT_ELEMENT_LOCAL_NAME) + encryptionMethod.setNamespacePrefix(SAMLConstants.SAML20MD_PREFIX) + encryptionMethod.setNamespaceURI(SAMLConstants.SAML20MD_NS) + encryptionMethod.setSchemaLocation(SAMLConstants.SAML20MD_SCHEMA_LOCATION) + encryptionMethod.setAlgorithm(algorithm) + return encryptionMethod + } + + private AlgorithmDigestMethod getDigestMethod(String algorithm) { + AlgorithmDigestMethod dm = new AlgorithmDigestMethod() + dm.setNamespaceURI(SAMLConstants.SAML20ALG_NS) + dm.setElementLocalName(AlgorithmDigestMethod.DEFAULT_ELEMENT_LOCAL_NAME) + dm.setNamespacePrefix(SAMLConstants.SAML20ALG_PREFIX) + dm.setAlgorithm(algorithm) + return dm + } + + private SignatureDigestMethod getSignatureDigestMethod(String algorithm) { + SignatureDigestMethod dm = new SignatureDigestMethod() + dm.setNamespaceURI(SignatureConstants.XMLSIG_NS) + dm.setElementLocalName(SignatureDigestMethod.DEFAULT_ELEMENT_LOCAL_NAME) + dm.setNamespacePrefix(SignatureConstants.XMLSIG_PREFIX) + dm.setAlgorithm(algorithm) + return dm + } + static genXmlSnippet(MarkupBuilder xml, Closure xmlNodeGenerator) { xml.MetadataProvider('id': 'ShibbolethMetadata', 'xmlns': 'urn:mace:shibboleth:2.0:metadata', diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestHelpers.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestHelpers.groovy index f50263663..3a21080bb 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestHelpers.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestHelpers.groovy @@ -3,6 +3,8 @@ package edu.internet2.tier.shibboleth.admin.ui.util import edu.internet2.tier.shibboleth.admin.ui.security.model.User import groovy.xml.XmlUtil import junit.framework.Assert +import org.w3c.dom.Node + import javax.xml.transform.Source; import javax.xml.transform.Transformer import javax.xml.transform.TransformerException @@ -50,6 +52,19 @@ class TestHelpers { Assert.assertFalse(myDiff.toString(), myDiff.hasDifferences()); } + static void generatedXmlIsTheSameAsExpectedXml(String expectedXmlResource, Node generatedXml) { + def Builder builder = Input.fromDocument(generatedXml) + def Source source = builder.build() + def myDiff = DiffBuilder.compare(Input.fromStream(TestHelpers.getResourceAsStream(expectedXmlResource))) + .withTest(builder) + .withAttributeFilter({attribute -> !attribute.name.equals("sourceDirectory")}) + .ignoreComments() + .ignoreWhitespace() + .build() + System.out.println("@@@ \n" + getString(source) + "\n") + Assert.assertFalse(myDiff.toString(), myDiff.hasDifferences()); + } + public static String getString(DOMSource domSource) throws TransformerException { StringWriter writer = new StringWriter(); StreamResult result = new StreamResult(writer); @@ -67,4 +82,4 @@ class TestHelpers { def user = new User(username: username, role: rolename) Optional.of(user) } -} +} \ No newline at end of file diff --git a/backend/src/test/resources/conf/2268-complex.xml b/backend/src/test/resources/conf/2268-complex.xml new file mode 100644 index 000000000..cb4615a40 --- /dev/null +++ b/backend/src/test/resources/conf/2268-complex.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + https://sp2.example.org + + \ No newline at end of file diff --git a/backend/src/test/resources/conf/2268-simple.xml b/backend/src/test/resources/conf/2268-simple.xml index f9b0ea14a..e4365da17 100644 --- a/backend/src/test/resources/conf/2268-simple.xml +++ b/backend/src/test/resources/conf/2268-simple.xml @@ -1,12 +1,24 @@ - - - + + + + + https://broken.example.org/sp https://also-broken.example.org/sp diff --git a/backend/src/test/resources/jpa-saml2-metadata-algorithm-config.xml b/backend/src/test/resources/jpa-saml2-metadata-algorithm-config.xml new file mode 100644 index 000000000..c37c788c1 --- /dev/null +++ b/backend/src/test/resources/jpa-saml2-metadata-algorithm-config.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/backend/src/test/resources/jpa-saml2-metadata-ds-config.xml b/backend/src/test/resources/jpa-saml2-metadata-ds-config.xml new file mode 100644 index 000000000..3a0eed8f0 --- /dev/null +++ b/backend/src/test/resources/jpa-saml2-metadata-ds-config.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 9269aca76729e5cb8482403cd78e86dd030d474f Mon Sep 17 00:00:00 2001 From: chasegawa Date: Mon, 25 Jul 2022 13:29:48 -0700 Subject: [PATCH 33/88] RELEASE 1.11.0 Merging master to branch to fix conflicts --- build.gradle | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/build.gradle b/build.gradle index 505350c6f..518a7baa6 100644 --- a/build.gradle +++ b/build.gradle @@ -28,15 +28,4 @@ release { } afterReleaseBuild.dependsOn project.getTasksByName('githubRelease', false) -afterReleaseBuild.dependsOn project.getTasksByName('dockerTagsPush', true) - -// force log4j version -allprojects { - configurations.all { - resolutionStrategy.eachDependency { d -> - if (d.requested.group == 'org.apache.logging.log4j') { - d.useVersion project.'log4j.version' - } - } - } -} \ No newline at end of file +afterReleaseBuild.dependsOn project.getTasksByName('dockerTagsPush', true) \ No newline at end of file From 0680b9b2f640ac9ad1a119886f651e2fdfce12bb Mon Sep 17 00:00:00 2001 From: chasegawa Date: Mon, 25 Jul 2022 13:51:45 -0700 Subject: [PATCH 34/88] RELEASE 1.11.0 gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 0848cc3ed..b298de799 100644 --- a/.gitignore +++ b/.gitignore @@ -412,3 +412,6 @@ beacon/spring/out # macOS jenv .java-version +/a.xml +/application.yml +/backend/src/test/resources/conf/deletem.xml From 2db56a6b6275a7fb0d1827a3ad68c6684234d290 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Mon, 25 Jul 2022 14:01:23 -0700 Subject: [PATCH 35/88] [Gradle Release Plugin] - pre tag commit: 'y'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index f891afd02..82d6905dc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ name=shibui group=edu.internet2.tier.shibboleth.admin.ui -version=1.11.0-SNAPSHOT +version=y ### library versions ### commonsCollections4Version=4.4 From c36c60ae6cd8f371bd5ac31deb62652f8e33074b Mon Sep 17 00:00:00 2001 From: chasegawa Date: Mon, 25 Jul 2022 14:15:35 -0700 Subject: [PATCH 36/88] NOJIRA removing docker tasks related to master from Jenkinsfile --- .gitignore | 3 +++ Jenkinsfile | 28 +--------------------------- 2 files changed, 4 insertions(+), 27 deletions(-) diff --git a/.gitignore b/.gitignore index 0848cc3ed..b298de799 100644 --- a/.gitignore +++ b/.gitignore @@ -412,3 +412,6 @@ beacon/spring/out # macOS jenv .java-version +/a.xml +/application.yml +/backend/src/test/resources/conf/deletem.xml diff --git a/Jenkinsfile b/Jenkinsfile index 3ae5f4595..60f82aca1 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -16,32 +16,6 @@ pipeline { } } } - - stage('Build Docker images') { - when { - expression { - return GIT_BRANCH in ['master'] - } - } - steps { - sh '''./gradlew docker -x test - ''' - } - } - - stage('Deploy') { - when { - expression { - return GIT_BRANCH in ['master'] - } - } - steps { - sh ''' - docker stop shibui || true && docker rm shibui || true - docker run -d --restart always --name shibui -p 8080:8080 -v /etc/shibui:/conf -v /etc/shibui/application.yml:/application.yml -m 2GB --memory-swap=4GB --entrypoint /usr/bin/java unicon/shibui:latest -Xmx1G -jar app.war - ''' - } - } } post { failure { @@ -54,4 +28,4 @@ pipeline { cleanWs() } } -} +} \ No newline at end of file From 996cdc8f1596c20b5794f3ab8e9152faed6f5ae5 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Mon, 25 Jul 2022 14:40:15 -0700 Subject: [PATCH 37/88] NOJIRA correcting version from faulty release --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 82d6905dc..f891afd02 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ name=shibui group=edu.internet2.tier.shibboleth.admin.ui -version=y +version=1.11.0-SNAPSHOT ### library versions ### commonsCollections4Version=4.4 From a9b7c193c7a083ef4934d220a481e8e346ca5563 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Mon, 25 Jul 2022 15:42:26 -0700 Subject: [PATCH 38/88] NOJIRA gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 0848cc3ed..b298de799 100644 --- a/.gitignore +++ b/.gitignore @@ -412,3 +412,6 @@ beacon/spring/out # macOS jenv .java-version +/a.xml +/application.yml +/backend/src/test/resources/conf/deletem.xml From 54b021319fa0096fc832b149f11da27f126ba96a Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Tue, 26 Jul 2022 10:24:01 -0400 Subject: [PATCH 39/88] SHIBUI-2188 Couple quick stability fixes. --- .../integration/resources/SHIBUI-1364-1.side | 31 +++++++++------ .../integration/resources/SHIBUI-1364-4.side | 21 +++------- .../integration/resources/SHIBUI-1732-3.side | 38 +++++++++---------- 3 files changed, 43 insertions(+), 47 deletions(-) diff --git a/backend/src/integration/resources/SHIBUI-1364-1.side b/backend/src/integration/resources/SHIBUI-1364-1.side index b1cb09526..8fe9da05e 100644 --- a/backend/src/integration/resources/SHIBUI-1364-1.side +++ b/backend/src/integration/resources/SHIBUI-1364-1.side @@ -2330,13 +2330,22 @@ ["xpath=//button[contains(.,'Compare Selected(2)')]", "xpath:innerText"] ], "value": "" + }, { + "id": "9ddfc4d9-0fbd-44f2-8584-4d7fcb6d0c6b", + "comment": "", + "command": "waitForElementEditable", + "target": "css=#filters > div:nth-child(3) > div:nth-child(2) > div > button", + "targets": [ + ["css=.d-flex:nth-child(3) > .border-primary:nth-child(2) .svg-inline--fa", "css:finder"] + ], + "value": "30000" }, { "id": "2ff5a597-9fe0-46b4-9ca5-63123ddb3cef", "comment": "", "command": "click", - "target": "xpath=//section/div/div/div[4]/div[2]/div/button", + "target": "css=#filters > div:nth-child(3) > div:nth-child(2) > div > button", "targets": [ - ["css=.border-primary:nth-child(2) .fa-square", "css:finder"] + ["css=.d-flex:nth-child(3) > .border-primary:nth-child(2) .svg-inline--fa", "css:finder"] ], "value": "" }, { @@ -2356,23 +2365,23 @@ "id": "d7b5550d-1db8-4fa5-800f-fde753413c13", "comment": "", "command": "assertText", - "target": "css=.mb-4:nth-child(8) .p-2 > div > div:nth-child(1) .d-block:nth-child(2)", + "target": "css=.bg-diff > .d-block:nth-child(2)", "targets": [ - ["css=.mb-4:nth-child(8) .p-2 > div > div:nth-child(1) .d-block:nth-child(2)", "css:finder"], - ["xpath=//div[@id='root']/div/main/div/section/div/div/section[5]/div/div[2]/div[2]/div/div/span[2]", "xpath:idRelative"], - ["xpath=//section[5]/div/div[2]/div[2]/div/div/span[2]", "xpath:position"], - ["xpath=//span[contains(.,'Entity Attributes Filter')]", "xpath:innerText"] + ["css=.bg-diff > .d-block:nth-child(2)", "css:finder"], + ["xpath=//div[@id='filters']/section/div/div[2]/div[2]/div/div/span[2]", "xpath:idRelative"], + ["xpath=//div[2]/section/div/div[2]/div[2]/div/div/span[2]", "xpath:position"], + ["xpath=//span[contains(.,'Entity Attributes Filter Version 2')]", "xpath:innerText"] ], "value": "Entity Attributes Filter Version 2" }, { "id": "ad797f09-746e-4778-954e-6f92ac5934ea", "comment": "", "command": "assertText", - "target": "css=.mb-4:nth-child(8) .p-2 > div > div:nth-child(1) .d-block:nth-child(3)", + "target": "css=.bg-diff > .d-block:nth-child(3)", "targets": [ - ["css=.mb-4:nth-child(8) .p-2 > div > div:nth-child(1) .d-block:nth-child(3)", "css:finder"], - ["xpath=//div[@id='root']/div/main/div/section/div/div/section[5]/div/div[2]/div[2]/div/div/span[3]", "xpath:idRelative"], - ["xpath=//section[5]/div/div[2]/div[2]/div/div/span[3]", "xpath:position"] + ["css=.bg-diff > .d-block:nth-child(3)", "css:finder"], + ["xpath=//div[@id='filters']/section/div/div[2]/div[2]/div/div/span[3]", "xpath:idRelative"], + ["xpath=//div[2]/section/div/div[2]/div[2]/div/div/span[3]", "xpath:position"] ], "value": "Entity Attributes Filter" }, { diff --git a/backend/src/integration/resources/SHIBUI-1364-4.side b/backend/src/integration/resources/SHIBUI-1364-4.side index 8f5192665..3384d27ea 100644 --- a/backend/src/integration/resources/SHIBUI-1364-4.side +++ b/backend/src/integration/resources/SHIBUI-1364-4.side @@ -1417,23 +1417,14 @@ ["xpath=//input", "xpath:position"] ], "value": "" - }, { - "id": "e83dc2da-ad95-4e50-b969-57721eb8f1dc", - "comment": "", - "command": "click", - "target": "css=.d-flex:nth-child(5) > .border-primary:nth-child(2) .svg-inline--fa", - "targets": [ - ["css=.d-flex:nth-child(5) > .border-primary:nth-child(2) .svg-inline--fa", "css:finder"] - ], - "value": "" }, { "id": "c2102a31-6e18-4d6c-8146-e23459403b65", "comment": "", "command": "assertText", - "target": "css=.border-primary:nth-child(2) > .bg-primary-light .mb-0:nth-child(1)", + "target": "css=.d-flex:nth-child(3) > .border-primary:nth-child(2) .mb-0:nth-child(1)", "targets": [ - ["css=.border-primary:nth-child(2) > .bg-primary-light .mb-0:nth-child(1)", "css:finder"], - ["xpath=//div[@id='root']/div/main/div/section/div/div/div[4]/div[2]/div/div/p", "xpath:idRelative"], + ["css=.d-flex:nth-child(3) > .border-primary:nth-child(2) .mb-0:nth-child(1)", "css:finder"], + ["xpath=//div[@id='filters']/div[3]/div[2]/div/div/p", "xpath:idRelative"], ["xpath=//p", "xpath:position"], ["xpath=//p[contains(.,'Entity Attributes Filter V2')]", "xpath:innerText"] ], @@ -1442,10 +1433,10 @@ "id": "cac6c125-c81b-40af-ae21-2b717df9511e", "comment": "", "command": "assertText", - "target": "css=.border-primary:nth-child(3) > .bg-primary-light .mb-0:nth-child(1)", + "target": "css=.d-flex:nth-child(3) .bg-lighter .mb-0:nth-child(1)", "targets": [ - ["css=.border-primary:nth-child(3) > .bg-primary-light .mb-0:nth-child(1)", "css:finder"], - ["xpath=//div[@id='root']/div/main/div/section/div/div/div[4]/div[3]/div/div/p", "xpath:idRelative"], + ["css=.d-flex:nth-child(3) .bg-lighter .mb-0:nth-child(1)", "css:finder"], + ["xpath=//div[@id='filters']/div[3]/div[3]/div/div/p", "xpath:idRelative"], ["xpath=//div[3]/div/div/p", "xpath:position"] ], "value": "Entity Attributes Filter" diff --git a/backend/src/integration/resources/SHIBUI-1732-3.side b/backend/src/integration/resources/SHIBUI-1732-3.side index c7d0f9fd4..54573d88b 100644 --- a/backend/src/integration/resources/SHIBUI-1732-3.side +++ b/backend/src/integration/resources/SHIBUI-1732-3.side @@ -1325,13 +1325,9 @@ "id": "2dd7992f-ee99-45a3-ad85-20488c4bd4b1", "comment": "", "command": "click", - "target": "xpath=//section/div/div/div[4]/div[2]/div/button", + "target": "css=#filters > div:nth-child(3) > div:nth-child(2) > div > button", "targets": [ - ["css=.border-primary:nth-child(2) .mx-auto", "css:finder"], - ["xpath=(//button[@type='button'])[5]", "xpath:attributes"], - ["xpath=//div[@id='root']/div/main/div/section/div/div/div[4]/div[2]/div/button", "xpath:idRelative"], - ["xpath=//div[2]/div/button", "xpath:position"], - ["xpath=//button[contains(.,'Compare')]", "xpath:innerText"] + ["css=.border-primary:nth-child(2) .svg-inline--fa", "css:finder"] ], "value": "" }, { @@ -1553,21 +1549,21 @@ ["xpath=//ul[2]/li[2]/span", "xpath:position"] ], "value": "bar" - },{ - "id": "4ec2c493-85e4-403b-9b09-031c5728f498", - "comment": "", - "command": "open", - "target": "/api/heheheheheheheWipeout", - "targets": [], - "value": "" - }, { - "id": "e074980a-8f21-4c22-8412-c4b6fcdcd1a4", - "comment": "", - "command": "assertText", - "target": "css=body", - "targets": [], - "value": "yes, you did it" - }] + }, { + "id": "4ec2c493-85e4-403b-9b09-031c5728f498", + "comment": "", + "command": "open", + "target": "/api/heheheheheheheWipeout", + "targets": [], + "value": "" + }, { + "id": "e074980a-8f21-4c22-8412-c4b6fcdcd1a4", + "comment": "", + "command": "assertText", + "target": "css=body", + "targets": [], + "value": "yes, you did it" + }] }], "suites": [{ "id": "575d414c-556d-45f7-b2f2-c9971ad51348", From dcfeae0cf874c81d1677571f8cc48778aabd66ef Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Wed, 27 Jul 2022 10:06:31 -0700 Subject: [PATCH 40/88] Consolidated messages files Former-commit-id: e318e00840321dc6e42c010ef097d51899b985c7 --- .../main/resources/i18n/messages.properties | 23 +- .../resources/i18n/messages_en.properties | 566 ------------------ 2 files changed, 18 insertions(+), 571 deletions(-) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index d5202280e..a9a0560be 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -216,7 +216,7 @@ label.select-protocol=Select Protocol label.nameid-format=NameID Format label.nameid-formats=NameID Formats label.name-and-entity-id=Name and Entity ID -label.organization-information=SP/Organization Information +label.organization-information=Organization Information label.contact-information=Contact Information label.given-name=Given Name label.contact-type=Contact Type @@ -282,7 +282,7 @@ label.add-a-new-metadata-source=Add a new metadata source - Finish Summary label.name-and-entityid=Name and Entity ID. label.finish-summary-validation=Finished! label.select-entity-id-to-copy=Select the Entity ID to copy -label.metadata-source-name-dashboard-display-only=Metadata Source Name (Dashboard Display Only) +label.metadata-source-name-dashboard-display-only=Service Provider Name (Dashboard Display Only) label.new-entity-id=New Entity ID label.sections-to-copy=Sections to Copy? label.add-a-new-metadata-resolver=Add a new metadata source @@ -417,6 +417,7 @@ label.dynamic-attributes=Dynamic Attributes label.metadata-filter-plugins=Metadata Filter Plugins label.advanced-settings=Advanced Settings label.edit-metadata-provider=Edit Metadata Provider +label.edit-metadata-source=Edit Metadata Source label.http-settings-advanced=Http Settings (Advanced) label.metadata-ui=User Interface / MDUI Information @@ -439,6 +440,7 @@ label.attribute-eduPersonUniqueId=eduPersonUniqueId label.attribute-employeeNumber=employeeNumber label.force-authn=Force AuthN +label.dynamic-attributes=Dynamic Attributes label.min-cache-duration=Min Cache Duration label.max-cache-duration=Max Cache Duration label.max-idle-entity-data=Max Idle Entity Data @@ -466,14 +468,20 @@ label.nameid-formats-type=NameID Type label.select-filter-type=Select Filter Type label.admin=Admin +label.action-required=Action Required +label.user-access-request=User Access Request label.user-maintenance=User Maintenance label.user-id=UserId label.email=Email +label.role=Role label.delete=Delete? - -label.title=Title +label.delete-request=Delete Request +label.enable=Enable +label.disable=Disable label.enabled=Enabled label.disabled=Disabled +label.enable-metadata-sources=Enable Metadata Sources +label.title=Title label.author=Author label.creation-date=Creation Date label.order=Order @@ -543,6 +551,7 @@ message.uri-valid-format=URI must be valid format. message.id-unique=ID must be unique. message.name-unique=Service provider name must be unique. message.array-items-must-be-unique=Items in list must be unique. +message.real-number=Optional. If using a value, must be a real number between 0-1. message.valid-duration=Must be a valid duration. message.valid-name=No special characters or whitespace allowed. message.required=Missing required property. @@ -592,7 +601,9 @@ message.database-constraint=There was a database constraint problem processing t message.no-filters=No Filters message.no-filters-added=No filters have been added to this Metadata Provider - +message.user-request-received-title=User request received +message.user-request-received-body=Your request has been received and is being reviewed. You will be notified with access status. +message.filter-fail=A server error occured, and the filter failed to save. message.create-new-version-from-version=Create New Version from Previous Settings message.restoring-this-version-will-copy=Restoring this version will copy the Version ({ date }) configuration and create a new Version from the selected version settings. You can then edit the configuration before saving the new version. @@ -628,6 +639,8 @@ tooltip.certificate-name=Certificate Name tooltip.certificate-type=Certificate Type tooltip.certificate=Certificate tooltip.logout-endpoints=Logout Endpoints +tooltip.logout-endpoints-url=Logout Endpoints Url +tooltip.logout-endpoints-binding-type=Logout Endpoints Binding Type tooltip.url=Logout Endpoints Url tooltip.binding-type=Logout Endpoints Binding Type tooltip.mdui-display-name=Typically, the IdP Display Name field will be presented on IdP discovery service interfaces. diff --git a/backend/src/main/resources/i18n/messages_en.properties b/backend/src/main/resources/i18n/messages_en.properties index ca93cdbb3..e69de29bb 100644 --- a/backend/src/main/resources/i18n/messages_en.properties +++ b/backend/src/main/resources/i18n/messages_en.properties @@ -1,566 +0,0 @@ -# Fill this file with key/value pairs, as follows: -# -# some.test.message=This is a test message. -# -# Then, create a copy using the name of the language code: -# -# messages_.properties -# -# Do this for each language we want to support. -# Ideally, all messages should exist for each language. - -action.dashboard=Dashboard -action.logout=Logout -action.add=Add -action.add-new=Add New -action.add-new-provider=Add a new metadata provider -action.add-new-source=Add a new metadata source -action.clear=Clear -action.delete=Delete -action.remove=Remove -action.save=Save -action.toggle=Toggle -action.add-contact=Add Contact -action.add-contacts=Add Contacts -action.use-mine=Use My Changes -action.use-theirs=Use Their Changes -action.discard-changes=Discard Changes -action.add-endpoint=Add Endpoint -action.add-nameid-format=Add NameID Format -action.add-certificate=Add Certificate -action.add-entity-id=Add Entity ID -action.download-file=Download File -action.cancel=Cancel -action.search=Search -action.select-id=Select ID -action.finish-later=Finish Later -action.back=Back -action.next=Next -action.create=Create -action.copy=Copy -action.choose-file=Choose File -action.search-by=Search By -action.preview=Preview -action.select-metadata-filter-type=Select a metadata filter type -action.add-authentication-method=Add Authentication Method -action.move-up=Move Up -action.move-down=Move Down -action.edit=Edit -action.add-filter=Add Filter -action.manage-filters=Manage Filters - -value.enabled=Enabled -value.disabled=Disabled -value.none=None -value.file=File -value.memory=Memory -value.true=true -value.false=false -value.regex=Regex -value.script=Script -value.entity-id=Entity ID - -value.support=Support -value.technical=Technical -value.administrative=Administrative -value.other=Other - -value.signing=Signing -value.encryption=Encryption -value.both=Both - -value.entity=Entity -value.condition-ref=ConditionRef -value.condition-script=ConditionScript - -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 -value.dynamic-http-metadata-provider=DynamicHttpMetadataProvider -value.local-dynamic-metadata-provider=LocalDynamicMetadataProvider - -value.md-query-protocol=MetadataQueryProtocol -value.template=Template - -brand.header.title=Source Management -brand.logo-link-label=Shibboleth -brand.logo-link-description=Link to Shibboleth Website -brand.logo-alt=Shibboleth Logo - Click to be directed to www.shibboleth.net -brand.footer.text=Links to Shibboleth resources: -brand.footer.links-label-1=Home Page -brand.footer.links-desc-1=Shibboleth.net open-source community home page -brand.footer.links-label-2=Wiki -brand.footer.links-desc-2=Shibboleth.net open-source community wiki -brand.footer.links-label-3=Issue Tracker -brand.footer.links-desc-3=Shibboleth.net open-source community issue tracker -brand.footer.links-label-4=Mailing List -brand.footer.links-desc-4=Shibboleth.net open-source community mailing list -brand.footer.copyright=Copyright \u00A9 {year} Internet2 - -brand.in-partnership-with=In partnership with -brand.and=and - -heading.shibboleth=Shibboleth - -label.metadata-source=Metadata Source -label.metadata-sources=Metadata Sources -label.metadata-provider=Metadata Provider -label.metadata-providers=Metadata Providers -label.source-management=Source Management -label.search-files=Search Files -label.service-provider-entity-id=Service Provider Entity ID -label.service-provider-name-dashboard-display-only=Service Provider Name (Dashboard Display Only) -label.enable-this-service=Enable this service? -label.organization-name=Organization Name -label.organization-display-name=Organization Display Name -label.organization-url=Organization URL -label.name=Name -label.type=Type -label.email-address=Email Address -label.assertion-consumer-service-endpoints=Assertion Consumer Service Endpoints -label.my-changes=My Changes -label.their-changes=Their Changes -label.new-endpoint=New Endpoint -label.select-binding=Select Binding Type -label.mark-as-default=Mark as Default -label.attribute-name=Attribute Name -label.yes=Yes -label.check-all-attributes=Check All Attributes -label.clear-all-attributes=Clear All Attributes -label.protocol-support-enumeration=Protocol Support Enumeration -label.select-protocol=Select Protocol -label.nameid-format=NameID Format -label.nameid-formats=NameID Formats -label.name-and-entity-id=Name and Entity ID -label.organization-information=Organization Information -label.contact-information=Contact Information -label.given-name=Given Name -label.contact-type=Contact Type -label.user-interface-mdui-infromation=User Interface / MDUI Information -label.display-name=Display Name -label.information-url=Information URL -label.description=Description -label.privacy-statement=Privacy Statement URL -label.logo-url=Logo URL -label.logo-width=Logo Width -label.logo-height=Logo Height -label.sp-sso-descriptor-information=SP SSO Descriptor Information -label.logout-endpoints=Logout Endpoints -label.binding-types=Binding Type -label.security-information=Security Information -label.is-there-a-x509-certificate=Is there a X509 Certificate? -label.authentication-requests-signed=Authentication Requests Signed? -label.want-assertions-signed=Want Assertions Signed? -label.x509-certificates=X509 Certificates -label.certificate-name-display-only=Certificate Name (Display Only) -label.certificate=Certificate -label.assertion-consumer-services=Assertion Consumer Services -label.assertion-consumer-service-location=Location -label.assertion-consumer-service-endpoint=Assertion Consumer Service Endpoints -label.default=(default) -label.assertion-consumer-service-location-binding=Location Binding -label.relying-party-overrides=Relying Party Overrides -label.sign-the-assertion=Sign the Assertion? -label.turn-off-encryption-of-response=Turn off Encryption of Response? -label.use-sha1-signing-algorithm=Use SHA1 Signing Algorithm? -label.ignore-any-sp-requested-authentication-method=Ignore any SP-Requested Authentication Method? -label.omit-not-before-condition=Omit Not Before Condition? -label.responderid=ResponderID -label.attribute-release=Attribute Release -label.true=True -label.false=False -label.no=No -label.new-cert=New Certificate -label.url=URL -label.privacy-statement-url=Privacy Statement URL -label.contact-name=Contact Name -label.select-contact-type=Select Contact Type -label.contact-email-address=Contact Email Address -label.dont-sign-the-response=Don\u0027t Sign the Response -label.nameid-format-to-send=NameID Format to Send -label.authentication-methods-to-use=Authentication Methods to Use -label.auth-method-indexed=Authentication Method -label.preview-provider=Preview XML -label.search-entity-id=Search Entity Id -label.edit-filter=Edit Filter -label.min-4-chars=Minimum 4 characters. -label.new-filter=New Filter -label.service-provider=Metadata Source Name: -label.created-date=Created Date: -label.service-entity-id=Metadata Source Entity ID: -label.service-provider-status=Metadata Source Status: -label.current-metadata-sources=Current Metadata Sources -label.current-metadata-providers=Current Metadata Providers -label.add-a-new-metadata-provider=Add a new metadata provider -label.service-resolver-name-dashboard-display-only=Service Provider Name (Dashboard Display Only) -label.service-resolver-entity-id=Service Provider Entity ID -label.add-a-new-metadata-source=Add a new metadata source - Finish Summary -label.name-and-entityid=Name and Entity ID. -label.finish-summary-validation=Finished! -label.select-entity-id-to-copy=Select the Entity ID to copy -label.metadata-source-name-dashboard-display-only=Service Provider Name (Dashboard Display Only) -label.new-entity-id=New Entity ID -label.sections-to-copy=Sections to Copy? -label.add-a-new-metadata-resolver=Add a new metadata source -label.how-are-you-adding-the-metadata-information=How are you adding the metadata information? -label.upload-url=Upload/URL -label.or=or -label.name-and-upload-url=Name and Upload Url -label.service-resolver-file=Select Provider Metadata File -label.service-resolver-metadata-url=Service Provider Metadata URL -label.search-criteria-by=Search Criteria by { displayType } -label.entity-ids-added=Entity Ids Added -label.ui-mdui-info=User Interface / MDUI Information -label.sp-sso-descriptor-info=SP SSO Descriptor Information -label.security-info=Security Information -label.sp-org-info=SP/Organization Information -label.finished=Finished! -label.signing=Signing -label.encryption=Encryption -label.both=Both -label.org-info=Organization Information -label.security-descriptor-info=Security Descriptor Information -label.entity-id=Entity ID -label.service-provider-name=Service Provider Name -label.organization=Organization -label.contacts=Contacts -label.contact=Contact -label.mdui=MDUI Information -label.service-provider-sso-descriptor=Service Provider Sso Descriptor -label.service-enabled=Service Enabled -label.filter-name=Filter Name -label.filter-enabled=Filter Enabled -label.filter-target=FilterTarget -label.filter-type=Filter Type -label.value=Value -label.binding-type=Binding Type -label.sign-assertion=Sign Assertions -label.dont-sign-response=Don\u0027t Sign Response -label.turn-off-encryption=Turn off encryption -label.use-sha=Use Sha -label.ignore-authentication-method=Ignore Authentication Method -label.omit-not-before=Omit Not Before -label.responder-id=Responder ID -label.name-id-formats=Name ID Formats -label.name-id-format= Name ID Format -label.authentication-methods=Authentication Methods -label.authentication-method=Authentication Method -label.x509-certificate-available=x509 Certificate Available -label.protocol-support-enum=Protocol Support Enumeration -label.binding=Binding -label.location-url=Location URL -label.make-default=Make Default -label.metadata-provider-name-dashboard-display-only=Metadata Provider Name (Dashboard Display Only) -label.default-authentication-methods=Default Authentication Method(s) -label.new-of-type=New { type } - -label.metadata-filter-name=Metadata Filter Name (Dashboard Display Only) -label.filter-enable=Enable this Filter? -label.search-criteria=Search Criteria -label.metadata-filter=Metadata Filter -label.metadata-filter-type=Metadata Filter Type - -label.http-connection-attributes=HTTP Connection Attributes -label.http-security-attributes=HTTP Security Attributes -label.http-proxy-attributes=HTTP Proxy Attributes -label.http-caching-attributes=HTTP Caching Attributes - -label.connection-request-timeout=Connection Request Timeout -label.connection-timeout=Connection Timeout -label.socket-timeout=Socket Timeout -label.disregard-tls-cert=Disregard TLS Certificate? -label.proxy-host=Proxy Host -label.proxy-port=Proxy Port -label.proxy-user=Proxy User -label.proxy-password=Proxy Password -label.http-caching=HTTP Caching? -label.select-caching-type=Select Caching Type -label.http-caching-directory=HTTP Cache Directory -label.http-max-cache-entries=HTTP Max Cache Entries -label.max-cache-entry-size=HTTP Max Cache Entry Size -label.duration=Duration -label.real-number=Real Number (between 0.0 and 1.0) -label.min-refresh-delay=Min Refresh Delay -label.max-refresh-delay=Max Refresh Delay -label.refresh-delay-factor=Refresh Delay Factor -label.resolve-via-predicates-only=Resolve Via Predicates Only? -label.expiration-warning-threshold=Expiration Warning Threshold - -label.satisfy-any-predicates=Satisfy Any Predicates? -label.use-default-predicate-reg=Use Default Predicate Registry? -label.fail-fast-init=Fail Fast Initialization? -label.require-valid-metadata=Require Valid Metadata? -label.backup-file-init-refresh-delay=Backup File Init Next Refresh Delay -label.backing-file=Backing File -label.init-from-backup=Initialize From Backup File? -label.metadata-url=Metadata URL -label.xml-id=ID -label.enable-service=Enable this service? -label.metadata-provider-type=Metadata Provider Type -label.metadata-provider-name=Metadata Provider Name -label.select-metadata-type=Select a metadata provider type -label.metadata-provider-status=Metadata Provider Status -label.enable-provider-upon-saving=Enable Metadata Provider? -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 -label.signature-validation-filter=Signature Validation Filter -label.require-signed-root=Require Signed Root -label.certificate-file=Certificate File -label.entity-role-whitelist=Entity Role Whitelist Filter -label.retained-roles=Retained Roles -label.remove-roleless-entity-descriptors=Remove Roleless Entity Descriptors? -label.remove-empty-entities-descriptors=Remove Empty Entities Descriptors? - -label.select-metadata-provider-type=Select Metadata Provider Type -label.filter-list=Filter List -label.common-attributes=Common Attributes -label.reloading-attributes=Reloading Attributes -label.dynamic-attributes=Dynamic Attributes -label.metadata-filter-plugins=Metadata Filter Plugins -label.advanced-settings=Advanced Settings -label.edit-metadata-provider=Edit Metadata Provider -label.edit-metadata-source=Edit Metadata Source -label.http-settings-advanced=Http Settings (Advanced) - -label.metadata-ui=User Interface / MDUI Information -label.descriptor-info=SP SSO Descriptor Information -label.key-info=Security Information -label.assertion=Assertion Consumer Service -label.relying-party=Relying Party Overrides - -label.attribute-eduPersonPrincipalName=eduPersonPrincipalName (EPPN) -label.attribute-uid=uid -label.attribute-mail=mail -label.attribute-surname=surname -label.attribute-givenName=givenName -label.attribute-eduPersonAffiliation=eduPersonAffiliation -label.attribute-eduPersonScopedAffiliation=eduPersonScopedAffiliation -label.attribute-eduPersonPrimaryAffiliation=eduPersonPrimaryAffiliation -label.attribute-eduPersonEntitlement=eduPersonEntitlement -label.attribute-eduPersonAssurance=eduPersonAssurance -label.attribute-eduPersonUniqueId=eduPersonUniqueId -label.attribute-employeeNumber=employeeNumber -label.force-authn=Force AuthN - -label.dynamic-attributes=Dynamic Attributes -label.min-cache-duration=Min Cache Duration -label.max-cache-duration=Max Cache Duration -label.max-idle-entity-data=Max Idle Entity Data -label.cleanup-task-interval=Cleanup Task Interval -label.persistent-cache-manager-directory=Persistent Cache Manager Directory -label.initialize-from-persistent-cache-in-background=Initialize from Persistent Cache in Background? -label.background-init-from-cache-delay=Background Initialization from Cache Delay -label.source-directory=Source Directory -label.remove-idle-entity-data=Remove Idle Entity Data? -label.do-resolver-initialization=Initialize -label.file-doesnt-exist=The file specified in the resolver does not exist on the file system. Therefore, the resolver cannot be initialized. - -label.md-request-type=Metadata Request URL Construction Type -label.md-request-value=Metadata Request URL Construction Value -label.transform-ref=Transform Ref -label.encoding-style=Encoding Style -label.velocity-engine=Velocity Engine -label.match=Match - -label.remove-existing-formats=Remove Existing Formats? -label.nameid-formats-format=NameID Format -label.nameid-formats-value=NameID Value -label.nameid-formats-type=NameID Type - -label.select-filter-type=Select Filter Type - -label.admin=Admin -label.action-required=Action Required -label.user-access-request=User Access Request -label.user-maintenance=User Maintenance -label.user-id=UserId -label.email=Email -label.role=Role -label.delete=Delete? -label.delete-request=Delete Request - -label.enable=Enable -label.disable=Disable -label.enable-metadata-sources=Enable Metadata Sources - -label.source=Metadata Source -label.provider=Metadata Provider - -message.delete-user-title=Delete User? -message.delete-user-body=You are requesting to delete a user. If you complete this process the user will be removed. This cannot be undone. Do you wish to continue? - -message.must-be-unique=Must be unique. -message.name-must-be-unique=Name must be unique. -message.uri-valid-format=URI must be valid format. -message.id-unique=ID must be unique. -message.array-items-must-be-unique=Items in list must be unique. -message.real-number=Optional. If using a value, must be a real number between 0-1. - -message.org-name-required=Organization Name is required. -message.org-displayName-required=Organization Name is required. -message.org-url-required=Organization Name is required. -message.org-incomplete=These three fields must all be entered if any single field has a value. - -message.type-required=Missing required property: Type -message.match-required=Missing required property: Match -message.value-required=Missing required property: Value -message.required=Missing required property. - -message.conflict=Conflict -message.data-version-contention=Data Version Contention -message.contention-new-version=A newer version of this metadata source has been saved. Below are a list of changes. You can use your changes or their changes. -message.organization-feedback=These three fields must all be entered if any single field has a value. -message.valid-email=Must be a valid Email Address -message.valid-url=Must be a valid URL -message.must-be-valid-url=Must be a valid URL -message.must-be-integer=Must be an integer equal to or greater than 0 -message.delete-source-title=Delete Metadata Source? -message.delete-source-body=You are deleting a metadata source. This cannot be undone. Continue? -message.incomplete-form=Incomplete Form -message.delete-filter-title=Delete Metadata Filter? -message.delete-filter-body=You are deleting a metadata filter. This cannot be undone. Continue? -message.unsaved-dialog-title=Save your information? -message.unsaved-editor=You have not saved your changes. If you exit this screen, your changes will be lost. -message.editor-invalid=All forms must be valid before changes can be saved! -message.unsaved-source-1=You have not completed the wizard! Do you wish to save this information? You can finish the wizard later by clicking the \u0027Edit\u0027 -message.unsaved-source-2=icon on the dashboard. -message.service-resolver-name-required=Service Provider Name is required -message.entity-id-required=Entity ID is required -message.entity-id-must-be-unique=Entity ID must be unique -message.target-required=Entity ID to copy is required -message.file-upload-alert=Note: You can only import a file with a single entityID (EntityDescriptor element) in it. Anything more in that file will result in an error. -message.add-new-md-resolver=Add a new metadata source -message.wizard-status=Step { index } of { length } -message.entity-id-min-unique=You must add at least one entity id target and they must each be unique. -message.required-for-scripts=Required for Scripts -message.required-for-regex=Required for Regex -message.file-doesnt-exist=The requested file to be processed does not exist on the server. -message.database-constraint=There was a database constraint problem processing the request. Check the request to ensure that fields that must be unique are truly unique. - -message.user-request-received-title=User request received -message.user-request-received-body=Your request has been received and is being reviewed. You will be notified with access status. - -message.filter-fail=A server error occured, and the filter failed to save. - -tooltip.entity-id=Entity ID -tooltip.service-provider-name=Service Provider Name (Dashboard Display Only) -tooltip.force-authn=Disallows use (or reuse) of authentication results and login flows that don\u0027t provide a real-time proof of user presence in the login process -tooltip.service-provider-name-dashboard-display-only=Service Provider Name (Dashboard Display Only) -tooltip.service-provider-entity-id=Service Provider Entity ID -tooltip.organization-name=Organization Name -tooltip.organization-display-name=Organization Display Name -tooltip.organization-url=Organization URL -tooltip.name=Name -tooltip.type=Type -tooltip.email-address=Email Address -tooltip.assertion-consumer-service-location=Assertion Consumer Service Location -tooltip.assertion-consumer-service-location-binding=Assertion Consumer Service Location Binding -tooltip.mark-as-default=Mark as Default -tooltip.protocol-support-enumeration=Protocol Support Enumeration -tooltip.nameid-format=Content is name identifier format which is added to all the applicable roles of the entities which match any of the following or {{}}elements. -tooltip.enable-this-service-upon-saving=If checkbox is clicked, the metadata provider is enabled for integration with the IdP -tooltip.authentication-requests-signed=Authentication Requests Signed -tooltip.want-assertions-signed=Want Assertions Signed -tooltip.certificate-name=Certificate Name -tooltip.certificate-type=Certificate Type -tooltip.certificate=Certificate -tooltip.logout-endpoints-url=Logout Endpoints Url -tooltip.logout-endpoints-binding-type=Logout Endpoints Binding Type -tooltip.mdui-display-name=Typically, the IdP Display Name field will be presented on IdP discovery service interfaces. -tooltip.mdui-information-url=The IdP Information URL is a link to a comprehensive information page about the IdP. This page should expand on the content of the IdP Description field. -tooltip.mdui-description=The IdP Description is a brief description of the IdP service. On a well-designed discovery interface, the IdP Description will be presented to the user in addition to the IdP Display Name, and so the IdP Description helps disambiguate duplicate or similar IdP Display Names. -tooltip.mdui-privacy-statement-url=The IdP Privacy Statement URL is a link to the IdP\u0027s Privacy Statement. The content of the Privacy Statement should be targeted at end users. -tooltip.mdui-logo-url=The IdP Logo URL in metadata points to an image file on a remote server. A discovery service, for example, may rely on a visual cue (i.e., a logo) instead of or in addition to the IdP Display Name. -tooltip.mdui-logo-width=The logo should have a minimum width of 100 pixels -tooltip.mdui-logo-height=The logo should have a minimum height of 75 pixels and a maximum height of 150 pixels (or the application will scale it proportionally) -tooltip.contact-name=Contact Name -tooltip.contact-type=Contact Type -tooltip.contact-email=Contact Email -tooltip.sign-assertion=Sign Assertion -tooltip.dont-sign-response=Don\u0027t Sign Response -tooltip.turn-off-encryption=Turn Off Encryption of Response -tooltip.usa-sha-algorithm=Use SHA1 Signing Algorithm -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 -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 -tooltip.connection-request-timeout=The maximum amount of time to wait for a connection to be returned from the HTTP client\u0027s connection pool manager. Set to PT0S to disable. This attribute is incompatible with httpClientRef. -tooltip.connection-timeout=The maximum amount of time to wait to establish a connection with the remote server. Set to PT0S to disable. This attribute is incompatible with httpClientRef. -tooltip.socket-timeout=The maximum amount of time to wait between two consecutive packets while reading from the socket connected to the remote server. Set to PT0S to disable. This attribute is incompatible with httpClientRef. -tooltip.disregard-tls-cert=If true, no TLS certificate checking will take place over an HTTPS connection. This attribute is incompatible with httpClientRef. (Be careful with this setting, it is typically only used during testing. See the HttpClientConfiguration topic for more information.) -tooltip.proxy-host=The hostname of the HTTP proxy through which connections will be made. This attribute is incompatible with httpClientRef. -tooltip.proxy-port=The port of the HTTP proxy through which connections will be made. This attribute is incompatible with httpClientRef. -tooltip.proxy-user=The username used with the HTTP proxy through which connections will be made. This attribute is incompatible with httpClientRef. -tooltip.proxy-password=The password used with the HTTP proxy through which connections will be made. This attribute is incompatible with httpClientRef. -tooltip.http-caching=The type of low-level HTTP caching to perform. There are three choices: 'none' indicates the HTTP response is not cached by the client library, 'file' indicates the HTTP response is written to disk (but will not survive a restart), 'memory' indicates the HTTP response is stored in memory. This attribute is incompatible with httpClientRef and its value may not be specified as a bean property. Some metadata providers, most notably the reloading 'batch-oriented' providers, implement HTTP caching at a higher layer and tend to work best with httpCaching='none'. -tooltip.http-caching-directory=If httpCaching='file', this attribute specifies where retrieved files are to be cached. This attribute is incompatible with httpClientRef. -tooltip.http-max-cache-entries=The maximum number of responses written to cache. This attribute is incompatible with httpClientRef. -tooltip.max-cache-entry-size=The maximum response body size that may be cached, in bytes. This attribute is incompatible with httpClientRef. - -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=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. -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=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=If checkbox is clicked, the metadata provider is enabled for integration with the IdP - -tooltip.max-validity-interval=Defines the window within which the metadata is valid. -tooltip.require-signed-root=If true, this fails to load metadata with no signature on the root XML element. -tooltip.certificate-file=A path (on the local file system) to a certificate file whose key is used to verify the signature. Conflicts with trustEngineRef and both of the child elements. -tooltip.retained-roles=Note that property replacement cannot be used on this element. -tooltip.remove-roleless-entity-descriptors=Controls whether to keep entity descriptors that contain no roles. Note: If this attribute is set to false, the resulting output may not be schema-valid since an element must include at least one role descriptor. -tooltip.remove-empty-entities-descriptors=Controls whether to keep entities descriptors that contain no entity descriptors. Note: If this attribute is set to false, the resulting output may not be schema-valid since an element must include at least one child element, either an element or an element. - -tooltip.min-refresh-delay=Lower bound on the next refresh from the time calculated based on the metadata\u0027s expiration. Setting this to 0 will result in the default value being used. -tooltip.max-refresh-delay=Upper bound on the next refresh from the time calculated based on the metadata\u0027s expiration. -tooltip.refresh-delay-factor=A factor applied to the initially determined refresh time in order to determine the next refresh time (typically to ensure refresh takes place prior to the metadata\u0027s expiration). Attempts to refresh metadata will generally begin around the product of this number and the maximum refresh delay. -tooltip.resolve-via-predicates-only=Flag indicating whether resolution may be performed solely by applying predicates to the entire metadata collection, when an entityID input criterion is not supplied. -tooltip.expiration-warning-threshold=For each attempted metadata refresh (whether or not fresh metadata is obtained), if requireValidMetadata is true, and there is a validUntil XML attribute on the document root element, and the difference between validUntil and the current time is less than expirationWarningThreshold, the system logs a warning about the impending expiration. - -tooltip.filter-name=Filter Name -tooltip.enable-filter=Enable Filter? -tooltip.enable-service=Enable Service? - -tooltip.min-cache-duration=The minimum duration for which metadata will be cached before it is refreshed. -tooltip.max-cache-duration=The maximum duration for which metadata will be cached before it is refreshed. -tooltip.max-idle-entity-data=The maximum duration for which metadata will be allowed to be idle (no requests for it) before it is removed from the cache. -tooltip.cleanup-task-interval=The interval at which the internal cleanup task should run. This task performs background maintenance tasks, such as the removal of expired and idle metadata. -tooltip.persistent-cache-manager-directory=The optional manager for the persistent cache store for resolved metadata. On metadata provider initialization, data present in the persistent cache will be loaded to memory, effectively restoring the state of the provider as closely as possible to that which existed before the previous shutdown. Each individual cache entry will only be loaded if 1) the entry is still valid as determined by the internal provider logic, and 2) the entry passes the (optional) predicate supplied via initializationFromCachePredicateRef. -tooltip.initialize-from-persistent-cache-in-background=Flag indicating whether should initialize from the persistent cache in the background. Initializing from the cache in the background will improve IdP startup times. -tooltip.background-init-from-cache-delay=The delay after which to schedule the background initialization from the persistent cache when initializeFromPersistentCacheInBackground=true. - -tooltip.source-directory=Convenience mechanism for wiring a FilesystemLoadSaveManager, loading from the specified source directory in the local filesystem. This attribute will be ignored if sourceManagerRef is also specified. Either this attribute or sourceManagerRef is required. -tooltip.remove-idle-entity-data=Flag indicating whether idle metadata should be removed. - -tooltip.do-resolver-initialization=Initialize this resolver? In the case of Filesystem resolvers, this will cause the system to read the file and index the resolver. -tooltip.md-request-type=Options are 1) Metadata Query Protocol, 2) Regex. -tooltip.md-request-value=Content of the element. -tooltip.transform-ref=A reference to a transform function for the entityID. If used, the child element must be empty. -tooltip.encoding-style=Determines whether and how the entityID value will be URL encoded prior to replacement. Allowed values are: 1) "none" - no encoding is performed, 2) "form" - encoded using URL form parameter encoding (for query parameters), 3) "path" - encoded using URL path encoding, or 4) "fragment" - encoded using URL fragment encoding. The precise definition of these terms is defined in the documentation for the methods of the Guava library\u0027s UrlEscapers class. -tooltip.velocity-engine=This attribute may be used to specify the name of the Velocity engine defined within the application. -tooltip.match=A regular expression against which the entityID is evaluated. - -tooltip.remove-existing-formats=Whether to remove any existing formats from a role if any are added by the filter (unmodified roles will be untouched regardless of this setting) -tooltip.nameid-formats-format=Format -tooltip.nameid-formats-value=Value -tooltip.nameid-formats-type=Type \ No newline at end of file From f5a59a7b73a6014fddc1b16313d5ba3991993206 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Wed, 27 Jul 2022 12:39:22 -0700 Subject: [PATCH 41/88] Fixed admin route --- ui/src/app/dashboard/view/Dashboard.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ui/src/app/dashboard/view/Dashboard.js b/ui/src/app/dashboard/view/Dashboard.js index e5f145572..b1d058eaf 100644 --- a/ui/src/app/dashboard/view/Dashboard.js +++ b/ui/src/app/dashboard/view/Dashboard.js @@ -112,6 +112,9 @@ export function Dashboard () { } /> + + + } From 246d295758145a1c4a5aedfe038f0eaa77c850ef Mon Sep 17 00:00:00 2001 From: chasegawa Date: Wed, 27 Jul 2022 13:31:27 -0700 Subject: [PATCH 42/88] SHIBUI-2327 Adding missing libraries and needed marshalling configuration for using pac4j --- .../resources/modified-saml2-assertion-config.xml | 14 +++++++++++++- pac4j-module/build.gradle | 3 +++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/backend/src/main/resources/modified-saml2-assertion-config.xml b/backend/src/main/resources/modified-saml2-assertion-config.xml index 2f09fa77b..3349e4558 100644 --- a/backend/src/main/resources/modified-saml2-assertion-config.xml +++ b/backend/src/main/resources/modified-saml2-assertion-config.xml @@ -230,7 +230,19 @@ - + + + + + + + + + + + + + diff --git a/pac4j-module/build.gradle b/pac4j-module/build.gradle index 6a1295758..4080df12a 100644 --- a/pac4j-module/build.gradle +++ b/pac4j-module/build.gradle @@ -46,8 +46,11 @@ dependencies { exclude group: 'org.opensaml' exclude group: 'commons-collections' } + // But we do need this opensaml lib that wasn't provided + implementation "org.opensaml:opensaml-storage-impl:${project.'opensamlVersion'}" compile "org.apache.commons:commons-collections4:${project.'commonsCollections4Version'}" + testCompile project(':backend') testCompile "org.opensaml:opensaml-saml-api:${project.'opensamlVersion'}" From e0f0074f8ccfc66f469b1d0c6f7ecf8982eebff5 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Wed, 27 Jul 2022 15:01:09 -0700 Subject: [PATCH 43/88] Updated spinners Former-commit-id: 0b6d9d6dd551433b898a514754ee9408a3eb2968 --- ui/src/app/metadata/hoc/MetadataSchema.js | 13 +++++++++++-- ui/src/app/metadata/hoc/MetadataVersionsLoader.js | 2 +- ui/src/app/metadata/view/MetadataWizard.js | 6 ++++-- .../app/metadata/wizard/MetadataProviderWizard.js | 6 +++++- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/ui/src/app/metadata/hoc/MetadataSchema.js b/ui/src/app/metadata/hoc/MetadataSchema.js index 025e7a415..d2d257623 100644 --- a/ui/src/app/metadata/hoc/MetadataSchema.js +++ b/ui/src/app/metadata/hoc/MetadataSchema.js @@ -9,6 +9,7 @@ export const MetadataDefinitionContext = React.createContext(); export function MetadataSchema({ type, children, wizard = false }) { const definition = React.useMemo(() => wizard ? getWizard(type) : getDefinition(type), [type, wizard]); + const [loading, setLoading] = React.useState(false); const { get, response } = useFetch(``, { cachePolicy: 'no-cache' @@ -21,18 +22,20 @@ export function MetadataSchema({ type, children, wizard = false }) { if (response.ok) { setSchema(source); } + setLoading(false); } /*eslint-disable react-hooks/exhaustive-deps*/ React.useEffect(() => { setSchema(null); loadSchema(definition); + setLoading(true); }, [definition]); return ( {type && definition && schema && - + {children} } @@ -41,7 +44,13 @@ export function MetadataSchema({ type, children, wizard = false }) { } export function useMetadataSchemaContext () { - return React.useContext(MetadataSchemaContext); + const {schema} = React.useContext(MetadataSchemaContext); + return schema; +} + +export function useMetadataSchemaLoading () { + const {loading} = React.useContext(MetadataSchemaContext); + return loading; } export function useMetadataDefinitionContext() { diff --git a/ui/src/app/metadata/hoc/MetadataVersionsLoader.js b/ui/src/app/metadata/hoc/MetadataVersionsLoader.js index f552db8c4..d957903d9 100644 --- a/ui/src/app/metadata/hoc/MetadataVersionsLoader.js +++ b/ui/src/app/metadata/hoc/MetadataVersionsLoader.js @@ -52,8 +52,8 @@ export function MetadataVersionsLoader ({versions, children}) { return ( - {children(versions.map(v => list[v]).filter(v => !!v))} {loading &&
} + {children(versions.map(v => list[v]).filter(v => !!v))}
); } \ No newline at end of file diff --git a/ui/src/app/metadata/view/MetadataWizard.js b/ui/src/app/metadata/view/MetadataWizard.js index 8dc5a9d51..d48cc4330 100644 --- a/ui/src/app/metadata/view/MetadataWizard.js +++ b/ui/src/app/metadata/view/MetadataWizard.js @@ -58,11 +58,13 @@ export function MetadataWizard ({type, data, onCallback}) { /> {type === 'source' ? - + + + {loading &&
} +
: } - {loading &&
}
); diff --git a/ui/src/app/metadata/wizard/MetadataProviderWizard.js b/ui/src/app/metadata/wizard/MetadataProviderWizard.js index 7193c0573..72df681fd 100644 --- a/ui/src/app/metadata/wizard/MetadataProviderWizard.js +++ b/ui/src/app/metadata/wizard/MetadataProviderWizard.js @@ -2,7 +2,7 @@ import React from 'react'; import { WizardNav } from './WizardNav'; import { MetadataWizardForm } from './MetadataWizardForm'; import { setWizardIndexAction, useCurrentIndex, useIsLastPage, useWizardDispatcher } from './Wizard'; -import { useMetadataDefinitionContext, useMetadataDefinitionValidator, useMetadataSchemaContext } from '../hoc/MetadataSchema'; +import { useMetadataDefinitionContext, useMetadataDefinitionValidator, useMetadataSchemaContext, useMetadataSchemaLoading } from '../hoc/MetadataSchema'; import { checkChanges, useMetadataSchema } from '../hooks/schema'; import { useMetadataFormDispatcher, setFormDataAction, setFormErrorAction, useMetadataFormData, useMetadataFormErrors } from '../hoc/MetadataFormContext'; import { MetadataConfiguration } from '../component/MetadataConfiguration'; @@ -12,6 +12,7 @@ import { useMetadataProviders } from '../hooks/api'; import { removeNull } from '../../core/utility/remove_null'; import { useUserGroup } from '../../core/user/UserContext'; +import Spinner from '../../core/components/Spinner'; export function MetadataProviderWizard({onSave, loading, block}) { @@ -20,6 +21,7 @@ export function MetadataProviderWizard({onSave, loading, block}) { const definition = useMetadataDefinitionContext(); const schema = useMetadataSchemaContext(); + const schemaLoading = useMetadataSchemaLoading(); const processed = useMetadataSchema(definition, schema); @@ -49,6 +51,7 @@ export function MetadataProviderWizard({onSave, loading, block}) { return ( <> +

+ {schemaLoading &&
}
Date: Thu, 28 Jul 2022 07:57:21 -0700 Subject: [PATCH 44/88] Fixed issue with configuration loading Former-commit-id: b2ab61a5066a7ce64a94e5619fc93bf4c74a6b3c --- ui/src/app/metadata/hoc/MetadataSchema.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ui/src/app/metadata/hoc/MetadataSchema.js b/ui/src/app/metadata/hoc/MetadataSchema.js index d2d257623..ea14361d9 100644 --- a/ui/src/app/metadata/hoc/MetadataSchema.js +++ b/ui/src/app/metadata/hoc/MetadataSchema.js @@ -5,6 +5,7 @@ import { useTranslator } from '../../i18n/hooks'; export const MetadataSchemaContext = React.createContext(); export const MetadataDefinitionContext = React.createContext(); +export const MetadataSchemaLoading = React.createContext(); export function MetadataSchema({ type, children, wizard = false }) { @@ -35,8 +36,10 @@ export function MetadataSchema({ type, children, wizard = false }) { return ( {type && definition && schema && - - {children} + + + {children} + } @@ -44,13 +47,11 @@ export function MetadataSchema({ type, children, wizard = false }) { } export function useMetadataSchemaContext () { - const {schema} = React.useContext(MetadataSchemaContext); - return schema; + return React.useContext(MetadataSchemaContext); } export function useMetadataSchemaLoading () { - const {loading} = React.useContext(MetadataSchemaContext); - return loading; + return React.useContext(MetadataSchemaLoading); } export function useMetadataDefinitionContext() { From 34b46b7854c483d5c438f322e5e66caebdf05abd Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 28 Jul 2022 09:50:01 -0700 Subject: [PATCH 45/88] Fixed loading spinner Former-commit-id: 81760a5d89c563c4cbb2b979cbeaf6251fd77d80 --- ui/src/app/metadata/view/MetadataWizard.js | 6 +----- ui/src/app/metadata/wizard/MetadataSourceWizard.js | 5 ++++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ui/src/app/metadata/view/MetadataWizard.js b/ui/src/app/metadata/view/MetadataWizard.js index d48cc4330..a95ca777c 100644 --- a/ui/src/app/metadata/view/MetadataWizard.js +++ b/ui/src/app/metadata/view/MetadataWizard.js @@ -8,7 +8,6 @@ import { useMetadataEntity } from '../hooks/api'; import { createNotificationAction, NotificationTypes, useNotificationDispatcher } from '../../notifications/hoc/Notifications'; import { Prompt, useHistory } from 'react-router-dom'; import { useTranslator } from '../../i18n/hooks'; -import Spinner from '../../core/components/Spinner'; export function MetadataWizard ({type, data, onCallback}) { @@ -58,10 +57,7 @@ export function MetadataWizard ({type, data, onCallback}) { /> {type === 'source' ? - - - {loading &&
} -
+ : } diff --git a/ui/src/app/metadata/wizard/MetadataSourceWizard.js b/ui/src/app/metadata/wizard/MetadataSourceWizard.js index 5dae8319a..b14c5c6d4 100644 --- a/ui/src/app/metadata/wizard/MetadataSourceWizard.js +++ b/ui/src/app/metadata/wizard/MetadataSourceWizard.js @@ -8,7 +8,7 @@ import Col from 'react-bootstrap/Col'; import { WizardNav } from './WizardNav'; import { MetadataWizardForm } from './MetadataWizardForm'; import { setWizardIndexAction, useCurrentIndex, useIsFirstPage, useIsLastPage, useWizardDispatcher } from './Wizard'; -import { useMetadataDefinitionContext, useMetadataSchemaContext, useMetadataDefinitionValidator } from '../hoc/MetadataSchema'; +import { useMetadataDefinitionContext, useMetadataSchemaContext, useMetadataDefinitionValidator, useMetadataSchemaLoading } from '../hoc/MetadataSchema'; import { useMetadataFormDispatcher, setFormDataAction, setFormErrorAction, useMetadataFormData, useMetadataFormErrors } from '../hoc/MetadataFormContext'; import { MetadataConfiguration } from '../component/MetadataConfiguration'; import { Configuration } from '../hoc/Configuration'; @@ -17,6 +17,7 @@ import { useMetadataSources } from '../hooks/api'; import Translate from '../../i18n/components/translate'; import { checkChanges } from '../hooks/utility'; import { useCurrentUserLoader, useUserGroup } from '../../core/user/UserContext'; +import Spinner from '../../core/components/Spinner'; export function MetadataSourceWizard ({ onShowNav, onSave, block, loading }) { @@ -24,6 +25,7 @@ export function MetadataSourceWizard ({ onShowNav, onSave, block, loading }) { const group = useUserGroup(); const userLoader = useCurrentUserLoader(); + const schemaLoading = useMetadataSchemaLoading(); /*eslint-disable react-hooks/exhaustive-deps*/ React.useEffect(() => { @@ -75,6 +77,7 @@ export function MetadataSourceWizard ({ onShowNav, onSave, block, loading }) {

+ {schemaLoading &&
} {warnings && warnings.hasOwnProperty(current) && From 603357bcd7a522cc751d989c0e8c91253e4e7d93 Mon Sep 17 00:00:00 2001 From: Jj! Date: Fri, 29 Jul 2022 16:21:52 -0500 Subject: [PATCH 46/88] [SHIBUI-2327] add provider configuration for signatures implement method for X509 --- .../shibboleth/admin/ui/domain/X509Data.java | 4 +- .../main/resources/jpa-signature-config.xml | 268 ++++++++++++++++++ 2 files changed, 271 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/X509Data.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/X509Data.java index e875932cd..7afd88814 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/X509Data.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/X509Data.java @@ -19,6 +19,7 @@ import javax.xml.namespace.QName; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -74,10 +75,11 @@ public void addX509Certificate(edu.internet2.tier.shibboleth.admin.ui.domain.X50 this.xmlObjects.add(x509Certificate); } + // TODO: might need to really implement this @Nonnull @Override public List getX509CRLs() { - return null; + return Collections.EMPTY_LIST; } @Nonnull diff --git a/backend/src/main/resources/jpa-signature-config.xml b/backend/src/main/resources/jpa-signature-config.xml index 0a6696db5..22f00e04b 100644 --- a/backend/src/main/resources/jpa-signature-config.xml +++ b/backend/src/main/resources/jpa-signature-config.xml @@ -39,6 +39,274 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 89d548510608c04a6f208774956244fc68959e8f Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 29 Jul 2022 15:56:56 -0700 Subject: [PATCH 47/88] SHIBUI-2327 Commented out block of builder-marshaller-unmarshaller that was causing conflict with testing --- backend/src/main/resources/jpa-signature-config.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/main/resources/jpa-signature-config.xml b/backend/src/main/resources/jpa-signature-config.xml index 22f00e04b..9a8da32e8 100644 --- a/backend/src/main/resources/jpa-signature-config.xml +++ b/backend/src/main/resources/jpa-signature-config.xml @@ -250,12 +250,12 @@ - + @@ -310,4 +310,4 @@ - + \ No newline at end of file From 4e9cc6683cd9c2a9189512af12cf6fa5f3b204d3 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Mon, 1 Aug 2022 12:27:39 -0700 Subject: [PATCH 48/88] SHIBUI-2327 Correcting security filter to work properly using the pac4j settup --- .../src/main/java/net/unicon/shibui/pac4j/WebSecurity.java | 7 +++++-- testbed/authentication/docker-compose.yml | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java index a67bf4a96..884569ac7 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java @@ -5,7 +5,7 @@ import edu.internet2.tier.shibboleth.admin.ui.security.service.IRolesService; import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService; import edu.internet2.tier.shibboleth.admin.ui.service.EmailService; -import static net.unicon.shibui.pac4j.Pac4jConfiguration.PAC4J_CLIENT_NAME; +import org.pac4j.core.authorization.authorizer.DefaultAuthorizers; import org.pac4j.core.config.Config; import org.pac4j.core.matching.matcher.Matcher; import org.pac4j.springframework.security.web.CallbackFilter; @@ -26,6 +26,8 @@ import javax.servlet.Filter; import java.util.Optional; +import static net.unicon.shibui.pac4j.Pac4jConfiguration.PAC4J_CLIENT_NAME; + @Configuration @AutoConfigureOrder(-1) @ConditionalOnProperty(name = "shibui.pac4j-enabled", havingValue = "true") @@ -62,7 +64,8 @@ public Pac4jWebSecurityConfigurerAdapter(final Config config, UserService userSe protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers("/unsecured/**/*").permitAll(); - final SecurityFilter securityFilter = new SecurityFilter(this.config, PAC4J_CLIENT_NAME); + // adding the authorizor bypasses the default behavior of checking CSRF in Pac4J's default securitylogic+defaultauthorizationchecker + final SecurityFilter securityFilter = new SecurityFilter(this.config, PAC4J_CLIENT_NAME, DefaultAuthorizers.IS_AUTHENTICATED); // add filter based on auth type http.antMatcher("/**").addFilterBefore(getFilter(config, pac4jConfigurationProperties.getTypeOfAuth()), BasicAuthenticationFilter.class); diff --git a/testbed/authentication/docker-compose.yml b/testbed/authentication/docker-compose.yml index 884042c4a..42b12cb6a 100644 --- a/testbed/authentication/docker-compose.yml +++ b/testbed/authentication/docker-compose.yml @@ -20,7 +20,7 @@ services: - "8080:8080" - "443:443" - "8443:8443" -# - "8000:8000" + - "9090:9090" volumes: - /var/run/docker.sock:/var/run/docker.sock - ../reverse-proxy/:/configuration/ @@ -72,6 +72,7 @@ services: - ./shibui/application.yml:/application.yml ports: - "8000:8000" +# - "9090:9090" entrypoint: ["/usr/bin/java", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000", "-jar", "app.war"] networks: reverse-proxy: From 8e25e15382d092f2e23379b0b7e4d1554d0376ed Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 2 Aug 2022 08:25:55 -0700 Subject: [PATCH 49/88] Updated tooltips for FileBacked Provider Former-commit-id: 58708bc501e1e39a6eac0b881b3532efe1e06ac3 --- backend/src/main/resources/i18n/messages.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index a9a0560be..12c4337ec 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -679,7 +679,7 @@ tooltip.http-max-cache-entries=The maximum number of responses written to cache. tooltip.max-cache-entry-size=The maximum response body size that may be cached, in bytes. This attribute is incompatible with httpClientRef. tooltip.metadata-provider-name=Metadata Provider Name (for display on the Dashboard only) -tooltip.metadata-provider-type=Metadata Provider Type +tooltip.metadata-provider-type=The precise behavior of any element is controlled by the xsi:type attribute. This specifies the exact type of provider to use. tooltip.xml-id=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. @@ -707,7 +707,7 @@ tooltip.expiration-warning-threshold=For each attempted metadata refresh (whethe tooltip.filter-name=Filter Name tooltip.enable-filter=Enable Filter? -tooltip.enable-service=Enable Service? +tooltip.enable-service=A boolean value representing whether or not this metadata should be enabled within the Shibboleth IDP UI. tooltip.min-cache-duration=The minimum duration for which metadata will be cached before it is refreshed. tooltip.max-cache-duration=The maximum duration for which metadata will be cached before it is refreshed. From 21a20e5bc6f14cc1d0b91c84f2c9798fcecbe121 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 2 Aug 2022 08:41:03 -0700 Subject: [PATCH 50/88] Updated tooltips for DynamicHttp Provider Former-commit-id: 9ceb46be312916bd01d76241d0b8ee982ebf6c53 --- backend/src/main/resources/i18n/messages.properties | 4 ++-- ui/public/assets/schema/provider/filebacked-http.schema.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index 12c4337ec..c3912d507 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -721,8 +721,8 @@ tooltip.source-directory=Convenience mechanism for wiring a FilesystemLoadSaveMa tooltip.remove-idle-entity-data=Flag indicating whether idle metadata should be removed. tooltip.do-resolver-initialization=Initialize this resolver? In the case of Filesystem resolvers, this will cause the system to read the file and index the resolver. -tooltip.md-request-type=Options are 1) Metadata Query Protocol, 2) Regex. -tooltip.md-request-value=Content of the element. +tooltip.md-request-type=Constructs the metadata request URL based on 1) Metadata Query Protocol, or 2) Regex (a regular expression). +tooltip.md-request-value=Content of the element based on the Metadata Request URL Construction Type. tooltip.transform-ref=A reference to a transform function for the entityID. If used, the child element must be empty. tooltip.encoding-style=Determines whether and how the entityID value will be URL encoded prior to replacement. Allowed values are: 1) "none" - no encoding is performed, 2) "form" - encoded using URL form parameter encoding (for query parameters), 3) "path" - encoded using URL path encoding, or 4) "fragment" - encoded using URL fragment encoding. The precise definition of these terms is defined in the documentation for the methods of the Guava library\u0027s UrlEscapers class. tooltip.velocity-engine=This attribute may be used to specify the name of the Velocity engine defined within the application. diff --git a/ui/public/assets/schema/provider/filebacked-http.schema.json b/ui/public/assets/schema/provider/filebacked-http.schema.json index dffeaa65e..e1b0d95c7 100644 --- a/ui/public/assets/schema/provider/filebacked-http.schema.json +++ b/ui/public/assets/schema/provider/filebacked-http.schema.json @@ -42,8 +42,8 @@ "const": "FileBackedHttpMetadataResolver" }, "enabled": { - "title": "label.enable-service", - "description": "tooltip.enable-service", + "title": "label.enable-provider-upon-saving", + "description": "tooltip.enable-provider-upon-saving", "type": "boolean", "default": false }, From d0eb6511b76b16129cfbc58a50f4e7cd80dade08 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 2 Aug 2022 14:24:07 -0700 Subject: [PATCH 51/88] Updated tooltips for Metadata Sources and filters Former-commit-id: 82ba43969aae58b68c4453931bcf4470949dcf16 --- .../main/resources/i18n/messages.properties | 75 ++++++++++--------- .../resources/metadata-sources-ui-schema.json | 2 +- .../component/fields/FilterTargetField.js | 4 +- .../wizard/MetadataFilterTypeSelector.js | 4 +- 4 files changed, 43 insertions(+), 42 deletions(-) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index c3912d507..8da49adb7 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -615,34 +615,35 @@ 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.entity-id=An entityID is the SAML identifier that uniquely names a service provider. tooltip.service-provider-name=Service Provider Name (Dashboard Display Only) -tooltip.force-authn=Disallows use (or reuse) of authentication results and login flows that don\u0027t provide a real-time proof of user presence in the login process +tooltip.force-authn=Disallows use (or reuse) of authentication results and login flows that don\u0027t provide a real-time proof of user presence in the login process. tooltip.service-provider-name-dashboard-display-only=Service Provider Name (Dashboard Display Only) tooltip.service-provider-entity-id=Service Provider Entity ID -tooltip.organization-name=Organization Name -tooltip.organization-display-name=Organization Display Name -tooltip.organization-url=Organization URL +tooltip.organization-name=Name of the organization standing up the entity. +tooltip.organization-display-name=Name of the organization standing up the entity to be used for display purposes. +tooltip.organization-url=URL of the organization standing up the entity. tooltip.name=Name tooltip.type=Type tooltip.email-address=Email Address -tooltip.assertion-consumer-service-location=Assertion Consumer Service Location -tooltip.assertion-consumer-service-location-binding=Assertion Consumer Service Location Binding -tooltip.mark-as-default=Mark as Default -tooltip.protocol-support-enumeration=Protocol Support Enumeration -tooltip.nameid-format=Content is name identifier format which is added to all the applicable roles of the entities which match any of the following or {{}}elements. -tooltip.enable-this-service-upon-saving=If checkbox is clicked, the metadata provider is enabled for integration with the IdP +tooltip.assertion-consumer-service-location=Path used to invoke handler (when appended to the base handlerURL). +tooltip.assertion-consumer-service-location-binding=The binding attribute of the element is a standard URI specified in the SAML 2.0 Binding specification. +tooltip.assertion-consumer-service-endpoints=An Assertion Consumer Service (or ACS) is SAML terminology for the location at a ServiceProvider that accepts messages (or SAML artifacts) for the purpose of establishing a session based on an assertion. +tooltip.mark-as-default=Whether to mark this endpoint as the default by setting the "isDefault" property. +tooltip.protocol-support-enumeration=This attribute contains a space-delimited collection of URIs that represent general classes of protocol support for the role in question. There are URIs defined by the various standards and profiles to represent the fact that an entity acting in a role "supports" a particular protocol family, such as SAML 2.0 or the Shibboleth profile of SAML 1.1. +tooltip.nameid-format=Content is name identifier format which is added to all the applicable roles of the entities which match any of the following or elements. +tooltip.enable-this-service-upon-saving=If checkbox is clicked, the metadata is enabled for integration with the IdP tooltip.is-there-a-x509-certificate=Is there a X509 Certificate? -tooltip.authentication-requests-signed=Authentication Requests Signed -tooltip.want-assertions-signed=Want Assertions Signed -tooltip.certificate-name=Certificate Name -tooltip.certificate-type=Certificate Type -tooltip.certificate=Certificate -tooltip.logout-endpoints=Logout Endpoints -tooltip.logout-endpoints-url=Logout Endpoints Url -tooltip.logout-endpoints-binding-type=Logout Endpoints Binding Type -tooltip.url=Logout Endpoints Url -tooltip.binding-type=Logout Endpoints Binding Type +tooltip.authentication-requests-signed=Whether to sign requests. +tooltip.want-assertions-signed=Whether to sign assertions. Element declares that the service provider wants the element to be digitally signed. +tooltip.certificate-name=Value used by the IDP UI to identify certificates. +tooltip.certificate-type=Describes the use to which the credential will be put (as defined by the SAML standard) +tooltip.certificate=A certificate containing a public key to use to require and verify an XML signature over the resource. +tooltip.logout-endpoints=If your SP supports SAML 2.0 Single Logout, you will need to include one or more endpoint elements in the metadata. +tooltip.logout-endpoints-url=The location of the handler (when combined with the base handlerURL). This is the location to which an IdP sends messages using whatever protocol and binding it shares with the SP. Each combination of SLO protocol and binding is installed at a unique location to improve efficiency. +tooltip.logout-endpoints-binding-type=Identifies the protocol binding supported by the handler. Bindings describe how the message is packaged by the IdP (or by the browser in some cases) for consumption by the handler. +tooltip.url=The location of the handler (when combined with the base handlerURL). This is the location to which an IdP sends messages using whatever protocol and binding it shares with the SP. Each combination of SLO protocol and binding is installed at a unique location to improve efficiency. +tooltip.binding-type=Identifies the protocol binding supported by the handler. Bindings describe how the message is packaged by the IdP (or by the browser in some cases) for consumption by the handler. tooltip.mdui-display-name=Typically, the IdP Display Name field will be presented on IdP discovery service interfaces. tooltip.mdui-information-url=The IdP Information URL is a link to a comprehensive information page about the IdP. This page should expand on the content of the IdP Description field. tooltip.mdui-description=The IdP Description is a brief description of the IdP service. On a well-designed discovery interface, the IdP Description will be presented to the user in addition to the IdP Display Name, and so the IdP Description helps disambiguate duplicate or similar IdP Display Names. @@ -650,21 +651,21 @@ tooltip.mdui-privacy-statement-url=The IdP Privacy Statement URL is a link to th tooltip.mdui-logo-url=The IdP Logo URL in metadata points to an image file on a remote server. A discovery service, for example, may rely on a visual cue (i.e., a logo) instead of or in addition to the IdP Display Name. tooltip.mdui-logo-width=The logo should have a minimum width of 100 pixels tooltip.mdui-logo-height=The logo should have a minimum height of 75 pixels and a maximum height of 150 pixels (or the application will scale it proportionally) -tooltip.contact-name=Contact Name -tooltip.contact-type=Contact Type -tooltip.contact-email=Contact Email -tooltip.sign-assertion=Sign Assertion -tooltip.dont-sign-response=Don\u0027t Sign Response -tooltip.turn-off-encryption=Turn Off Encryption of Response -tooltip.usa-sha-algorithm=Use SHA1 Signing Algorithm -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.contact-name=The given name of the contact. +tooltip.contact-type=Type / role of the contact. +tooltip.contact-email=Email address of the contact. +tooltip.sign-assertion=Sign Assertion declares that the service provider wants the element to be digitally signed. +tooltip.dont-sign-response=Don\u0027t Sign Response. +tooltip.turn-off-encryption=Whether to turn off encryption of the response. +tooltip.usa-sha-algorithm=Whether to use the SHA1 Signing Algorithm. +tooltip.authentication-methods-to-use=The method used to authenticate the subject. +tooltip.ignore-auth-method=Whether to ignore any SP-Requested Authentication Method. +tooltip.omit-not-before-condition=Whether to include a NotBefore attribute in assertions. +tooltip.responder-id=Identifier of the selected SAML IdP entity. 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 +tooltip.metadata-filter-type=The precise behavior of any element is controlled by the xsi:type attribute. tooltip.connection-request-timeout=The maximum amount of time to wait for a connection to be returned from the HTTP client\u0027s connection pool manager. Set to PT0S to disable. This attribute is incompatible with httpClientRef. tooltip.connection-timeout=The maximum amount of time to wait to establish a connection with the remote server. Set to PT0S to disable. This attribute is incompatible with httpClientRef. tooltip.socket-timeout=The maximum amount of time to wait between two consecutive packets while reading from the socket connected to the remote server. Set to PT0S to disable. This attribute is incompatible with httpClientRef. @@ -690,7 +691,7 @@ tooltip.require-valid-metadata=Whether candidate metadata found by the resolver 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=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=If checkbox is clicked, the metadata provider is enabled for integration with the IdP +tooltip.enable-provider-upon-saving=If checkbox is clicked, the metadata provider is enabled for integration with the IdP. tooltip.max-validity-interval=Defines the window within which the metadata is valid. tooltip.require-signed-root=If true, this fails to load metadata with no signature on the root XML element. @@ -706,9 +707,9 @@ tooltip.resolve-via-predicates-only=Flag indicating whether resolution may be pe tooltip.expiration-warning-threshold=For each attempted metadata refresh (whether or not fresh metadata is obtained), if requireValidMetadata is true, and there is a validUntil XML attribute on the document root element, and the difference between validUntil and the current time is less than expirationWarningThreshold, the system logs a warning about the impending expiration. tooltip.filter-name=Filter Name -tooltip.enable-filter=Enable Filter? +tooltip.enable-filter=If checkbox is clicked, the metadata filter is enabled for integration with the IdP. tooltip.enable-service=A boolean value representing whether or not this metadata should be enabled within the Shibboleth IDP UI. - +tooltip.search-by=Indicates the type of search to be performed. tooltip.min-cache-duration=The minimum duration for which metadata will be cached before it is refreshed. tooltip.max-cache-duration=The maximum duration for which metadata will be cached before it is refreshed. tooltip.max-idle-entity-data=The maximum duration for which metadata will be allowed to be idle (no requests for it) before it is removed from the cache. @@ -739,4 +740,4 @@ tooltip.group-description=Group Description tooltip.role-name=Role Name tooltip.role-description=Role Description -tooltip.contact-information=Contact Information \ No newline at end of file +tooltip.contact-information=Contacts provide information about how to contact the organization responsible for standing up the entity. \ No newline at end of file diff --git a/backend/src/main/resources/metadata-sources-ui-schema.json b/backend/src/main/resources/metadata-sources-ui-schema.json index 09abb43c1..2d64f96bb 100644 --- a/backend/src/main/resources/metadata-sources-ui-schema.json +++ b/backend/src/main/resources/metadata-sources-ui-schema.json @@ -102,7 +102,7 @@ }, "assertionConsumerServices": { "title": "label.assertion-consumer-service-endpoints", - "description": "", + "description": "tooltip.assertion-consumer-service-endpoints", "type": "array", "items": { "$ref": "#/definitions/AssertionConsumerService" diff --git a/ui/src/app/form/component/fields/FilterTargetField.js b/ui/src/app/form/component/fields/FilterTargetField.js index 0cdaa50ce..afb4f7828 100644 --- a/ui/src/app/form/component/fields/FilterTargetField.js +++ b/ui/src/app/form/component/fields/FilterTargetField.js @@ -145,7 +145,7 @@ const FilterTargetField = ({ @@ -170,7 +170,7 @@ const FilterTargetField = ({ - +
diff --git a/ui/src/app/metadata/wizard/MetadataFilterTypeSelector.js b/ui/src/app/metadata/wizard/MetadataFilterTypeSelector.js index 09260c018..8318bbda1 100644 --- a/ui/src/app/metadata/wizard/MetadataFilterTypeSelector.js +++ b/ui/src/app/metadata/wizard/MetadataFilterTypeSelector.js @@ -41,8 +41,8 @@ export function MetadataFilterTypeSelector({ types = [], children, actions}) { - - + + Date: Tue, 2 Aug 2022 14:36:26 -0700 Subject: [PATCH 52/88] Updated tooltips for Groups and Roles Former-commit-id: 18357f2e77c956d2c6edee20236a03676ec73ba4 --- .../main/resources/i18n/messages.properties | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index 8da49adb7..0f22d95b6 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -152,21 +152,21 @@ heading.shibboleth=Shibboleth label.source-configuration=Metadata Source Configuration label.provider-configuration=Metadata Provider Configuration label.entity-attribute-name=Custom Entity Attribute Name -tooltip.entity-attribute-name=Custom Entity Attribute Name +tooltip.entity-attribute-name=Name of the attribute that the service provider uses and requires from the identity provider. It corresponds to the element in the SAML assertion. label.entity-attribute-type=Attribute Type -tooltip.entity-attribute-type=Attribute Type +tooltip.entity-attribute-type=Data type of the attribute such as boolean or string. label.entity-attribute-help=Help Text -tooltip.entity-attribute-help=Help Text +tooltip.entity-attribute-help=Defines help text used in the Shibboleth IDP UI when adding the attribute. label.entity-attribute-default=Default Value -tooltip.entity-attribute-default=Default Value +tooltip.entity-attribute-default=The default value of the attribute. label.entity-attribute-list-options=List options -tooltip.entity-attribute-list-options=List options +tooltip.entity-attribute-list-options=A list of pre-defined selectable options for a user to select from in the Shibboleth IDP UI. label.entity-attribute-friendly-name=Friendly name -tooltip.entity-attribute-friendly-name=Friendly name +tooltip.entity-attribute-friendly-name=A descriptive or human-friendly name for users of the Shibboleth IDP UI. label.entity-attribute-attr-name=Attribute name -tooltip.entity-attribute-attr-name=This is normally a uri or urn +tooltip.entity-attribute-attr-name=Indicates how to interpret the attribute name. It corresponds to the element in the SAML assertion. This is normally a uri or urn. label.entity-attribute-display-name=Display name -tooltip.entity-attribute-display-name=Display name +tooltip.entity-attribute-display-name=Provides a human readable value that identifies the subject. This value is not guaranteed to be unique and is designed to be used only for display purposes. label.entity-attribute-persist-value=Persist Value label.entity-attribute-persist-type=Persist Type @@ -508,7 +508,7 @@ label.source=Metadata Source label.provider=Metadata Provider label.url-validation-regex=URL validation regular expression -tooltip.url-validation-regex=URL validation regular expression +tooltip.url-validation-regex=URL validation regular expression. This is used by the Shibboleth IDP UI to restrict entities that may be targetted by this group and is added as form validation. label.bundle-name=Bundle name label.bundle-disp=Bundle - {name} @@ -734,10 +734,10 @@ tooltip.nameid-formats-format=Format tooltip.nameid-formats-value=Value tooltip.nameid-formats-type=Type -tooltip.group-name=Group Name -tooltip.group-description=Group Description +tooltip.group-name=A user friendly name used to identify the group. +tooltip.group-description=A description of the purpose of the group. -tooltip.role-name=Role Name -tooltip.role-description=Role Description +tooltip.role-name=A user friendly name used to identify the role. +tooltip.role-description=A description of the purpose of the role. tooltip.contact-information=Contacts provide information about how to contact the organization responsible for standing up the entity. \ No newline at end of file From e9f1bd5ab8684c25d5c64a77ab08783503bb26c2 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 2 Aug 2022 14:59:52 -0700 Subject: [PATCH 53/88] Fixed issue with scrollbar on dashboard Former-commit-id: 8c5c29392d932da493211d12ba7ab96a2fed0182 --- .../domain/provider/component/ProviderList.js | 151 +++++++++--------- .../domain/source/component/SourceList.js | 9 +- 2 files changed, 83 insertions(+), 77 deletions(-) diff --git a/ui/src/app/metadata/domain/provider/component/ProviderList.js b/ui/src/app/metadata/domain/provider/component/ProviderList.js index 1b367a69d..9a9ac90d4 100644 --- a/ui/src/app/metadata/domain/provider/component/ProviderList.js +++ b/ui/src/app/metadata/domain/provider/component/ProviderList.js @@ -18,83 +18,86 @@ export function ProviderList({ children, entities, reorder = true, first, last, const translator = useTranslator(); return ( - - {(limited) =>
- - - - - - - - - - - - - {limited.map((provider, idx) => - - + + )} + +
OrderTitleProvider TypeAuthorCreated DateEnabled
-
- {reorder ? -
{idx + 1}
+ + + {(limited) =>
+ + + + + + + + + + + + + {limited.map((provider, idx) => + + + + + + + - - - - - - - )} - -
OrderTitleProvider TypeAuthorCreated DateEnabled
+
+ {reorder ? +
{idx + 1}
+ : +
+ } +   + + +
+
+ {provider.name} + { provider['@type'] }{ provider.createdBy } + + {onEnable && isAdmin ? + onEnable(provider, checked)} + checked={provider.enabled} + > + : -
+ + + } -   - - - -
- {provider.name} - { provider['@type'] }{ provider.createdBy } - - {onEnable && isAdmin ? - onEnable(provider, checked)} - checked={provider.enabled} - > - - : - - - - } - -
+ +
+
+ } +
{children} -
- } - + + ); } diff --git a/ui/src/app/metadata/domain/source/component/SourceList.js b/ui/src/app/metadata/domain/source/component/SourceList.js index 42af027dd..8e8a10825 100644 --- a/ui/src/app/metadata/domain/source/component/SourceList.js +++ b/ui/src/app/metadata/domain/source/component/SourceList.js @@ -23,7 +23,8 @@ export default function SourceList({ entities, onDelete, onEnable, onChangeGroup const canEnable = useCanEnable(); return ( - + + {(limited) =>
@@ -122,9 +123,11 @@ export default function SourceList({ entities, onDelete, onEnable, onChangeGroup
- {children}
} -
+
+ {children} + + ); } From 3c2cde47054ba06f2940cebd76af0f138b447d1c Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Tue, 2 Aug 2022 19:15:09 -0400 Subject: [PATCH 54/88] SHIBUI-1978 Small test tweak for stability. Former-commit-id: 9f3792a8374ecd91862bdc12d97907adcb350f16 --- .../integration/resources/SHIBUI-1732-4.side | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/backend/src/integration/resources/SHIBUI-1732-4.side b/backend/src/integration/resources/SHIBUI-1732-4.side index 6aab66e67..214a49cbd 100644 --- a/backend/src/integration/resources/SHIBUI-1732-4.side +++ b/backend/src/integration/resources/SHIBUI-1732-4.side @@ -992,6 +992,13 @@ ["xpath=//div[3]/div/div/div[3]/button", "xpath:position"] ], "value": "" + }, { + "id": "14c486b1-bdff-4474-94e3-b4286303a8fd", + "comment": "", + "command": "pause", + "target": "5000", + "targets": [], + "value": "" }, { "id": "e3892564-1a1b-4ee6-bbab-49d3cb3079d7", "comment": "", @@ -999,21 +1006,21 @@ "target": "css=table > tbody > tr", "targets": [], "value": "" - },{ - "id": "4ec2c493-85e4-403b-9b09-031c5728f498", - "comment": "", - "command": "open", - "target": "/api/heheheheheheheWipeout", - "targets": [], - "value": "" - }, { - "id": "e074980a-8f21-4c22-8412-c4b6fcdcd1a4", - "comment": "", - "command": "assertText", - "target": "css=body", - "targets": [], - "value": "yes, you did it" - }] + }, { + "id": "4ec2c493-85e4-403b-9b09-031c5728f498", + "comment": "", + "command": "open", + "target": "/api/heheheheheheheWipeout", + "targets": [], + "value": "" + }, { + "id": "e074980a-8f21-4c22-8412-c4b6fcdcd1a4", + "comment": "", + "command": "assertText", + "target": "css=body", + "targets": [], + "value": "yes, you did it" + }] }], "suites": [{ "id": "575d414c-556d-45f7-b2f2-c9971ad51348", From 372bac2bc9c6f7493fff1662a19963f294a43a24 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 4 Aug 2022 11:32:22 -0700 Subject: [PATCH 55/88] Set popover icons to placement auto Former-commit-id: 49e9a7f18cc1fd9e48e6a8a54b451dc786132386 --- ui/src/app/form/component/InfoIcon.js | 2 +- ui/src/app/form/component/fields/DescriptionField.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/src/app/form/component/InfoIcon.js b/ui/src/app/form/component/InfoIcon.js index 209e4f426..a9dbb9363 100644 --- a/ui/src/app/form/component/InfoIcon.js +++ b/ui/src/app/form/component/InfoIcon.js @@ -7,7 +7,7 @@ import Button from 'react-bootstrap/Button'; import Translate from '../../i18n/components/translate'; import { useTranslator } from '../../i18n/hooks'; -export function InfoIcon ({ value = '', placement='left', ...props }) { +export function InfoIcon ({ value = '', placement='auto', ...props }) { const translate = useTranslator(); return( { if (description) { - return ; + return ; } return null; From d6567acaa2f55352d490c7f6fcdefb1a5d24607e Mon Sep 17 00:00:00 2001 From: Sean Porth Date: Fri, 5 Aug 2022 08:49:47 -0400 Subject: [PATCH 56/88] added ignoreRequestSignatures Former-commit-id: a37482fe6f460f7cb11c11b1e8a75f0d275027e6 --- backend/src/main/resources/application.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index ffeab970c..bf1367934 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -156,4 +156,10 @@ custom: displayType: boolean helpText: tooltip.force-authn attributeName: http://shibboleth.net/ns/profiles/forceAuthn - attributeFriendlyName: forceAuthn \ No newline at end of file + attributeFriendlyName: forceAuthn + - name: ignoreRequestSignatures + displayName: label.ignore-request-signatures + displayType: boolean + helpText: tooltip.ignore-request-signatures + attributeName: http://shibboleth.net/ns/profiles/ignoreRequestSignatures + attributeFriendlyName: ignoreRequestSignatures \ No newline at end of file From 1111d68bae1367627eafdecd366c3a3ffcba7a91 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 5 Aug 2022 14:21:31 -0700 Subject: [PATCH 57/88] SHIBUI-2268 Adding xml config for marshalling/unmarshalling xml pieces --- .../main/resources/jpa-encryption-config.xml | 284 ++++++++++++++++ .../test/resources/jpa-encryption-config.xml | 284 ++++++++++++++++ .../test/resources/jpa-signature-config.xml | 313 ++++++++++++++++++ 3 files changed, 881 insertions(+) create mode 100644 backend/src/main/resources/jpa-encryption-config.xml create mode 100644 backend/src/test/resources/jpa-encryption-config.xml create mode 100644 backend/src/test/resources/jpa-signature-config.xml diff --git a/backend/src/main/resources/jpa-encryption-config.xml b/backend/src/main/resources/jpa-encryption-config.xml new file mode 100644 index 000000000..05adde279 --- /dev/null +++ b/backend/src/main/resources/jpa-encryption-config.xml @@ -0,0 +1,284 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/src/test/resources/jpa-encryption-config.xml b/backend/src/test/resources/jpa-encryption-config.xml new file mode 100644 index 000000000..05adde279 --- /dev/null +++ b/backend/src/test/resources/jpa-encryption-config.xml @@ -0,0 +1,284 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/src/test/resources/jpa-signature-config.xml b/backend/src/test/resources/jpa-signature-config.xml new file mode 100644 index 000000000..9a8da32e8 --- /dev/null +++ b/backend/src/test/resources/jpa-signature-config.xml @@ -0,0 +1,313 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 50bd2c7d074081f06cd13b3f94c06f1f38c043c1 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 5 Aug 2022 14:22:09 -0700 Subject: [PATCH 58/88] SHIBUI-2268 Fixing broken enhancements --- .../JPAMetadataResolverServiceImpl.groovy | 3 +- .../AbstractAlgorithmIdentifierType.java | 18 +++++++++- .../jpa-saml2-metadata-ds-config.xml | 23 ------------- ...XMLObjectProviderInitializerForTest.groovy | 2 +- ...JPAMetadataResolverServiceImplTests.groovy | 18 +++++++--- .../src/test/resources/conf/2268-complex.xml | 33 ++++++++----------- .../src/test/resources/conf/2268-simple.xml | 29 ++++++++-------- 7 files changed, 60 insertions(+), 66 deletions(-) delete mode 100644 backend/src/main/resources/jpa-saml2-metadata-ds-config.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 66bfb65ca..6497608a0 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 @@ -104,7 +104,8 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { 'xmlns:security': 'urn:mace:shibboleth:2.0:security', 'xmlns:saml2': 'urn:oasis:names:tc:SAML:2.0:assertion', 'xmlns:xenc11': 'http://www.w3.org/2009/xmlenc11#', - 'xmlns:alg': 'urn:oasis:names:tc:SAML:metadata:algsupport' + 'xmlns:alg': 'urn:oasis:names:tc:SAML:metadata:algsupport', + 'xmlns:ds': 'http://www.w3.org/2000/09/xmldsig#' ) { filter.unknownXMLObjects.each { xmlObject -> { diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AbstractAlgorithmIdentifierType.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AbstractAlgorithmIdentifierType.java index fcca2dd08..99fdc3bfa 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AbstractAlgorithmIdentifierType.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AbstractAlgorithmIdentifierType.java @@ -6,7 +6,10 @@ import lombok.Setter; import lombok.ToString; import org.hibernate.envers.Audited; +import org.opensaml.core.xml.XMLObject; +import org.opensaml.xmlsec.encryption.AlgorithmIdentifierType; +import javax.annotation.Nullable; import javax.persistence.Entity; @Entity @@ -15,6 +18,19 @@ @Setter @ToString @EqualsAndHashCode(callSuper = true) -public abstract class AbstractAlgorithmIdentifierType extends AbstractXMLObject { +public abstract class AbstractAlgorithmIdentifierType extends AbstractXMLObject implements AlgorithmIdentifierType { private String algorithm; + + @Nullable + @Override + public XMLObject getParameters() { + // implement? + return null; + } + + @Override + public void setParameters(@Nullable final XMLObject newParameters) { + // do nothing? + } + } \ No newline at end of file diff --git a/backend/src/main/resources/jpa-saml2-metadata-ds-config.xml b/backend/src/main/resources/jpa-saml2-metadata-ds-config.xml deleted file mode 100644 index 3a0eed8f0..000000000 --- a/backend/src/main/resources/jpa-saml2-metadata-ds-config.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializerForTest.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializerForTest.groovy index 4ac1ba2b1..f84afdcc5 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializerForTest.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializerForTest.groovy @@ -6,7 +6,7 @@ class JPAXMLObjectProviderInitializerForTest extends AbstractXMLObjectProviderIn @Override protected String[] getConfigResources() { return new String[]{ - "/jpa-saml2-metadata-config.xml", "jpa-saml2-metadata-algorithm-config.xml", "jpa-saml2-metadata-ds-config.xml" + "/jpa-saml2-metadata-config.xml", "jpa-saml2-metadata-algorithm-config.xml", "jpa-encryption-config.xml", "jpa-signature-config.xml" } } } \ No newline at end of file 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 0ca8ca3a3..1bdf0f791 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 @@ -4,11 +4,18 @@ package edu.internet2.tier.shibboleth.admin.ui.service import edu.internet2.tier.shibboleth.admin.ui.AbstractBaseDataJpaTest import edu.internet2.tier.shibboleth.admin.ui.configuration.PlaceholderResolverComponentsConfiguration import edu.internet2.tier.shibboleth.admin.ui.configuration.ShibUIConfiguration +import edu.internet2.tier.shibboleth.admin.ui.domain.AlgorithmDigestMethod +import edu.internet2.tier.shibboleth.admin.ui.domain.EncryptionMethod +import edu.internet2.tier.shibboleth.admin.ui.domain.SignatureDigestMethod +import edu.internet2.tier.shibboleth.admin.ui.domain.SigningMethod +import edu.internet2.tier.shibboleth.admin.ui.domain.XSString import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.Entity +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.MGF +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.PRF import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ClasspathMetadataResource import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetadataResolver import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ExternalMetadataResolver @@ -19,6 +26,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.SvnMetadataResour import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.TemplateScheme import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlChainingMetadataResolver import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects +import edu.internet2.tier.shibboleth.admin.ui.opensaml.config.JPAXMLObjectProviderInitializerForTest import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator import edu.internet2.tier.shibboleth.admin.util.AttributeUtility @@ -48,7 +56,6 @@ import java.time.Instant import static edu.internet2.tier.shibboleth.admin.ui.util.TestHelpers.generatedXmlIsTheSameAsExpectedXml -@ContextConfiguration(classes=[ JPAMRSIConfig, PlaceholderResolverComponentsConfiguration ]) @ContextConfiguration(classes=[ JPAMRSIConfig, PlaceholderResolverComponentsConfiguration, JPAXMLObjectProviderInitializerForTest ]) class JPAMetadataResolverServiceImplTests extends AbstractBaseDataJpaTest { @@ -217,9 +224,12 @@ class JPAMetadataResolverServiceImplTests extends AbstractBaseDataJpaTest { filter.addUnknownXMLObject(encryptionMethod) EncryptionMethod encryptionMethod2 = getEncryptionMethod("http://www.w3.org/2009/xmlenc11#rsa-oaep") -// MGF mgf = new MGF() -// mgf.setAlgorithm("http://www.w3.org/2009/xmlenc11#mgf1sha256") -// encryptionMethod2.addUnknownXMLObject(mgf) + MGF mgf = new MGF() + mgf.setAlgorithm("http://www.w3.org/2009/xmlenc11#mgf1sha256") + encryptionMethod2.addUnknownXMLObject(mgf) + PRF prf = new PRF() + prf.setAlgorithm("http://www.w3.org/2009/xmlenc11#mgf1sha384") + encryptionMethod2.addUnknownXMLObject(prf) SignatureDigestMethod dm = getSignatureDigestMethod("http://www.w3.org/2001/04/xmlenc#sha256") encryptionMethod2.addUnknownXMLObject(dm) filter.addUnknownXMLObject(encryptionMethod2) diff --git a/backend/src/test/resources/conf/2268-complex.xml b/backend/src/test/resources/conf/2268-complex.xml index cb4615a40..ee76b2f84 100644 --- a/backend/src/test/resources/conf/2268-complex.xml +++ b/backend/src/test/resources/conf/2268-complex.xml @@ -1,36 +1,29 @@ - - + + - + - https://sp2.example.org + https://broken.example.org/sp + \ No newline at end of file diff --git a/backend/src/test/resources/conf/2268-simple.xml b/backend/src/test/resources/conf/2268-simple.xml index e4365da17..daf8c5fac 100644 --- a/backend/src/test/resources/conf/2268-simple.xml +++ b/backend/src/test/resources/conf/2268-simple.xml @@ -1,25 +1,22 @@ - - + https://broken.example.org/sp https://also-broken.example.org/sp + \ No newline at end of file From ccc61fff1e667ee0b0ec0a8826677111cbdac67a Mon Sep 17 00:00:00 2001 From: chasegawa Date: Mon, 8 Aug 2022 13:23:58 -0700 Subject: [PATCH 59/88] SHIBUI-2268 Adding remaining needed pieces for Algorithm filter --- backend/build.gradle | 2 +- .../JPAMetadataResolverServiceImpl.groovy | 17 +++++++-- .../filters/algorithm/ConditionRef.java | 38 +++++++++++++++++++ .../filters/algorithm/ConditionScript.java | 38 +++++++++++++++++++ .../ui/domain/filters/algorithm/Entity.java | 3 ++ .../JPAXMLObjectProviderInitializer.java | 13 +++---- ...JPAMetadataResolverServiceImplTests.groovy | 36 ++++++++++++++++++ .../src/test/resources/conf/2268-actual.xml | 29 ++++++++++++++ 8 files changed, 164 insertions(+), 12 deletions(-) create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/ConditionRef.java create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/ConditionScript.java create mode 100644 backend/src/test/resources/conf/2268-actual.xml diff --git a/backend/build.gradle b/backend/build.gradle index cfd16a65a..83d2c8dd8 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -332,7 +332,7 @@ task generateSources { } } - new XmlSlurper().parse(file('src/main/resources/jpa-saml2-metadata-ds-config.xml')).with { builders -> + new XmlSlurper().parse(file('src/main/resources/jpa-signature-config.xml')).with { builders -> builders.ObjectProviders.ObjectProvider.BuilderClass.each { processLine(it['@className'].toString(), 'src/main/templates/SignatureBuilderTemplate.java') } 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 6497608a0..78ca12254 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 @@ -10,6 +10,8 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.filters.NameIdFormatFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.SignatureValidationFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.AlgorithmFilter +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.ConditionRef +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.ConditionScript import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.Entity import edu.internet2.tier.shibboleth.admin.ui.domain.filters.opensaml.OpenSamlNameIdFormatFilter import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetadataResolver @@ -111,6 +113,15 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { { if (xmlObject instanceof Entity) { Entity(xmlObject.getValue()) + } else if (xmlObject instanceof ConditionRef) { + ConditionRef(xmlObject.getValue()) + } else if (xmlObject instanceof ConditionScript) { + ConditionScript() { + Script() { + def script = xmlObject.getValue() + mkp.yieldUnescaped("\n\n") + } + } } else { mkp.yieldUnescaped(openSamlObjects.marshalToXmlString(xmlObject, false)) } @@ -133,10 +144,8 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { Entity(it) } break - case EntityAttributesFilterTarget - .EntityAttributesFilterTargetType.CONDITION_SCRIPT: - case EntityAttributesFilterTarget - .EntityAttributesFilterTargetType.REGEX: + case EntityAttributesFilterTarget.EntityAttributesFilterTargetType.CONDITION_SCRIPT: + case EntityAttributesFilterTarget.EntityAttributesFilterTargetType.REGEX: ConditionScript() { Script() { def script diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/ConditionRef.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/ConditionRef.java new file mode 100644 index 000000000..b35cd0762 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/ConditionRef.java @@ -0,0 +1,38 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm; + +import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractXMLObject; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.hibernate.envers.Audited; + +import javax.annotation.Nullable; + +@javax.persistence.Entity +@Audited +@Getter +@Setter +@ToString +@EqualsAndHashCode(callSuper = true) +/** + * The textual content (the value/uri) is the Bean ID of type Predicate + */ +public class ConditionRef extends AbstractXMLObject implements org.opensaml.core.xml.schema.XSString { + private String uri; + + public ConditionRef() { + setElementLocalName("ConditionRef"); + } + + @Nullable + @Override + public String getValue() { + return this.uri; + } + + @Override + public void setValue(@Nullable String newValue) { + this.uri = newValue; + } +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/ConditionScript.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/ConditionScript.java new file mode 100644 index 000000000..a2d58382a --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/ConditionScript.java @@ -0,0 +1,38 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm; + +import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractXMLObject; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.hibernate.envers.Audited; + +import javax.annotation.Nullable; + +@javax.persistence.Entity +@Audited +@Getter +@Setter +@ToString +@EqualsAndHashCode(callSuper = true) +/** + * The textual content is the JS script (the export of the XML will wrap it appropriately) + */ +public class ConditionScript extends AbstractXMLObject implements org.opensaml.core.xml.schema.XSString { + private String uri; + + public ConditionScript() { + setElementLocalName("ConditionScript"); + } + + @Nullable + @Override + public String getValue() { + return this.uri; + } + + @Override + public void setValue(@Nullable String newValue) { + this.uri = newValue; + } +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/Entity.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/Entity.java index b15ec2ca1..18dfcbe8e 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/Entity.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/Entity.java @@ -15,6 +15,9 @@ @Setter @ToString @EqualsAndHashCode(callSuper = true) +/** + * The textual content (value/uri) is an entityID. + */ public class Entity extends AbstractXMLObject implements org.opensaml.core.xml.schema.XSString { private String uri; diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializer.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializer.java index d1413b87f..24757d560 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializer.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/config/JPAXMLObjectProviderInitializer.java @@ -8,16 +8,15 @@ public class JPAXMLObjectProviderInitializer extends AbstractXMLObjectProviderIn protected String[] getConfigResources() { return new String[]{ "/jpa-default-config.xml", - "/jpa-saml2-metadata-config.xml", - "/jpa-saml2-metadata-attr-config.xml", + "/encryption-config.xml", "/jpa-saml2-assertion-config.xml", - "/jpa-schema-config.xml", - "/jpa-saml2-metadata-ui-config.xml", - "/jpa-signature-config.xml", "/jpa-saml2-metadata-algorithm-config.xml", - "/jpa-saml2-metadata-ds-config.xml", - "/encryption-config.xml", + "/jpa-saml2-metadata-attr-config.xml", + "/jpa-saml2-metadata-config.xml", "/jpa-saml2-metadata-reqinit-config.xml", + "/jpa-saml2-metadata-ui-config.xml", + "/jpa-schema-config.xml", + "/jpa-signature-config.xml", "/saml2-protocol-config.xml", "/modified-saml2-assertion-config.xml" }; 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 1bdf0f791..505d1507a 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 @@ -13,6 +13,8 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFil import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilFilter +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.ConditionRef +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.ConditionScript import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.Entity import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.MGF import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.PRF @@ -217,6 +219,40 @@ class JPAMetadataResolverServiceImplTests extends AbstractBaseDataJpaTest { generatedXmlIsTheSameAsExpectedXml('/conf/2268-simple.xml', domBuilder.parseText(writer.toString())) } + def 'test generating AlgorithmFilter shibui-2268 actual'() { + given: + def filter = TestObjectGenerator.algorithmFilter() + EncryptionMethod encryptionMethod = new EncryptionMethod() + encryptionMethod.setElementLocalName(EncryptionMethod.DEFAULT_ELEMENT_LOCAL_NAME) + encryptionMethod.setNamespacePrefix(SAMLConstants.SAML20MD_PREFIX) + encryptionMethod.setNamespaceURI(SAMLConstants.SAML20MD_NS) + encryptionMethod.setSchemaLocation(SAMLConstants.SAML20MD_SCHEMA_LOCATION) + encryptionMethod.setAlgorithm("http://www.w3.org/2001/04/xmlenc#aes128-cbc") + filter.addUnknownXMLObject(encryptionMethod) + + Entity entity = new Entity() + entity.setValue("https://broken.example.org/sp") + filter.addUnknownXMLObject(entity) + + ConditionRef cr = new ConditionRef() + cr.setValue("shibboleth.Conditions.TRUE") + filter.addUnknownXMLObject(cr) + + ConditionScript cs = new ConditionScript() + cs.setValue("\"use strict\";\nfalse;") + filter.addUnknownXMLObject(cs) + + when: + genXmlSnippet(markupBuilder) { JPAMetadataResolverServiceImpl.cast(metadataResolverService).constructXmlNodeForFilter(filter, it) } + + then: + generatedXmlIsTheSameAsExpectedXml('/conf/2268-actual.xml', domBuilder.parseText(writer.toString())) + } + + /** + * This test was written before we simplified the concept of what we'd allow the users to build in the UI. Because the test was + * already done and working, it was left here for completeness. + */ def 'test generating complex AlgorithmFilter xml snippet'() { given: def filter = TestObjectGenerator.algorithmFilter() diff --git a/backend/src/test/resources/conf/2268-actual.xml b/backend/src/test/resources/conf/2268-actual.xml new file mode 100644 index 000000000..961079197 --- /dev/null +++ b/backend/src/test/resources/conf/2268-actual.xml @@ -0,0 +1,29 @@ + + + + + + https://broken.example.org/sp + shibboleth.Conditions.TRUE + + + + + + \ No newline at end of file From ae97066d48525ec71392ca9b8df0e2b1a4f881ca Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 9 Aug 2022 13:55:06 -0700 Subject: [PATCH 60/88] SHIBUI-2268 Refactoring and simplifying code for AlgorithmFilter --- ...gorithmFilterUiDefinitionController.groovy | 56 +++++++++ .../JPAMetadataResolverServiceImpl.groovy | 62 +++++++--- .../domain/{filters/algorithm => }/MGF.java | 3 +- .../{filters/algorithm => }/OtherSource.java | 3 +- .../domain/{filters/algorithm => }/PRF.java | 3 +- .../domain/filters/AbstractFilterTarget.java | 39 +++++++ .../filters/EntityAttributesFilterTarget.java | 39 +------ .../ui/domain/filters/MetadataFilter.java | 2 +- .../filters/NameIdFormatFilterTarget.java | 29 +---- .../filters/algorithm/AlgorithmFilter.java | 38 +++--- .../algorithm/AlgorithmFilterTarget.java | 34 ++++++ .../filters/algorithm/ConditionRef.java | 38 ------ .../filters/algorithm/ConditionScript.java | 38 ------ .../ui/domain/filters/algorithm/Entity.java | 38 ------ .../jsonschema/JsonSchemaLocationLookup.java | 12 ++ .../resources/algorithm-filter.schema.json | 33 ++++++ ...JPAMetadataResolverServiceImplTests.groovy | 108 ++++-------------- .../src/test/resources/conf/2268-complex.xml | 29 ----- .../conf/{2268-simple.xml => 2268-entity.xml} | 0 .../conf/{2268-actual.xml => 2268-script.xml} | 2 - 20 files changed, 268 insertions(+), 338 deletions(-) create mode 100644 backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/AlgorithmFilterUiDefinitionController.groovy rename backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/{filters/algorithm => }/MGF.java (78%) rename backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/{filters/algorithm => }/OtherSource.java (79%) rename backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/{filters/algorithm => }/PRF.java (78%) create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/AbstractFilterTarget.java create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AlgorithmFilterTarget.java delete mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/ConditionRef.java delete mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/ConditionScript.java delete mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/Entity.java create mode 100644 backend/src/main/resources/algorithm-filter.schema.json delete mode 100644 backend/src/test/resources/conf/2268-complex.xml rename backend/src/test/resources/conf/{2268-simple.xml => 2268-entity.xml} (100%) rename backend/src/test/resources/conf/{2268-actual.xml => 2268-script.xml} (95%) diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/AlgorithmFilterUiDefinitionController.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/AlgorithmFilterUiDefinitionController.groovy new file mode 100644 index 000000000..9c7698235 --- /dev/null +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/AlgorithmFilterUiDefinitionController.groovy @@ -0,0 +1,56 @@ +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 groovy.util.logging.Slf4j +import io.swagger.v3.oas.annotations.tags.Tag +import io.swagger.v3.oas.annotations.tags.Tags +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.RequestMapping +import org.springframework.web.bind.annotation.RestController + +import javax.annotation.PostConstruct + +import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR + +/** + * Controller implementing REST resource responsible for exposing structure definition for algorithm format filter user + * interface in terms of JSON schema. + */ +@RestController +@RequestMapping('/api/ui/AlgorithmFilter') +@Slf4j +@Tags(value = [@Tag(name = "ui")]) +class AlgorithmFilterUiDefinitionController { + + @Autowired + JsonSchemaResourceLocationRegistry jsonSchemaResourceLocationRegistry + + JsonSchemaResourceLocation jsonSchemaLocation + + @Autowired + ObjectMapper jacksonObjectMapper + + @Autowired + JsonSchemaBuilderService jsonSchemaBuilderService + + @GetMapping + ResponseEntity getUiDefinitionJsonSchema() { + try { + def parsedJson = jacksonObjectMapper.readValue(this.jsonSchemaLocation.url, Map) + return ResponseEntity.ok(parsedJson) + } catch (Exception e) { + log.error(e.getMessage(), e) + return ResponseEntity.status(INTERNAL_SERVER_ERROR).body([jsonParseError : e.getMessage(), sourceUiSchemaDefinitionFile: this.jsonSchemaLocation.url]) + } + } + + @PostConstruct + void init() { +// this.jsonSchemaLocation = algorithmFilterSchema(this.jsonSchemaResourceLocationRegistry) + } +} \ No newline at end of file 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 78ca12254..f3f0b0eb3 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 @@ -2,6 +2,8 @@ package edu.internet2.tier.shibboleth.admin.ui.service import com.google.common.base.Predicate import edu.internet2.tier.shibboleth.admin.ui.configuration.ShibUIConfiguration +import edu.internet2.tier.shibboleth.admin.ui.domain.EncryptionMethod +import edu.internet2.tier.shibboleth.admin.ui.domain.EncryptionMethodBuilder import edu.internet2.tier.shibboleth.admin.ui.domain.exceptions.MetadataFileNotFoundException import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget @@ -10,9 +12,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.filters.NameIdFormatFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.SignatureValidationFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.AlgorithmFilter -import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.ConditionRef -import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.ConditionScript -import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.Entity +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.AlgorithmFilterTarget import edu.internet2.tier.shibboleth.admin.ui.domain.filters.opensaml.OpenSamlNameIdFormatFilter import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetadataResolver import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ExternalMetadataResolver @@ -109,24 +109,50 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { 'xmlns:alg': 'urn:oasis:names:tc:SAML:metadata:algsupport', 'xmlns:ds': 'http://www.w3.org/2000/09/xmldsig#' ) { - filter.unknownXMLObjects.each { xmlObject -> - { - if (xmlObject instanceof Entity) { - Entity(xmlObject.getValue()) - } else if (xmlObject instanceof ConditionRef) { - ConditionRef(xmlObject.getValue()) - } else if (xmlObject instanceof ConditionScript) { - ConditionScript() { - Script() { - def script = xmlObject.getValue() - mkp.yieldUnescaped("\n\n") - } + for (String algValue : filter.getAlgorithms()) { + EncryptionMethod method = new EncryptionMethodBuilder().buildObject(); + method.setAlgorithm(algValue) + mkp.yieldUnescaped(openSamlObjects.marshalToXmlString(method, false)) + } + switch (filter.algorithmFilterTarget.targetType) { + case AlgorithmFilterTarget.AlgorithmFilterTargetType.ENTITY: + filter.algorithmFilterTarget.value.each { + Entity(it) + } + break + case AlgorithmFilterTarget.AlgorithmFilterTargetType.CONDITION_REF: + ConditionRef(xmlObject.getValue()) + break + case AlgorithmFilterTarget.AlgorithmFilterTargetType.CONDITION_SCRIPT: + ConditionScript() { + Script() { + def script = filter.getAlgorithmFilterTarget().value[0] + mkp.yieldUnescaped("\n\n") } - } else { - mkp.yieldUnescaped(openSamlObjects.marshalToXmlString(xmlObject, false)) } - } + break + default: + // do nothing, we'd have exploded elsewhere previously. + break } +// filter.unknownXMLObjects.each { xmlObject -> +// { +// if (xmlObject instanceof Entity) { +// Entity(xmlObject.getValue()) +// } else if (xmlObject instanceof ConditionRef) { +// ConditionRef(xmlObject.getValue()) +// } else if (xmlObject instanceof ConditionScript) { +// ConditionScript() { +// Script() { +// def script = xmlObject.getValue() +// mkp.yieldUnescaped("\n\n") +// } +// } +// } else { +// mkp.yieldUnescaped(openSamlObjects.marshalToXmlString(xmlObject, false)) +// } +// } +// } } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/MGF.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/MGF.java similarity index 78% rename from backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/MGF.java rename to backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/MGF.java index f78eaaf00..0278b3af8 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/MGF.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/MGF.java @@ -1,5 +1,6 @@ -package edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm; +package edu.internet2.tier.shibboleth.admin.ui.domain; +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.AbstractAlgorithmIdentifierType; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/OtherSource.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/OtherSource.java similarity index 79% rename from backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/OtherSource.java rename to backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/OtherSource.java index b57e0c82c..afc50b3f4 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/OtherSource.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/OtherSource.java @@ -1,5 +1,6 @@ -package edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm; +package edu.internet2.tier.shibboleth.admin.ui.domain; +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.AbstractAlgorithmIdentifierType; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/PRF.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/PRF.java similarity index 78% rename from backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/PRF.java rename to backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/PRF.java index 3ee2dabec..b621a0278 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/PRF.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/PRF.java @@ -1,5 +1,6 @@ -package edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm; +package edu.internet2.tier.shibboleth.admin.ui.domain; +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.AbstractAlgorithmIdentifierType; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/AbstractFilterTarget.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/AbstractFilterTarget.java new file mode 100644 index 000000000..a26c06e88 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/AbstractFilterTarget.java @@ -0,0 +1,39 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.filters; + +import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractAuditable; +import lombok.EqualsAndHashCode; + +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.FetchType; +import javax.persistence.MappedSuperclass; +import javax.persistence.OrderColumn; +import java.util.ArrayList; +import java.util.List; + +@MappedSuperclass +@EqualsAndHashCode(callSuper = true) +public abstract class AbstractFilterTarget extends AbstractAuditable implements IFilterTarget { + @ElementCollection(fetch = FetchType.EAGER) + @OrderColumn + @Column(length = 760, name="target_value") + protected List value; + + @Override + public List getValue() { + return value == null ? new ArrayList<>() : value; + } + + @Override + public void setSingleValue(String value) { + List values = new ArrayList<>(); + values.add(value); + this.value = values; + } + + @Override + public void setValue(List value) { + this.value = value; + } + +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilterTarget.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilterTarget.java index e2ed028a0..b2ffb6b0d 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilterTarget.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilterTarget.java @@ -4,31 +4,21 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractAuditable; import lombok.EqualsAndHashCode; +import lombok.ToString; import org.hibernate.envers.AuditOverride; import org.hibernate.envers.Audited; -import javax.persistence.Column; -import javax.persistence.ElementCollection; import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.OrderColumn; -import java.util.ArrayList; -import java.util.List; @Entity @EqualsAndHashCode(callSuper = true) +@ToString @Audited @AuditOverride(forClass = AbstractAuditable.class) @JsonIgnoreProperties({"handler", "hibernateLazyInitializer"}) -public class EntityAttributesFilterTarget extends AbstractAuditable implements IFilterTarget { - +public class EntityAttributesFilterTarget extends AbstractFilterTarget { private EntityAttributesFilterTargetType entityAttributesFilterTargetType; - @ElementCollection (fetch = FetchType.EAGER) - @OrderColumn - @Column(length = 760, name="target_value") - private List value; - public EntityAttributesFilterTargetType getEntityAttributesFilterTargetType() { return entityAttributesFilterTargetType; } @@ -39,33 +29,10 @@ public String getTargetTypeValue() { return entityAttributesFilterTargetType == null ? "NONE" : entityAttributesFilterTargetType.name(); } - @Override - public List getValue() { - return value == null ? new ArrayList<>() : value; - } - public void setEntityAttributesFilterTargetType(EntityAttributesFilterTargetType entityAttributesFilterTarget) { this.entityAttributesFilterTargetType = entityAttributesFilterTarget; } - public void setSingleValue(String value) { - List values = new ArrayList<>(); - values.add(value); - this.value = values; - } - - public void setValue(List value) { - this.value = value; - } - - @Override - public String toString() { - return "EntityAttributesFilterTarget{" + - "entityAttributesFilterTargetType=" + entityAttributesFilterTargetType + - ", value=" + value + - '}'; - } - public enum EntityAttributesFilterTargetType { ENTITY, CONDITION_SCRIPT, CONDITION_REF, REGEX } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/MetadataFilter.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/MetadataFilter.java index 548c97356..c566576df 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/MetadataFilter.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/MetadataFilter.java @@ -50,7 +50,7 @@ public abstract class MetadataFilter extends AbstractAuditable implements IConcr @JsonProperty("@type") @Transient - String type; + protected String type; @Transient private transient Integer version; diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/NameIdFormatFilterTarget.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/NameIdFormatFilterTarget.java index 3a5bfe9da..c5441a053 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/NameIdFormatFilterTarget.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/NameIdFormatFilterTarget.java @@ -8,29 +8,18 @@ import org.hibernate.envers.AuditOverride; import org.hibernate.envers.Audited; -import javax.persistence.Column; -import javax.persistence.ElementCollection; import javax.persistence.Entity; -import javax.persistence.OrderColumn; -import javax.persistence.Transient; -import java.util.ArrayList; -import java.util.List; @Entity @EqualsAndHashCode(callSuper = true) @ToString @Audited @AuditOverride(forClass = AbstractAuditable.class) -@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"}) -public class NameIdFormatFilterTarget extends AbstractAuditable implements IFilterTarget { +@JsonIgnoreProperties({ "handler", "hibernateLazyInitializer" }) +public class NameIdFormatFilterTarget extends AbstractFilterTarget { private NameIdFormatFilterTargetType nameIdFormatFilterTargetType; - @ElementCollection - @OrderColumn - @Column(name="target_value") - private List value; - public NameIdFormatFilterTargetType getNameIdFormatFilterTargetType() { return nameIdFormatFilterTargetType; } @@ -41,24 +30,10 @@ public String getTargetTypeValue() { return nameIdFormatFilterTargetType.name(); } - public List getValue() { - return value; - } - public void setNameIdFormatFilterTargetType(NameIdFormatFilterTargetType nameIdFormatFilterTargetType) { this.nameIdFormatFilterTargetType = nameIdFormatFilterTargetType; } - public void setSingleValue(String value) { - List values = new ArrayList<>(); - values.add(value); - this.value = values; - } - - public void setValue(List value) { - this.value = value; - } - public enum NameIdFormatFilterTargetType { ENTITY, CONDITION_SCRIPT, REGEX } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AlgorithmFilter.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AlgorithmFilter.java index 85a4d9129..52e08b436 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AlgorithmFilter.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AlgorithmFilter.java @@ -1,54 +1,46 @@ package edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm; -import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractXMLObject; +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.IFilterTarget; +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.ITargetable; import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter; -import edu.internet2.tier.shibboleth.admin.ui.domain.filters.SignatureValidationFilter; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; import org.hibernate.envers.Audited; -import org.opensaml.core.xml.ElementExtensibleXMLObject; -import org.opensaml.core.xml.XMLObject; -import javax.annotation.Nonnull; import javax.persistence.CascadeType; import javax.persistence.ElementCollection; import javax.persistence.Entity; -import javax.persistence.OneToMany; +import javax.persistence.OneToOne; import javax.persistence.OrderColumn; -import javax.xml.namespace.QName; -import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; -/** - * Following the pattern of AbstractElementExtensibleXMLObject - this XML type can hold a couple of different types of XML objects - */ @Entity @Audited @Getter @Setter @ToString @EqualsAndHashCode(callSuper = true) -public class AlgorithmFilter extends MetadataFilter { - @OneToMany(cascade = CascadeType.ALL) +public class AlgorithmFilter extends MetadataFilter implements ITargetable { + @OneToOne(cascade = CascadeType.ALL) private AlgorithmFilterTarget algorithmFilterTarget; + + @ElementCollection @OrderColumn - private List unknownXMLObjects = new ArrayList<>(); + private List algorithms; - public void addUnknownXMLObject(AbstractXMLObject xmlObject) { - this.unknownXMLObjects.add(xmlObject); + public AlgorithmFilter() { + type = "Algorithm"; } - @Nonnull - public List getUnknownXMLObjects() { - return (List) (List) this.unknownXMLObjects; + @Override + public IFilterTarget getTarget() { + return algorithmFilterTarget; } private AlgorithmFilter updateConcreteFilterTypeData(AlgorithmFilter filterToBeUpdated) { - for (XMLObject o : getUnknownXMLObjects()) { - filterToBeUpdated.addUnknownXMLObject((AbstractXMLObject) o); - } + filterToBeUpdated.setAlgorithms(getAlgorithms()); + filterToBeUpdated.setAlgorithmFilterTarget(getAlgorithmFilterTarget()); return filterToBeUpdated; } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AlgorithmFilterTarget.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AlgorithmFilterTarget.java new file mode 100644 index 000000000..558231038 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/AlgorithmFilterTarget.java @@ -0,0 +1,34 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractAuditable; +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.AbstractFilterTarget; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.hibernate.envers.AuditOverride; +import org.hibernate.envers.Audited; + +import javax.persistence.Entity; + +@Entity +@EqualsAndHashCode(callSuper = true) +@ToString +@Audited +@AuditOverride(forClass = AbstractAuditable.class) +@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"}) +public class AlgorithmFilterTarget extends AbstractFilterTarget { + private AlgorithmFilterTargetType targetType; + + @Override + public String getTargetTypeValue() { + return targetType == null ? "NONE" : targetType.name(); + } + + public void setAlgorithmFilterTargetType(AlgorithmFilterTargetType type) { + this.targetType = type; + } + + public enum AlgorithmFilterTargetType { + ENTITY, CONDITION_SCRIPT, CONDITION_REF + } +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/ConditionRef.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/ConditionRef.java deleted file mode 100644 index b35cd0762..000000000 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/ConditionRef.java +++ /dev/null @@ -1,38 +0,0 @@ -package edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm; - -import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractXMLObject; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; -import org.hibernate.envers.Audited; - -import javax.annotation.Nullable; - -@javax.persistence.Entity -@Audited -@Getter -@Setter -@ToString -@EqualsAndHashCode(callSuper = true) -/** - * The textual content (the value/uri) is the Bean ID of type Predicate - */ -public class ConditionRef extends AbstractXMLObject implements org.opensaml.core.xml.schema.XSString { - private String uri; - - public ConditionRef() { - setElementLocalName("ConditionRef"); - } - - @Nullable - @Override - public String getValue() { - return this.uri; - } - - @Override - public void setValue(@Nullable String newValue) { - this.uri = newValue; - } -} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/ConditionScript.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/ConditionScript.java deleted file mode 100644 index a2d58382a..000000000 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/ConditionScript.java +++ /dev/null @@ -1,38 +0,0 @@ -package edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm; - -import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractXMLObject; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; -import org.hibernate.envers.Audited; - -import javax.annotation.Nullable; - -@javax.persistence.Entity -@Audited -@Getter -@Setter -@ToString -@EqualsAndHashCode(callSuper = true) -/** - * The textual content is the JS script (the export of the XML will wrap it appropriately) - */ -public class ConditionScript extends AbstractXMLObject implements org.opensaml.core.xml.schema.XSString { - private String uri; - - public ConditionScript() { - setElementLocalName("ConditionScript"); - } - - @Nullable - @Override - public String getValue() { - return this.uri; - } - - @Override - public void setValue(@Nullable String newValue) { - this.uri = newValue; - } -} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/Entity.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/Entity.java deleted file mode 100644 index 18dfcbe8e..000000000 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/algorithm/Entity.java +++ /dev/null @@ -1,38 +0,0 @@ -package edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm; - -import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractXMLObject; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; -import org.hibernate.envers.Audited; - -import javax.annotation.Nullable; - -@javax.persistence.Entity -@Audited -@Getter -@Setter -@ToString -@EqualsAndHashCode(callSuper = true) -/** - * The textual content (value/uri) is an entityID. - */ -public class Entity extends AbstractXMLObject implements org.opensaml.core.xml.schema.XSString { - private String uri; - - public Entity(){ - setElementLocalName("Entity"); - } - - @Nullable - @Override - public String getValue() { - return this.uri; - } - - @Override - public void setValue(@Nullable String newValue) { - this.uri = newValue; - } -} \ No newline at end of file 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 b44e4e7ce..4e7da170f 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 @@ -105,4 +105,16 @@ public static JsonSchemaResourceLocation nameIdFormatFilterSchema(JsonSchemaReso .lookup(NAME_ID_FORMAT_FILTER) .orElseThrow(() -> new IllegalStateException("JSON schema resource location for name id format filter is not registered.")); } + +// /** +// * Searches algorithm filter JSON schema resource location object in the given location registry. +// * +// * @param resourceLocationRegistry +// * @return algorithm filter JSON schema resource location object +// * @throws IllegalStateException if schema is not found in the given registry +// */ +// public static JsonSchemaResourceLocation algorithmFilterSchema(JsonSchemaResourceLocationRegistry resourceLocationRegistry) { +// return resourceLocationRegistry.lookup(ALGORITHM_FILTER) +// .orElseThrow(() -> new IllegalStateException("JSON schema resource location for algorithm filter is not registered.")); +// } } \ No newline at end of file diff --git a/backend/src/main/resources/algorithm-filter.schema.json b/backend/src/main/resources/algorithm-filter.schema.json new file mode 100644 index 000000000..642acbb4b --- /dev/null +++ b/backend/src/main/resources/algorithm-filter.schema.json @@ -0,0 +1,33 @@ +{ + "type": "object", + "required": [ + "name" + ], + "properties": { + "@type": { + "type": "string", + "default": "Algorithm" + }, + "name": { + "title": "label.filter-algorithm", + "description": "tooltip.filter-algorithm", + "type": "string" + }, + "filterEnabled": { + "title": "label.enable-filter", + "description": "tooltip.enable-filter", + "type": "boolean", + "default": false + }, + "version": { + "type": "integer" + }, + "resourceId": { + "type": "string" + }, + "unknownXMLObjects": { + + } + }, + "definitions": {} +} \ No newline at end of file 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 505d1507a..4fe54e9cc 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 @@ -1,23 +1,17 @@ package edu.internet2.tier.shibboleth.admin.ui.service - import edu.internet2.tier.shibboleth.admin.ui.AbstractBaseDataJpaTest import edu.internet2.tier.shibboleth.admin.ui.configuration.PlaceholderResolverComponentsConfiguration import edu.internet2.tier.shibboleth.admin.ui.configuration.ShibUIConfiguration import edu.internet2.tier.shibboleth.admin.ui.domain.AlgorithmDigestMethod import edu.internet2.tier.shibboleth.admin.ui.domain.EncryptionMethod import edu.internet2.tier.shibboleth.admin.ui.domain.SignatureDigestMethod -import edu.internet2.tier.shibboleth.admin.ui.domain.SigningMethod import edu.internet2.tier.shibboleth.admin.ui.domain.XSString import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilFilter -import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.ConditionRef -import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.ConditionScript -import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.Entity -import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.MGF -import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.PRF +import edu.internet2.tier.shibboleth.admin.ui.domain.filters.algorithm.AlgorithmFilterTarget import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ClasspathMetadataResource import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetadataResolver import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ExternalMetadataResolver @@ -194,101 +188,45 @@ class JPAMetadataResolverServiceImplTests extends AbstractBaseDataJpaTest { !diff.hasDifferences() } - def 'test generating AlgorithmFilter xml snippet'() { + def 'test generating AlgorithmFilter shibui-2268 entities'() { given: def filter = TestObjectGenerator.algorithmFilter() - EncryptionMethod encryptionMethod = new EncryptionMethod() - encryptionMethod.setElementLocalName(EncryptionMethod.DEFAULT_ELEMENT_LOCAL_NAME) - encryptionMethod.setNamespacePrefix(SAMLConstants.SAML20MD_PREFIX) - encryptionMethod.setNamespaceURI(SAMLConstants.SAML20MD_NS) - encryptionMethod.setSchemaLocation(SAMLConstants.SAML20MD_SCHEMA_LOCATION) - encryptionMethod.setAlgorithm("http://www.w3.org/2001/04/xmlenc#aes128-cbc") - filter.addUnknownXMLObject(encryptionMethod) - - Entity entity = new Entity() - entity.setValue("https://broken.example.org/sp") - filter.addUnknownXMLObject(entity) - Entity entity2 = new Entity() - entity2.setValue("https://also-broken.example.org/sp") - filter.addUnknownXMLObject(entity2) + ArrayList algs = new ArrayList<>() + algs.add("http://www.w3.org/2001/04/xmlenc#aes128-cbc") + filter.setAlgorithms(algs) + + AlgorithmFilterTarget target = new AlgorithmFilterTarget() + target.setAlgorithmFilterTargetType(AlgorithmFilterTarget.AlgorithmFilterTargetType.ENTITY) + ArrayList entities = new ArrayList<>() + entities.add("https://broken.example.org/sp") + entities.add("https://also-broken.example.org/sp") + target.setValue(entities) + filter.setAlgorithmFilterTarget(target) when: genXmlSnippet(markupBuilder) { JPAMetadataResolverServiceImpl.cast(metadataResolverService).constructXmlNodeForFilter(filter, it) } then: - generatedXmlIsTheSameAsExpectedXml('/conf/2268-simple.xml', domBuilder.parseText(writer.toString())) + generatedXmlIsTheSameAsExpectedXml('/conf/2268-entity.xml', domBuilder.parseText(writer.toString())) } - def 'test generating AlgorithmFilter shibui-2268 actual'() { + def 'test generating AlgorithmFilter shibui-2268 script'() { given: def filter = TestObjectGenerator.algorithmFilter() - EncryptionMethod encryptionMethod = new EncryptionMethod() - encryptionMethod.setElementLocalName(EncryptionMethod.DEFAULT_ELEMENT_LOCAL_NAME) - encryptionMethod.setNamespacePrefix(SAMLConstants.SAML20MD_PREFIX) - encryptionMethod.setNamespaceURI(SAMLConstants.SAML20MD_NS) - encryptionMethod.setSchemaLocation(SAMLConstants.SAML20MD_SCHEMA_LOCATION) - encryptionMethod.setAlgorithm("http://www.w3.org/2001/04/xmlenc#aes128-cbc") - filter.addUnknownXMLObject(encryptionMethod) + ArrayList algs = new ArrayList<>() + algs.add("http://www.w3.org/2001/04/xmlenc#aes128-cbc") + filter.setAlgorithms(algs) - Entity entity = new Entity() - entity.setValue("https://broken.example.org/sp") - filter.addUnknownXMLObject(entity) - - ConditionRef cr = new ConditionRef() - cr.setValue("shibboleth.Conditions.TRUE") - filter.addUnknownXMLObject(cr) - - ConditionScript cs = new ConditionScript() - cs.setValue("\"use strict\";\nfalse;") - filter.addUnknownXMLObject(cs) - - when: - genXmlSnippet(markupBuilder) { JPAMetadataResolverServiceImpl.cast(metadataResolverService).constructXmlNodeForFilter(filter, it) } - - then: - generatedXmlIsTheSameAsExpectedXml('/conf/2268-actual.xml', domBuilder.parseText(writer.toString())) - } - - /** - * This test was written before we simplified the concept of what we'd allow the users to build in the UI. Because the test was - * already done and working, it was left here for completeness. - */ - def 'test generating complex AlgorithmFilter xml snippet'() { - given: - def filter = TestObjectGenerator.algorithmFilter() - EncryptionMethod encryptionMethod = getEncryptionMethod("http://www.w3.org/2001/04/xmlenc#aes128-cbc") - filter.addUnknownXMLObject(encryptionMethod) - - EncryptionMethod encryptionMethod2 = getEncryptionMethod("http://www.w3.org/2009/xmlenc11#rsa-oaep") - MGF mgf = new MGF() - mgf.setAlgorithm("http://www.w3.org/2009/xmlenc11#mgf1sha256") - encryptionMethod2.addUnknownXMLObject(mgf) - PRF prf = new PRF() - prf.setAlgorithm("http://www.w3.org/2009/xmlenc11#mgf1sha384") - encryptionMethod2.addUnknownXMLObject(prf) - SignatureDigestMethod dm = getSignatureDigestMethod("http://www.w3.org/2001/04/xmlenc#sha256") - encryptionMethod2.addUnknownXMLObject(dm) - filter.addUnknownXMLObject(encryptionMethod2) - - AlgorithmDigestMethod dm2 = getDigestMethod("http://www.w3.org/2001/04/xmlenc#sha51") - filter.addUnknownXMLObject(dm2) - - SigningMethod sm = new SigningMethod() - sm.setNamespaceURI(SAMLConstants.SAML20ALG_NS) - sm.setElementLocalName(SigningMethod.DEFAULT_ELEMENT_LOCAL_NAME) - sm.setNamespacePrefix(SAMLConstants.SAML20ALG_PREFIX) - sm.setAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512") - filter.addUnknownXMLObject(sm) - - Entity entity = new Entity() - entity.setValue("https://broken.example.org/sp") - filter.addUnknownXMLObject(entity) + AlgorithmFilterTarget target = new AlgorithmFilterTarget() + target.setAlgorithmFilterTargetType(AlgorithmFilterTarget.AlgorithmFilterTargetType.CONDITION_SCRIPT) + target.setSingleValue("\"use strict\";\nfalse;") + filter.setAlgorithmFilterTarget(target) when: genXmlSnippet(markupBuilder) { JPAMetadataResolverServiceImpl.cast(metadataResolverService).constructXmlNodeForFilter(filter, it) } then: - generatedXmlIsTheSameAsExpectedXml('/conf/2268-complex.xml', domBuilder.parseText(writer.toString())) + generatedXmlIsTheSameAsExpectedXml('/conf/2268-script.xml', domBuilder.parseText(writer.toString())) } def 'test generating EntityAttributesFilter xml snippet with condition script'() { diff --git a/backend/src/test/resources/conf/2268-complex.xml b/backend/src/test/resources/conf/2268-complex.xml deleted file mode 100644 index ee76b2f84..000000000 --- a/backend/src/test/resources/conf/2268-complex.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - https://broken.example.org/sp - - - \ No newline at end of file diff --git a/backend/src/test/resources/conf/2268-simple.xml b/backend/src/test/resources/conf/2268-entity.xml similarity index 100% rename from backend/src/test/resources/conf/2268-simple.xml rename to backend/src/test/resources/conf/2268-entity.xml diff --git a/backend/src/test/resources/conf/2268-actual.xml b/backend/src/test/resources/conf/2268-script.xml similarity index 95% rename from backend/src/test/resources/conf/2268-actual.xml rename to backend/src/test/resources/conf/2268-script.xml index 961079197..3283e883c 100644 --- a/backend/src/test/resources/conf/2268-actual.xml +++ b/backend/src/test/resources/conf/2268-script.xml @@ -14,8 +14,6 @@ xsi:type="Algorithm"> - https://broken.example.org/sp - shibboleth.Conditions.TRUE