From 428e2b0449b2b886fd5291c5f15e2326fb8e09c2 Mon Sep 17 00:00:00 2001 From: Sean Porth Date: Fri, 29 Jul 2022 14:01:19 -0400 Subject: [PATCH 01/71] init setup Former-commit-id: 1b0d9f85c1bfa32b897b5cf9586bc9a92493a7e3 --- testbed/smoke-test/cheat.html | 110 ++++++++++++++++++++++ testbed/smoke-test/docker-compose.yml | 105 +++++++++++++++++++++ testbed/smoke-test/shibui/application.yml | 40 ++++++++ 3 files changed, 255 insertions(+) create mode 100644 testbed/smoke-test/cheat.html create mode 100644 testbed/smoke-test/docker-compose.yml create mode 100644 testbed/smoke-test/shibui/application.yml diff --git a/testbed/smoke-test/cheat.html b/testbed/smoke-test/cheat.html new file mode 100644 index 000000000..74682f912 --- /dev/null +++ b/testbed/smoke-test/cheat.html @@ -0,0 +1,110 @@ + + +

Reload Service

+
+ + + +
+

Attribute Resolution

+
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + +
+
+

Metadata Query

+ + + + + +
+ + + +
+ +
+
+

Reload Metadata

+ + + + + +
+ + + +
+ +
+
+

Unsolicited SSO

+ + + + + +
+ + + +
+ +
+metrics + + diff --git a/testbed/smoke-test/docker-compose.yml b/testbed/smoke-test/docker-compose.yml new file mode 100644 index 000000000..ec2f2c854 --- /dev/null +++ b/testbed/smoke-test/docker-compose.yml @@ -0,0 +1,105 @@ +version: "3.8" + +services: + reverse-proxy: + image: library/traefik:v2.5.2 + command: + - "--api.insecure=true" + - "--providers.docker=true" + - "--providers.docker.exposedbydefault=false" + - "--entrypoints.web-secure.address=:443" + - "--providers.file.directory=/configuration/" + - "--providers.file.watch=true" + # - "--log.level=DEBUG" + networks: + reverse-proxy: + aliases: + - idp.unicon.local + ports: + - "80:80" + - "8080:8080" + - "443:443" + - "8443:8443" + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ../reverse-proxy/:/configuration/ + - ../reverse-proxy/certs/:/certs/ + directory: + build: ../directory + networks: + - idp + volumes: + - directory_data:/var/lib/ldap + - directory_config:/etc/ldap/slapd.d + - ../directory/certs:/container/service/slapd/assets/certs + environment: + LDAP_BASE_DN: "dc=unicon,dc=local" + LDAP_DOMAIN: "unicon.local" + HOSTNAME: "directory" + LDAP_TLS_VERIFY_CLIENT: "try" + idp: + build: ../integration/shibboleth-idp + labels: + - "traefik.http.routers.idp.rule=Host(`idp.unicon.local`)" + - "traefik.http.services.idp.loadbalancer.server.port=8080" + - "traefik.http.routers.idp.tls=true" + - "traefik.docker.network=integration_reverse-proxy" + - "traefik.enable=true" + depends_on: + - directory + - reverse-proxy + networks: + - reverse-proxy + - idp + volumes: + - ../directory/certs/ca.crt:/opt/shibboleth-idp/credentials/ldap-server.crt + - dynamic_metadata:/opt/shibboleth-idp/metadata/dynamic + - dynamic_config:/opt/shibboleth-idp/conf/dynamic + - ../integration/shibboleth-idp/metadata/dynamic:/opt/shibboleth-idp/metadata/dynamic + - ../authentication/shibboleth-idp/config/shib-idp/conf/attribute-filter.xml:/opt/shibboleth-idp/conf/attribute-filter.xml + healthcheck: + disable: true + shib-idp-ui: + image: unicon/shibui:latest + labels: + - "traefik.http.routers.shibui.rule=Host(`shibui.unicon.local`)" + - "traefik.http.services.shibui.loadbalancer.server.port=8080" + - "traefik.http.routers.shibui.tls=true" + - "traefik.docker.network=integration_reverse-proxy" + - "traefik.enable=true" + networks: + - reverse-proxy + - backend + volumes: + - ../authentication/shibui:/conf + - ./shibui/application.yml:/application.yml + - dynamic_metadata:/var/shibboleth/dynamic_metadata + - dynamic_config:/var/shibboleth/dynamic_config + - ../integration/shibboleth-idp/credentials/shib-idp/inc-md-cert-mdq.pem:/opt/shibboleth-idp/credentials/inc-md-cert-mdq.pem + environment: + - "IDP_HOME=/opt/shibboleth-idp" + database: + image: postgres:14-alpine + environment: + POSTGRES_PASSWORD: shibui + POSTGRES_USER: shibui + POSTGRES_DB: shibui + networks: + - backend + volumes: + - database_data:/var/lib/postgresql/data +networks: + reverse-proxy: + idp: + backend: +volumes: + directory_data: + driver: local + directory_config: + driver: local + dynamic_metadata: + driver: local + dynamic_config: + driver: local + database_data: + driver: local diff --git a/testbed/smoke-test/shibui/application.yml b/testbed/smoke-test/shibui/application.yml new file mode 100644 index 000000000..126256f0d --- /dev/null +++ b/testbed/smoke-test/shibui/application.yml @@ -0,0 +1,40 @@ +server: + forward-headers-strategy: NATIVE +spring: + profiles: + include: + datasource: + platform: postgres + driver-class-name: org.postgresql.Driver + url: jdbc:postgresql://database:5432/shibui + username: shibui + password: shibui + jpa: + properties: + hibernate: + dialect: org.hibernate.dialect.PostgreSQLDialect +shibui: + default-password: "{noop}letmein7" + metadata-dir: /var/shibboleth/dynamic_metadata + metadataProviders: + target: file:/var/shibboleth/dynamic_config/metadata-providers.xml + user-bootstrap-resource: file:/conf/users.csv + roles: ROLE_ADMIN,ROLE_NONE,ROLE_USER,ROLE_ENABLE,ROLE_PONY + pac4j-enabled: true + pac4j: + keystorePath: "/conf/samlKeystore.jks" + keystorePassword: "changeit" + privateKeyPassword: "changeit" + serviceProviderEntityId: "https://unicon.net/test/shibui" + serviceProviderMetadataPath: "/conf/sp-metadata.xml" + identityProviderMetadataPath: "/conf/idp-metadata.xml" + forceServiceProviderMetadataGeneration: true + callbackUrl: "https://shibui.unicon.local/callback" + maximumAuthenticationLifetime: 3600000 + simpleProfileMapping: + username: urn:oid:0.9.2342.19200300.100.1.1 + firstName: urn:oid:2.5.4.42 + lastName: urn:oid:2.5.4.4 + email: urn:oid:0.9.2342.19200300.100.1.3 + groups: urn:oid:2.5.4.15 # businessCategory + roles: urn:oid:1.3.6.1.4.1.5923.1.1.1.7 # eduPersonEntitlement From 8e9c695e29ae4003b82169aaa6eb5dcea8984cdb Mon Sep 17 00:00:00 2001 From: Sean Porth Date: Fri, 5 Aug 2022 14:45:00 -0400 Subject: [PATCH 02/71] auth and integration testbeds combined Former-commit-id: 9adbe95312c2bc7482005da48d9b8d6be7732023 --- testbed/smoke-test/docker-compose.yml | 17 +-- .../shibboleth-idp/conf/access-control.xml | 68 ++++++++++++ .../conf/metadata-providers.xml | 101 ++++++++++++++++++ .../metadata/test-provider-config.xml | 38 +++++++ 4 files changed, 217 insertions(+), 7 deletions(-) create mode 100644 testbed/smoke-test/shibboleth-idp/conf/access-control.xml create mode 100644 testbed/smoke-test/shibboleth-idp/conf/metadata-providers.xml create mode 100644 testbed/smoke-test/shibboleth-idp/metadata/test-provider-config.xml diff --git a/testbed/smoke-test/docker-compose.yml b/testbed/smoke-test/docker-compose.yml index ec2f2c854..0c92cad01 100644 --- a/testbed/smoke-test/docker-compose.yml +++ b/testbed/smoke-test/docker-compose.yml @@ -10,7 +10,7 @@ services: - "--entrypoints.web-secure.address=:443" - "--providers.file.directory=/configuration/" - "--providers.file.watch=true" - # - "--log.level=DEBUG" + #- "--log.level=DEBUG" networks: reverse-proxy: aliases: @@ -43,7 +43,7 @@ services: - "traefik.http.routers.idp.rule=Host(`idp.unicon.local`)" - "traefik.http.services.idp.loadbalancer.server.port=8080" - "traefik.http.routers.idp.tls=true" - - "traefik.docker.network=integration_reverse-proxy" + - "traefik.docker.network=smoke-test_reverse-proxy" - "traefik.enable=true" depends_on: - directory @@ -52,11 +52,14 @@ services: - reverse-proxy - idp volumes: - - ../directory/certs/ca.crt:/opt/shibboleth-idp/credentials/ldap-server.crt - dynamic_metadata:/opt/shibboleth-idp/metadata/dynamic - dynamic_config:/opt/shibboleth-idp/conf/dynamic - - ../integration/shibboleth-idp/metadata/dynamic:/opt/shibboleth-idp/metadata/dynamic + - ../directory/certs/ca.crt:/opt/shibboleth-idp/credentials/ldap-server.crt - ../authentication/shibboleth-idp/config/shib-idp/conf/attribute-filter.xml:/opt/shibboleth-idp/conf/attribute-filter.xml + - ./shibboleth-idp/conf/metadata-providers.xml:/opt/shibboleth-idp/conf/metadata-providers.xml + - ./shibboleth-idp/conf/access-control.xml:/opt/shibboleth-idp/conf/access-control.xml + - ./shibboleth-idp/metadata/test-provider-config.xml:/opt/shibboleth-idp/metadata/test-provider-config.xml + - ../integration/shibboleth-idp/metadata/dynamic/700bfe6fa4495100f5c193fa5b7ca4192c150923.xml:/opt/shibboleth-idp/metadata/700bfe6fa4495100f5c193fa5b7ca4192c150923.xml healthcheck: disable: true shib-idp-ui: @@ -65,16 +68,16 @@ services: - "traefik.http.routers.shibui.rule=Host(`shibui.unicon.local`)" - "traefik.http.services.shibui.loadbalancer.server.port=8080" - "traefik.http.routers.shibui.tls=true" - - "traefik.docker.network=integration_reverse-proxy" + - "traefik.docker.network=smoke-test_reverse-proxy" - "traefik.enable=true" networks: - reverse-proxy - backend volumes: - - ../authentication/shibui:/conf - - ./shibui/application.yml:/application.yml - dynamic_metadata:/var/shibboleth/dynamic_metadata - dynamic_config:/var/shibboleth/dynamic_config + - ../authentication/shibui:/conf + - ./shibui/application.yml:/application.yml - ../integration/shibboleth-idp/credentials/shib-idp/inc-md-cert-mdq.pem:/opt/shibboleth-idp/credentials/inc-md-cert-mdq.pem environment: - "IDP_HOME=/opt/shibboleth-idp" diff --git a/testbed/smoke-test/shibboleth-idp/conf/access-control.xml b/testbed/smoke-test/shibboleth-idp/conf/access-control.xml new file mode 100644 index 000000000..053bc22c7 --- /dev/null +++ b/testbed/smoke-test/shibboleth-idp/conf/access-control.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/testbed/smoke-test/shibboleth-idp/conf/metadata-providers.xml b/testbed/smoke-test/shibboleth-idp/conf/metadata-providers.xml new file mode 100644 index 000000000..bd90a4751 --- /dev/null +++ b/testbed/smoke-test/shibboleth-idp/conf/metadata-providers.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://mdq.incommon.org/ + + + diff --git a/testbed/smoke-test/shibboleth-idp/metadata/test-provider-config.xml b/testbed/smoke-test/shibboleth-idp/metadata/test-provider-config.xml new file mode 100644 index 000000000..caec9caf4 --- /dev/null +++ b/testbed/smoke-test/shibboleth-idp/metadata/test-provider-config.xml @@ -0,0 +1,38 @@ + + + + + + +MIIECDCCAnCgAwIBAgIUXOD+38b0Cpaynm5Wrclnzigz9rcwDQYJKoZIhvcNAQEL +BQAwHTEbMBkGA1UEAxMSdW5pY29uLXNwb3J0aC0yNjU4MB4XDTIyMDgwNTE3MDE1 +NloXDTMyMDgwMjE3MDE1NlowHTEbMBkGA1UEAxMSdW5pY29uLXNwb3J0aC0yNjU4 +MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAynP0dUXXr0yb4oAYT5OG +/ik+24jor0W0Z/0T0g3C4IXqDMHMdHlfPSrp6rf+PDlS+0L+GCZQC2IpntmGNEdf +miCs9UcssZ3aBHoch0R0Og4rxu74Vk488NVXHsX75RTom5B0atPGxdmHRNIPUPNp +F4AqAMMV18y35+ElJj5UuPZe9QEgJVzGqdH0dGvaNFPZfB7HCD7lGJiO0Remhufn +umwrRqfQETmefCD4Wrv60I4LgUrUSqlZTpD4TaR3o1N6uSKaJPy7iANqQXoEqc3p +jbiM+Tkv6t+q6FbEIF3zKwODzHcycaVYzqOxzVMGWtyPADBm3P/8wvDZnHWEqAcy +9cHY7THHq8s6bdR8aIO+T0uvIqXJAO0orGVJ4b1X2OBRRneUVtxFbzbAXWN+wwKW +Xn8M1sP9hteV9CAkp4nbyPnfwWlZYaN48QytMZhu3oQywlcc/VuDEst04IeAt/1f +YTWmSliJwAduFXpRtQjgB/ejfLUkJHugNJe2N23dNb8ZAgMBAAGjQDA+MB0GA1Ud +EQQWMBSCEnVuaWNvbi1zcG9ydGgtMjY1ODAdBgNVHQ4EFgQUuAUQzGLs2Psbx5aw +ec5sz66h4TIwDQYJKoZIhvcNAQELBQADggGBAEqDt2lXrAEJ80yWLYZKM2qdif5j +DbFI4oGMJ+6Wicfjh9iSm6CG2pSdZllypNLd7KmUJbGFS5wmP7qPAiPLOiHn6hBC +L5ke3y8bJsaEazOmZt0IgKv2w6naEAfvR5dKbEbXsipf/k+WHyk6uLFoz9iGxZ0g +f8MA+nWa1tJcPcGVOReN3wNNeBaRZ5y0r6oWSpwYtoBJH+wp2EoLPYhOXFjUoAZ0 +d4b+G2x9FyHU4yfnN9sTLocl/BVDiVdazMQqSvZDSWbccRsD8sz4BaLnXkLOtulv +0qOYuVTdCivgU0lBMhvXjiEpn0ZwU+UlSgtfEgaVP8pZVgHxKrMhoOxAe85dNHun +RyYCrByqg4lyFGzRKSTAUlx0YittvEyYOEqbSsXExViSIl+elg4PtghsYAaUphm4 ++FHJo8B1rNNQp4vqikGF2WOr3D2usIS9ZbiGvTC0M8TSG39jGCqgQZaclV2yshEC +cXQllPfIyCtMzlaGVjpXPEqahwkug4ywml9yAw== + + + + + + + + + + From 9fc79c1b338d4d847664038c05e3d73a7acdae49 Mon Sep 17 00:00:00 2001 From: Sean Porth Date: Mon, 8 Aug 2022 15:59:20 -0400 Subject: [PATCH 03/71] added ability to switch database backends Former-commit-id: df22df0198e0d0feccb6311d9a5834d75fb32edc --- .../mariadb.docker-compose.override.yml | 19 +++++++++++++ testbed/smoke-test/db_configs/mariadb.yml | 13 +++++++++ .../mysql.docker-compose.override.yml | 19 +++++++++++++ testbed/smoke-test/db_configs/mysql.yml | 13 +++++++++ testbed/smoke-test/db_configs/postgres.yml | 13 +++++++++ .../sqlServer.docker-compose.override.yml | 17 ++++++++++++ testbed/smoke-test/db_configs/sqlServer.yml | 13 +++++++++ testbed/smoke-test/docker-compose.yml | 22 ++++++++------- testbed/smoke-test/setdb.sh | 22 +++++++++++++++ testbed/smoke-test/shibui/application.yml | 26 +++++++++--------- .../smoke-test/shibui/application.yml.nodb | 27 +++++++++++++++++++ 11 files changed, 181 insertions(+), 23 deletions(-) create mode 100644 testbed/smoke-test/db_configs/mariadb.docker-compose.override.yml create mode 100644 testbed/smoke-test/db_configs/mariadb.yml create mode 100644 testbed/smoke-test/db_configs/mysql.docker-compose.override.yml create mode 100644 testbed/smoke-test/db_configs/mysql.yml create mode 100644 testbed/smoke-test/db_configs/postgres.yml create mode 100644 testbed/smoke-test/db_configs/sqlServer.docker-compose.override.yml create mode 100644 testbed/smoke-test/db_configs/sqlServer.yml create mode 100755 testbed/smoke-test/setdb.sh create mode 100644 testbed/smoke-test/shibui/application.yml.nodb diff --git a/testbed/smoke-test/db_configs/mariadb.docker-compose.override.yml b/testbed/smoke-test/db_configs/mariadb.docker-compose.override.yml new file mode 100644 index 000000000..ad9f8ae09 --- /dev/null +++ b/testbed/smoke-test/db_configs/mariadb.docker-compose.override.yml @@ -0,0 +1,19 @@ +services: + database: + image: mariadb + environment: + MYSQL_DATABASE: shibui + MYSQL_USER: shibui + MYSQL_PASSWORD: shibui + MYSQL_ROOT_PASSWORD: root + healthcheck: + test: mysql -u shibui --password=shibui shibui -e "select 1" + interval: 5s + retries: 5 + start_period: 5s + timeout: 10s + shib-idp-ui: + depends_on: + database: + condition: service_healthy + \ No newline at end of file diff --git a/testbed/smoke-test/db_configs/mariadb.yml b/testbed/smoke-test/db_configs/mariadb.yml new file mode 100644 index 000000000..9b64f680f --- /dev/null +++ b/testbed/smoke-test/db_configs/mariadb.yml @@ -0,0 +1,13 @@ +spring: + profiles: + include: + datasource: + platform: mysql + driver-class-name: com.mariadb.jdbc.Driver + url: jdbc:mariadb://database:3306/shibui + username: shibui + password: shibui + jpa: + properties: + hibernate: + dialect: org.hibernate.dialect.MariaDB103Dialect diff --git a/testbed/smoke-test/db_configs/mysql.docker-compose.override.yml b/testbed/smoke-test/db_configs/mysql.docker-compose.override.yml new file mode 100644 index 000000000..6d511c7e6 --- /dev/null +++ b/testbed/smoke-test/db_configs/mysql.docker-compose.override.yml @@ -0,0 +1,19 @@ +services: + database: + image: mysql + environment: + MYSQL_DATABASE: shibui + MYSQL_USER: shibui + MYSQL_PASSWORD: shibui + MYSQL_ROOT_PASSWORD: root + healthcheck: + test: mysql -u shibui --password=shibui shibui -e "select 1" + interval: 5s + retries: 5 + start_period: 5s + timeout: 10s + shib-idp-ui: + depends_on: + database: + condition: service_healthy + \ No newline at end of file diff --git a/testbed/smoke-test/db_configs/mysql.yml b/testbed/smoke-test/db_configs/mysql.yml new file mode 100644 index 000000000..b3d434d8a --- /dev/null +++ b/testbed/smoke-test/db_configs/mysql.yml @@ -0,0 +1,13 @@ +spring: + profiles: + include: + datasource: + platform: mysql + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://database:3306/shibui + username: shibui + password: shibui + jpa: + properties: + hibernate: + dialect: org.hibernate.dialect.MySQL8Dialect diff --git a/testbed/smoke-test/db_configs/postgres.yml b/testbed/smoke-test/db_configs/postgres.yml new file mode 100644 index 000000000..c9117f2e5 --- /dev/null +++ b/testbed/smoke-test/db_configs/postgres.yml @@ -0,0 +1,13 @@ +spring: + profiles: + include: + datasource: + platform: postgres + driver-class-name: org.postgresql.Driver + url: jdbc:postgresql://database:5432/shibui + username: shibui + password: shibui + jpa: + properties: + hibernate: + dialect: org.hibernate.dialect.PostgreSQLDialect \ No newline at end of file diff --git a/testbed/smoke-test/db_configs/sqlServer.docker-compose.override.yml b/testbed/smoke-test/db_configs/sqlServer.docker-compose.override.yml new file mode 100644 index 000000000..13d5a0670 --- /dev/null +++ b/testbed/smoke-test/db_configs/sqlServer.docker-compose.override.yml @@ -0,0 +1,17 @@ +services: + database: + build: + context: ../sqlServer + dockerfile: ../sqlServer/docker/Dockerfile + image: smoke-test_database +# healthcheck: +# test: mysql -u shibui --password=shibui shibui -e "select 1" +# interval: 5s +# retries: 5 +# start_period: 5s +# timeout: 10s +# shib-idp-ui: +# depends_on: +# database: +# condition: service_healthy + \ No newline at end of file diff --git a/testbed/smoke-test/db_configs/sqlServer.yml b/testbed/smoke-test/db_configs/sqlServer.yml new file mode 100644 index 000000000..d6e7a3e68 --- /dev/null +++ b/testbed/smoke-test/db_configs/sqlServer.yml @@ -0,0 +1,13 @@ +spring: + profiles: + include: + datasource: + platform: sqlserver + driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver + url: jdbc:sqlserver://database:1433 + username: sa + password: Password1 + jpa: + properties: + hibernate: + dialect: org.hibernate.dialect.SQLServerDialect \ No newline at end of file diff --git a/testbed/smoke-test/docker-compose.yml b/testbed/smoke-test/docker-compose.yml index 0c92cad01..9e2ac5340 100644 --- a/testbed/smoke-test/docker-compose.yml +++ b/testbed/smoke-test/docker-compose.yml @@ -37,6 +37,14 @@ services: LDAP_DOMAIN: "unicon.local" HOSTNAME: "directory" LDAP_TLS_VERIFY_CLIENT: "try" + database: + image: postgres:14-alpine + networks: + - backend + environment: + POSTGRES_PASSWORD: shibui + POSTGRES_USER: shibui + POSTGRES_DB: shibui idp: build: ../integration/shibboleth-idp labels: @@ -70,6 +78,9 @@ services: - "traefik.http.routers.shibui.tls=true" - "traefik.docker.network=smoke-test_reverse-proxy" - "traefik.enable=true" + depends_on: + database: + condition: service_started networks: - reverse-proxy - backend @@ -81,16 +92,7 @@ services: - ../integration/shibboleth-idp/credentials/shib-idp/inc-md-cert-mdq.pem:/opt/shibboleth-idp/credentials/inc-md-cert-mdq.pem environment: - "IDP_HOME=/opt/shibboleth-idp" - database: - image: postgres:14-alpine - environment: - POSTGRES_PASSWORD: shibui - POSTGRES_USER: shibui - POSTGRES_DB: shibui - networks: - - backend - volumes: - - database_data:/var/lib/postgresql/data + networks: reverse-proxy: idp: diff --git a/testbed/smoke-test/setdb.sh b/testbed/smoke-test/setdb.sh new file mode 100755 index 000000000..e4347a298 --- /dev/null +++ b/testbed/smoke-test/setdb.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +DB=$1 + +if [[ ! "$DB" =~ ^(postgres|mariadb|mysql|sqlServer)$ ]]; +then + echo "argument mst be one of: postgres mariadb mysql sqlServer" + exit 0; +fi + +if [[ $DB == "postgres" ]]; +then +rm -f docker-compose.override.yml +else +rm -f docker-compose.override.yml +ln -s db_configs/$DB.docker-compose.override.yml docker-compose.override.yml +fi + +rm -f shibui/application.yml +cat shibui/application.yml.nodb db_configs/$DB.yml >> shibui/application.yml + +echo "shibui will now use the $DB container" diff --git a/testbed/smoke-test/shibui/application.yml b/testbed/smoke-test/shibui/application.yml index 126256f0d..df9137c0b 100644 --- a/testbed/smoke-test/shibui/application.yml +++ b/testbed/smoke-test/shibui/application.yml @@ -1,18 +1,5 @@ server: forward-headers-strategy: NATIVE -spring: - profiles: - include: - datasource: - platform: postgres - driver-class-name: org.postgresql.Driver - url: jdbc:postgresql://database:5432/shibui - username: shibui - password: shibui - jpa: - properties: - hibernate: - dialect: org.hibernate.dialect.PostgreSQLDialect shibui: default-password: "{noop}letmein7" metadata-dir: /var/shibboleth/dynamic_metadata @@ -38,3 +25,16 @@ shibui: email: urn:oid:0.9.2342.19200300.100.1.3 groups: urn:oid:2.5.4.15 # businessCategory roles: urn:oid:1.3.6.1.4.1.5923.1.1.1.7 # eduPersonEntitlement +spring: + profiles: + include: + datasource: + platform: postgres + driver-class-name: org.postgresql.Driver + url: jdbc:postgresql://database:5432/shibui + username: shibui + password: shibui + jpa: + properties: + hibernate: + dialect: org.hibernate.dialect.PostgreSQLDialect \ No newline at end of file diff --git a/testbed/smoke-test/shibui/application.yml.nodb b/testbed/smoke-test/shibui/application.yml.nodb new file mode 100644 index 000000000..b4a070c2c --- /dev/null +++ b/testbed/smoke-test/shibui/application.yml.nodb @@ -0,0 +1,27 @@ +server: + forward-headers-strategy: NATIVE +shibui: + default-password: "{noop}letmein7" + metadata-dir: /var/shibboleth/dynamic_metadata + metadataProviders: + target: file:/var/shibboleth/dynamic_config/metadata-providers.xml + user-bootstrap-resource: file:/conf/users.csv + roles: ROLE_ADMIN,ROLE_NONE,ROLE_USER,ROLE_ENABLE,ROLE_PONY + pac4j-enabled: true + pac4j: + keystorePath: "/conf/samlKeystore.jks" + keystorePassword: "changeit" + privateKeyPassword: "changeit" + serviceProviderEntityId: "https://unicon.net/test/shibui" + serviceProviderMetadataPath: "/conf/sp-metadata.xml" + identityProviderMetadataPath: "/conf/idp-metadata.xml" + forceServiceProviderMetadataGeneration: true + callbackUrl: "https://shibui.unicon.local/callback" + maximumAuthenticationLifetime: 3600000 + simpleProfileMapping: + username: urn:oid:0.9.2342.19200300.100.1.1 + firstName: urn:oid:2.5.4.42 + lastName: urn:oid:2.5.4.4 + email: urn:oid:0.9.2342.19200300.100.1.3 + groups: urn:oid:2.5.4.15 # businessCategory + roles: urn:oid:1.3.6.1.4.1.5923.1.1.1.7 # eduPersonEntitlement From dc3c0e281ce2b56406775b3f6d3ea30d260c20dc Mon Sep 17 00:00:00 2001 From: Sean Porth Date: Tue, 9 Aug 2022 09:47:23 -0400 Subject: [PATCH 04/71] cleanup, fix mariadb driver name Former-commit-id: 66dc0ef9e2ccd5738b3b3308be366ed224276b78 --- .../db_configs/{mariadb.yml => mariadb.application.yml} | 2 +- .../smoke-test/db_configs/{mysql.yml => mysql.application.yml} | 0 .../db_configs/{postgres.yml => postgres.application.yml} | 0 .../db_configs/{sqlServer.yml => sqlServer.application.yml} | 0 testbed/smoke-test/setdb.sh | 2 +- 5 files changed, 2 insertions(+), 2 deletions(-) rename testbed/smoke-test/db_configs/{mariadb.yml => mariadb.application.yml} (84%) rename testbed/smoke-test/db_configs/{mysql.yml => mysql.application.yml} (100%) rename testbed/smoke-test/db_configs/{postgres.yml => postgres.application.yml} (100%) rename testbed/smoke-test/db_configs/{sqlServer.yml => sqlServer.application.yml} (100%) diff --git a/testbed/smoke-test/db_configs/mariadb.yml b/testbed/smoke-test/db_configs/mariadb.application.yml similarity index 84% rename from testbed/smoke-test/db_configs/mariadb.yml rename to testbed/smoke-test/db_configs/mariadb.application.yml index 9b64f680f..a42a5c8bc 100644 --- a/testbed/smoke-test/db_configs/mariadb.yml +++ b/testbed/smoke-test/db_configs/mariadb.application.yml @@ -3,7 +3,7 @@ spring: include: datasource: platform: mysql - driver-class-name: com.mariadb.jdbc.Driver + driver-class-name: org.mariadb.jdbc.Driver url: jdbc:mariadb://database:3306/shibui username: shibui password: shibui diff --git a/testbed/smoke-test/db_configs/mysql.yml b/testbed/smoke-test/db_configs/mysql.application.yml similarity index 100% rename from testbed/smoke-test/db_configs/mysql.yml rename to testbed/smoke-test/db_configs/mysql.application.yml diff --git a/testbed/smoke-test/db_configs/postgres.yml b/testbed/smoke-test/db_configs/postgres.application.yml similarity index 100% rename from testbed/smoke-test/db_configs/postgres.yml rename to testbed/smoke-test/db_configs/postgres.application.yml diff --git a/testbed/smoke-test/db_configs/sqlServer.yml b/testbed/smoke-test/db_configs/sqlServer.application.yml similarity index 100% rename from testbed/smoke-test/db_configs/sqlServer.yml rename to testbed/smoke-test/db_configs/sqlServer.application.yml diff --git a/testbed/smoke-test/setdb.sh b/testbed/smoke-test/setdb.sh index e4347a298..06821b37c 100755 --- a/testbed/smoke-test/setdb.sh +++ b/testbed/smoke-test/setdb.sh @@ -17,6 +17,6 @@ ln -s db_configs/$DB.docker-compose.override.yml docker-compose.override.yml fi rm -f shibui/application.yml -cat shibui/application.yml.nodb db_configs/$DB.yml >> shibui/application.yml +cat shibui/application.yml.nodb db_configs/$DB.application.yml >> shibui/application.yml echo "shibui will now use the $DB container" From eb92a8c4dcd173c7b0fedeedd0475696081ff39f Mon Sep 17 00:00:00 2001 From: Sean Porth Date: Tue, 9 Aug 2022 12:48:05 -0400 Subject: [PATCH 05/71] typo Former-commit-id: 8651e6d3f8a6d18220b65ea350c570aa8a3b527c --- testbed/smoke-test/setdb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testbed/smoke-test/setdb.sh b/testbed/smoke-test/setdb.sh index 06821b37c..4795526a2 100755 --- a/testbed/smoke-test/setdb.sh +++ b/testbed/smoke-test/setdb.sh @@ -4,7 +4,7 @@ DB=$1 if [[ ! "$DB" =~ ^(postgres|mariadb|mysql|sqlServer)$ ]]; then - echo "argument mst be one of: postgres mariadb mysql sqlServer" + echo "argument must be one of: postgres mariadb mysql sqlServer" exit 0; fi From 9f79d25d5828ca70ed0badcc22d71f1334a30567 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Mon, 15 Aug 2022 14:59:04 -0700 Subject: [PATCH 06/71] SHIBUI-2333 Added logic to correctly support IDP logout Former-commit-id: b392b8396cd91660259297aaca91702987378f6e --- .../shibui/pac4j/Pac4jConfiguration.java | 34 ++++++++++++------- .../pac4j/Pac4jConfigurationProperties.java | 1 + .../net/unicon/shibui/pac4j/WebSecurity.java | 18 ++++++++-- testbed/authentication/shibui/application.yml | 1 + 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java index fd018d4b6..5853da065 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java @@ -8,6 +8,7 @@ import net.unicon.shibui.pac4j.authenticator.ShibuiSAML2Authenticator; import org.pac4j.core.client.Clients; import org.pac4j.core.config.Config; +import org.pac4j.core.engine.LogoutLogic; import org.pac4j.core.matching.matcher.PathMatcher; import org.pac4j.core.profile.definition.CommonProfileDefinition; import org.pac4j.http.client.direct.HeaderClient; @@ -69,32 +70,39 @@ public Config config(final Pac4jConfigurationProperties pac4jConfigProps, case "SAML2": default: log.info("**** Configuring PAC4J SAML2"); - final SAML2Configuration saml2Config = new SAML2Configuration(); - saml2Config.setKeystorePath(pac4jConfigProps.getKeystorePath()); - saml2Config.setKeystorePassword(pac4jConfigProps.getKeystorePassword()); - saml2Config.setPrivateKeyPassword(pac4jConfigProps.getPrivateKeyPassword()); - saml2Config.setIdentityProviderMetadataPath(pac4jConfigProps.getIdentityProviderMetadataPath()); - saml2Config.setMaximumAuthenticationLifetime(pac4jConfigProps.getMaximumAuthenticationLifetime()); - saml2Config.setServiceProviderEntityId(pac4jConfigProps.getServiceProviderEntityId()); - saml2Config.setServiceProviderMetadataPath(pac4jConfigProps.getServiceProviderMetadataPath()); - saml2Config.setForceServiceProviderMetadataGeneration(pac4jConfigProps.isForceServiceProviderMetadataGeneration()); - saml2Config.setWantsAssertionsSigned(pac4jConfigProps.isWantAssertionsSigned()); - saml2Config.setAttributeAsId(pac4jConfigProps.getSimpleProfileMapping().getUsername()); + final SAML2Configuration saml2Config = buildSaml2ConfigFromPac4JConfiguration(pac4jConfigProps); + final SAML2Client saml2Client = new SAML2Client(saml2Config); + saml2Client.setName(PAC4J_CLIENT_NAME); saml2Client.addAuthorizationGenerator(saml2ModelAuthorizationGenerator); SAML2Authenticator saml2Authenticator = new ShibuiSAML2Authenticator(saml2Config.getAttributeAsId(), saml2Config.getMappedAttributes(), userService); saml2Authenticator.setProfileDefinition(new CommonProfileDefinition(p -> new BetterSAML2Profile(pac4jConfigProps.getSimpleProfileMapping()))); saml2Client.setAuthenticator(saml2Authenticator); - saml2Client.setName(PAC4J_CLIENT_NAME); clients.setClients(saml2Client); break; } config.setClients(clients); return config; } - + + private SAML2Configuration buildSaml2ConfigFromPac4JConfiguration(Pac4jConfigurationProperties pac4jConfigProps) { + SAML2Configuration saml2Config = new SAML2Configuration(); + saml2Config.setKeystorePath(pac4jConfigProps.getKeystorePath()); + saml2Config.setKeystorePassword(pac4jConfigProps.getKeystorePassword()); + saml2Config.setPrivateKeyPassword(pac4jConfigProps.getPrivateKeyPassword()); + saml2Config.setIdentityProviderMetadataPath(pac4jConfigProps.getIdentityProviderMetadataPath()); + saml2Config.setMaximumAuthenticationLifetime(pac4jConfigProps.getMaximumAuthenticationLifetime()); + saml2Config.setServiceProviderEntityId(pac4jConfigProps.getServiceProviderEntityId()); + saml2Config.setServiceProviderMetadataPath(pac4jConfigProps.getServiceProviderMetadataPath()); + saml2Config.setForceServiceProviderMetadataGeneration(pac4jConfigProps.isForceServiceProviderMetadataGeneration()); + saml2Config.setWantsAssertionsSigned(pac4jConfigProps.isWantAssertionsSigned()); + saml2Config.setAttributeAsId(pac4jConfigProps.getSimpleProfileMapping().getUsername()); + saml2Config.setPostLogoutURL(pac4jConfigProps.getPostLogoutURL()); + return saml2Config; + } + @Bean public ErrorPageRegistrar errorPageRegistrar() { return this::registerErrorPages; diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java index 30311ba84..19507d1c0 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java @@ -29,6 +29,7 @@ public class Pac4jConfigurationProperties { private String serviceProviderEntityId = "https://unicon.net/shibui"; private String serviceProviderMetadataPath = "/tmp/sp-metadata.xml"; private String typeOfAuth = "SAML2"; + private String postLogoutURL; private boolean wantAssertionsSigned = true; 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 884569ac7..00383f770 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,10 +5,12 @@ 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 org.jadira.usertype.spi.utils.lang.StringUtils; 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; +import org.pac4j.springframework.security.web.LogoutFilter; import org.pac4j.springframework.security.web.SecurityFilter; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureOrder; @@ -67,9 +69,19 @@ protected void configure(HttpSecurity http) throws Exception { // 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); + final LogoutFilter logoutFilter = new LogoutFilter(config); + logoutFilter.setLocalLogout(Boolean.TRUE); + if (StringUtils.isNotEmpty(pac4jConfigurationProperties.getPostLogoutURL())){ + logoutFilter.setSuffix("login"); // "logout" is redirected before we ever hit the filters - sent to /login?logout + logoutFilter.setCentralLogout(Boolean.TRUE); + logoutFilter.setDefaultUrl(pac4jConfigurationProperties.getPostLogoutURL()); + } + + // add filters + http.antMatcher("/**").addFilterBefore(logoutFilter, BasicAuthenticationFilter.class); + http.antMatcher("/**").addFilterBefore(getFilter(pac4jConfigurationProperties.getTypeOfAuth()), BasicAuthenticationFilter.class); http.antMatcher("/**").addFilterBefore(securityFilter, BasicAuthenticationFilter.class); + // add the new user filter http.addFilterAfter(new AddNewUserFilter(pac4jConfigurationProperties, userService, rolesService, getPathMatcher("exclude-paths-matcher"), groupService, emailService), SecurityFilter.class); @@ -84,7 +96,7 @@ private Matcher getPathMatcher(String name) { return config.getMatchers().get(name); } - private Filter getFilter(Config config2, String typeOfAuth) { + private Filter getFilter(String typeOfAuth) { switch (typeOfAuth) { case "SAML2": return new CallbackFilter(this.config); diff --git a/testbed/authentication/shibui/application.yml b/testbed/authentication/shibui/application.yml index 14085a9b7..cb789f06c 100644 --- a/testbed/authentication/shibui/application.yml +++ b/testbed/authentication/shibui/application.yml @@ -18,6 +18,7 @@ shibui: forceServiceProviderMetadataGeneration: true callbackUrl: "https://shibui.unicon.local/callback" maximumAuthenticationLifetime: 3600000 + postLogoutURL: "https://idp.unicon.local/idp/profile/Logout" simpleProfileMapping: username: urn:oid:0.9.2342.19200300.100.1.1 firstName: urn:oid:2.5.4.42 From d517d5196a35c04488da78527c54b6bb4e61b487 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Mon, 15 Aug 2022 15:15:03 -0700 Subject: [PATCH 07/71] SHIBUI-2333 Added logic to correctly support IDP logout Former-commit-id: 797df715c159fe7124bd9a716d78649c93c4dd56 --- backend/src/main/resources/application.yml | 1 + .../main/java/net/unicon/shibui/pac4j/WebSecurity.java | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index ffeab970c..0d2308307 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -22,6 +22,7 @@ # identityProviderMetadataPath: "/etc/shibui/idp-metadata.xml" # forceServiceProviderMetadataGeneration: false # callbackUrl: "https://localhost:8443/callback" +# postLogoutURL: "https://idp.example.com/idp/profile/Logout" # Must set this to get IDP logout # maximumAuthenticationLifetime: 3600000 # requireAssertedRoleForNewUsers: false # saml2ProfileMapping: 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 00383f770..cc5ce8e25 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 @@ -66,19 +66,20 @@ public Pac4jWebSecurityConfigurerAdapter(final Config config, UserService userSe protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers("/unsecured/**/*").permitAll(); - // adding the authorizor bypasses the default behavior of checking CSRF in Pac4J's default securitylogic+defaultauthorizationchecker + // adding the authorizer 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); - final LogoutFilter logoutFilter = new LogoutFilter(config); - logoutFilter.setLocalLogout(Boolean.TRUE); + // If the post logout URL is configured, setup the logout filter if (StringUtils.isNotEmpty(pac4jConfigurationProperties.getPostLogoutURL())){ + final LogoutFilter logoutFilter = new LogoutFilter(config); + logoutFilter.setLocalLogout(Boolean.TRUE); logoutFilter.setSuffix("login"); // "logout" is redirected before we ever hit the filters - sent to /login?logout logoutFilter.setCentralLogout(Boolean.TRUE); logoutFilter.setDefaultUrl(pac4jConfigurationProperties.getPostLogoutURL()); + http.antMatcher("/**").addFilterBefore(logoutFilter, BasicAuthenticationFilter.class); } // add filters - http.antMatcher("/**").addFilterBefore(logoutFilter, BasicAuthenticationFilter.class); http.antMatcher("/**").addFilterBefore(getFilter(pac4jConfigurationProperties.getTypeOfAuth()), BasicAuthenticationFilter.class); http.antMatcher("/**").addFilterBefore(securityFilter, BasicAuthenticationFilter.class); From ead3e593b50e9abd1a08a49c130e78524176048a Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 16 Aug 2022 09:26:51 -0700 Subject: [PATCH 08/71] SHIBUI-1699 Correcting date format output for versions to match the date format supplied to the UI in the rest of the application Former-commit-id: ec174727db631b7bd457f88a5ff723d219cfd0f1 --- .../tier/shibboleth/admin/ui/domain/versioning/Version.java | 4 ++-- .../versioning/VersionJsonSerializationBasicTests.groovy | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/versioning/Version.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/versioning/Version.java index 100b0fdbd..55fc0566d 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/versioning/Version.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/versioning/Version.java @@ -26,9 +26,9 @@ public class Version implements Serializable { private String creator; - @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSSSS") private ZonedDateTime date; private static final long serialVersionUID = 3429591830989243421L; -} +} \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/versioning/VersionJsonSerializationBasicTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/versioning/VersionJsonSerializationBasicTests.groovy index b7fecdf4d..2ceb78df6 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/versioning/VersionJsonSerializationBasicTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/versioning/VersionJsonSerializationBasicTests.groovy @@ -27,7 +27,7 @@ class VersionJsonSerializationBasicTests extends Specification { { "id": "2", "creator": "kramer", - "date": "2019-05-20T15:00:00.574Z" + "date": "2019-05-20T15:00:00.574000" } """ def expectedJsonMap = jsonSlurper.parseText(expectedJson) @@ -40,4 +40,4 @@ class VersionJsonSerializationBasicTests extends Specification { deSerializedJsonMap.id == expectedJsonMap.id deSerializedJsonMap.creator == expectedJsonMap.creator } -} +} \ No newline at end of file From c64f77cf6c3a0d017040350b6f0e261d4a45baf0 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 25 Aug 2022 14:00:12 -0700 Subject: [PATCH 09/71] Fixed issue with changing filter type Former-commit-id: 85cd2e617127f91ab585f400d6d9ac8b8db78321 --- ui/src/app/metadata/Filter.js | 2 -- ui/src/app/metadata/editor/MetadataFilterEditor.js | 8 ++++++++ ui/src/app/metadata/hooks/schema.js | 6 +++++- ui/src/app/metadata/wizard/MetadataFilterTypeSelector.js | 4 ++-- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/ui/src/app/metadata/Filter.js b/ui/src/app/metadata/Filter.js index 58b867040..4c1bc707c 100644 --- a/ui/src/app/metadata/Filter.js +++ b/ui/src/app/metadata/Filter.js @@ -11,8 +11,6 @@ export function Filter() { const { path, url } = useRouteMatch(); - console.log(path, url) - return ( diff --git a/ui/src/app/metadata/editor/MetadataFilterEditor.js b/ui/src/app/metadata/editor/MetadataFilterEditor.js index 538c85d0e..972905e0a 100644 --- a/ui/src/app/metadata/editor/MetadataFilterEditor.js +++ b/ui/src/app/metadata/editor/MetadataFilterEditor.js @@ -25,6 +25,13 @@ export function MetadataFilterEditor({children, onNavigate, block}) { const schema = React.useContext(MetadataSchemaContext); const current = React.useContext(MetadataFilterContext); + React.useEffect(() => { + const step = definition.steps.find(step => step.id === section); + if (!step) { + onNavigate(definition.steps[0].id); + } + }, [section, current, onNavigate, definition]); + const { state, dispatch } = React.useContext(MetadataFormContext); const { metadata, errors } = state; @@ -38,6 +45,7 @@ export function MetadataFilterEditor({children, onNavigate, block}) { const warnings = definition.warnings && definition.warnings(metadata); + return (
diff --git a/ui/src/app/metadata/hooks/schema.js b/ui/src/app/metadata/hooks/schema.js index 5083559b1..b8bfcf7ca 100644 --- a/ui/src/app/metadata/hooks/schema.js +++ b/ui/src/app/metadata/hooks/schema.js @@ -11,7 +11,11 @@ export function useUiSchema(definition, schema, current, locked = true) { const ui = React.useMemo(() => definition ? { ...definition.uiSchema } : {}, [definition]); const schemaKeys = React.useMemo(() => schema ? Object.keys(schema.properties) : [], [schema]); - const step = React.useMemo(() => definition ? definition.steps.find(step => step.id === current) : {fields: []}, [definition, current]); + let step = React.useMemo(() => definition ? definition.steps.find(step => step.id === current) : {fields: []}, [definition, current]); + + if (!step) { + step = definition.steps[0]; + } const filled = React.useMemo(() => fillInRootProperties(schemaKeys, ui), [schemaKeys, ui]); const mapped = React.useMemo(() => Object.keys(filled).reduce((sch, key) => { diff --git a/ui/src/app/metadata/wizard/MetadataFilterTypeSelector.js b/ui/src/app/metadata/wizard/MetadataFilterTypeSelector.js index ff16b61a4..d46e79999 100644 --- a/ui/src/app/metadata/wizard/MetadataFilterTypeSelector.js +++ b/ui/src/app/metadata/wizard/MetadataFilterTypeSelector.js @@ -5,7 +5,7 @@ import Translate from '../../i18n/components/translate'; import { InfoIcon } from '../../form/component/InfoIcon'; import { useTranslator } from '../../i18n/hooks'; -export function MetadataFilterTypeSelector({ types = [], children, actions}) { +export function MetadataFilterTypeSelector({ types = [], children}) { const translator = useTranslator(); @@ -29,7 +29,7 @@ export function MetadataFilterTypeSelector({ types = [], children, actions}) { React.useEffect(() => { setBase({ '@type': type - }) + }); }, [type]) return ( From 88c147dd4d14fc0b6f0ce419c4914150e1f4ab6e Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 25 Aug 2022 14:03:02 -0700 Subject: [PATCH 10/71] Fixed message Former-commit-id: f3f02ceb321e1b064b9432bacce456222f821059 --- backend/src/main/resources/i18n/messages.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index 92f1edb6f..29aaf5de9 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -534,7 +534,7 @@ label.role=Role message.delete-role-title=Delete Role? message.delete-role-body=You are requesting to delete a role. If you complete this process the role will be removed. This cannot be undone. Do you wish to continue? -message.duration=Requires a valid ISO 8601 duration (ex. PT2D) +message.duration=Requires a valid ISO 8601 duration (ex. PT4H) 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? From 103525268d84169e6ee8cf7d065ab95b81185dec Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 26 Aug 2022 14:34:59 -0700 Subject: [PATCH 11/71] [Gradle Release Plugin] - pre tag commit: '1.12.0'. Former-commit-id: 3475c161b916fc2fd15dee4292d004d6aebc363a --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 7efe1ae08..da3a66a9f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ name=shibui group=edu.internet2.tier.shibboleth.admin.ui -version=1.12.0-SNAPSHOT +version=1.12.0 ### library versions ### commonsCollections4Version=4.4 From 19661eb29847c412a1717526fbe8c49f2b6bdb29 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 26 Aug 2022 15:35:42 -0700 Subject: [PATCH 12/71] NOJIRA change to version to snapshot Former-commit-id: 15c237d08e24014a878fe3863be720a2f7cf61af --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index da3a66a9f..7efe1ae08 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ name=shibui group=edu.internet2.tier.shibboleth.admin.ui -version=1.12.0 +version=1.12.0-SNAPSHOT ### library versions ### commonsCollections4Version=4.4 From 6e830a2c3b8110f19da45e7a01a624fe0b818666 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 26 Aug 2022 15:51:32 -0700 Subject: [PATCH 13/71] [Gradle Release Plugin] - pre tag commit: '1.12.0'. Former-commit-id: 93571463dc2a6210a92f8b80d05ed8aeaa8a9bd1 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 7efe1ae08..da3a66a9f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ name=shibui group=edu.internet2.tier.shibboleth.admin.ui -version=1.12.0-SNAPSHOT +version=1.12.0 ### library versions ### commonsCollections4Version=4.4 From 8344512ec8f90cf907b386ca946987fb51a2abb3 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 26 Aug 2022 15:56:33 -0700 Subject: [PATCH 14/71] NOJIRA change to version to snapshot Former-commit-id: d8ba22f701a9c34c35c24fd0f446c15e8819f0f1 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index da3a66a9f..7efe1ae08 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ name=shibui group=edu.internet2.tier.shibboleth.admin.ui -version=1.12.0 +version=1.12.0-SNAPSHOT ### library versions ### commonsCollections4Version=4.4 From bfbc8e2caabb707e574120643c608100e69a9a97 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 26 Aug 2022 16:26:50 -0700 Subject: [PATCH 15/71] [Gradle Release Plugin] - pre tag commit: '1.12.0'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 7efe1ae08..da3a66a9f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ name=shibui group=edu.internet2.tier.shibboleth.admin.ui -version=1.12.0-SNAPSHOT +version=1.12.0 ### library versions ### commonsCollections4Version=4.4 From 468ff2a0a9c1eef973fea984414e5b1a864a3b29 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 26 Aug 2022 18:25:34 -0700 Subject: [PATCH 16/71] NOJIRA change to version to snapshot --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index da3a66a9f..7efe1ae08 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ name=shibui group=edu.internet2.tier.shibboleth.admin.ui -version=1.12.0 +version=1.12.0-SNAPSHOT ### library versions ### commonsCollections4Version=4.4 From 446e2995811a391c79fbd02b73081cc200eeed3b Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 26 Aug 2022 18:35:08 -0700 Subject: [PATCH 17/71] [Gradle Release Plugin] - pre tag commit: '1.12.0'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 7efe1ae08..da3a66a9f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ name=shibui group=edu.internet2.tier.shibboleth.admin.ui -version=1.12.0-SNAPSHOT +version=1.12.0 ### library versions ### commonsCollections4Version=4.4 From dd0632a1bbe9ebcca58bd4f38c33df72d9985036 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 26 Aug 2022 19:22:16 -0700 Subject: [PATCH 18/71] NOJIRA change to version to snapshot --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index da3a66a9f..1594d2baa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ name=shibui group=edu.internet2.tier.shibboleth.admin.ui -version=1.12.0 +version=1.13.0-SNAPSHOT ### library versions ### commonsCollections4Version=4.4 From 3ead20d90c44e908649c4c46d337b3610a508e4a Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Mon, 29 Aug 2022 13:25:22 -0700 Subject: [PATCH 19/71] Updated configuration builder --- ui/package-lock.json | 14 +- ui/package.json | 2 +- ui/public/assets/data/configuration.json | 29 +++ .../app/admin/component/ConfigurationForm.js | 174 +++++++----------- .../app/admin/component/PropertySelector.js | 92 +++++++++ .../app/admin/container/ConfigurationList.js | 12 +- .../app/admin/container/EditConfiguration.js | 76 ++++---- .../app/admin/container/NewConfiguration.js | 30 ++- .../app/admin/hoc/ConfigurationsProvider.js | 2 +- ui/src/app/admin/hoc/PropertiesProvider.js | 4 +- ui/src/app/admin/hooks.js | 8 +- ui/src/theme/project/configuration.scss | 11 ++ ui/src/theme/project/index.scss | 1 + 13 files changed, 271 insertions(+), 184 deletions(-) create mode 100644 ui/public/assets/data/configuration.json create mode 100644 ui/src/app/admin/component/PropertySelector.js create mode 100644 ui/src/theme/project/configuration.scss diff --git a/ui/package-lock.json b/ui/package-lock.json index 0cc5f3665..2083b22a0 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -25,7 +25,7 @@ "react-bootstrap": "^2.3.0", "react-bootstrap-typeahead": "^5.1.4", "react-dom": "^18.0.0", - "react-hook-form": "^7.30.0", + "react-hook-form": "^7.34.0", "react-infinite-scroll-component": "^6.1.0", "react-router": "^5.1.0", "react-router-dom": "^5.1.0", @@ -13536,9 +13536,9 @@ "dev": true }, "node_modules/react-hook-form": { - "version": "7.30.0", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.30.0.tgz", - "integrity": "sha512-DzjiM6o2vtDGNMB9I4yCqW8J21P314SboNG1O0obROkbg7KVS0I7bMtwSdKyapnCPjHgnxc3L7E5PEdISeEUcQ==", + "version": "7.34.2", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.34.2.tgz", + "integrity": "sha512-1lYWbEqr0GW7HHUjMScXMidGvV0BE2RJV3ap2BL7G0EJirkqpccTaawbsvBO8GZaB3JjCeFBEbnEWI1P8ZoLRQ==", "engines": { "node": ">=12.22.0" }, @@ -26712,9 +26712,9 @@ "dev": true }, "react-hook-form": { - "version": "7.30.0", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.30.0.tgz", - "integrity": "sha512-DzjiM6o2vtDGNMB9I4yCqW8J21P314SboNG1O0obROkbg7KVS0I7bMtwSdKyapnCPjHgnxc3L7E5PEdISeEUcQ==", + "version": "7.34.2", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.34.2.tgz", + "integrity": "sha512-1lYWbEqr0GW7HHUjMScXMidGvV0BE2RJV3ap2BL7G0EJirkqpccTaawbsvBO8GZaB3JjCeFBEbnEWI1P8ZoLRQ==", "requires": {} }, "react-infinite-scroll-component": { diff --git a/ui/package.json b/ui/package.json index 25cc8cd8a..b32a48b1d 100644 --- a/ui/package.json +++ b/ui/package.json @@ -21,7 +21,7 @@ "react-bootstrap": "^2.3.0", "react-bootstrap-typeahead": "^5.1.4", "react-dom": "^18.0.0", - "react-hook-form": "^7.30.0", + "react-hook-form": "^7.34.0", "react-infinite-scroll-component": "^6.1.0", "react-router": "^5.1.0", "react-router-dom": "^5.1.0", diff --git a/ui/public/assets/data/configuration.json b/ui/public/assets/data/configuration.json new file mode 100644 index 000000000..82e86dd4d --- /dev/null +++ b/ui/public/assets/data/configuration.json @@ -0,0 +1,29 @@ +{ + "resourceId": 11, + "name": "setname1", + "properties": [ + { + "resourceId":"577", + "category":"OPSubClaim", + "configFile":"oidc.properties", + "description":"The source attribute used in generating the sub claim", + "idpVersion":"4.1", + "module":"idp.oidc.OP", + "moduleVersion":"3", + "propertyName":"idp.oidc.subject.sourceAttribute", + "displayType":"string", + "propertyValue": "foo" + }, + { + "resourceId": "393", + "category": "ReloadableServices", + "configFile": "services.properties", + "defaultValue": "false", + "description": "Fail at startup if MetadataConfiguration is invalid", + "idpVersion": "all", + "propertyName": "idp.service.metadata.failFast", + "displayType": "boolean", + "propertyValue": "true" + } + ] +} diff --git a/ui/src/app/admin/component/ConfigurationForm.js b/ui/src/app/admin/component/ConfigurationForm.js index ff890a6a2..9db9756da 100644 --- a/ui/src/app/admin/component/ConfigurationForm.js +++ b/ui/src/app/admin/component/ConfigurationForm.js @@ -1,74 +1,34 @@ -import React, { Fragment } from 'react'; +import React from 'react'; import Button from 'react-bootstrap/Button'; +import { useFieldArray, useForm } from 'react-hook-form'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faSpinner, faSave, faTrash } from '@fortawesome/free-solid-svg-icons'; -import { Highlighter, Menu, MenuItem, Token, Typeahead } from 'react-bootstrap-typeahead'; + import Translate from '../../i18n/components/translate'; -import { ToggleButton } from '../../form/component/ToggleButton'; +import PropertySelector from './PropertySelector'; import { useProperties, usePropertiesLoading } from '../hoc/PropertiesProvider'; -import { groupBy } from 'lodash'; -import { useCallback } from 'react'; + import Form from 'react-bootstrap/Form'; import FloatingLabel from 'react-bootstrap/FloatingLabel'; -export function ConfigurationForm({ configuration = {}, errors = [], schema, onSave, onCancel }) { - - const properties = useProperties(); - const loading = usePropertiesLoading(); +export function ConfigurationForm({ configuration = {}, schema, onSave, onCancel }) { - const select = (data) => { - console.log(data); - setSelected(data); - }; + const { control, register, getValues, watch, formState: { errors } } = useForm({ + defaultValues: { + ...configuration + } + }); - const [selected, setSelected] = React.useState([]); + const { fields, prepend, remove } = useFieldArray({ + control, + name: "properties", + }); - const [config, setConfig] = React.useState({ name: '', properties: [] }); - - // config.properties.filter(p => p.category === item.category).length === properties.filter(p => p.category === item.category).length - - const menu = useCallback((results, menuProps, state) => { - let index = 0; - const mapped = results.map(p => !p.category || p.category === '?' ? { ...p, category: 'Misc' } : p); - const grouped = groupBy(mapped, 'category'); - const items = Object.keys(grouped).sort().map((item) => ( - - {index !== 0 && } - - - {item} - Add all - - - {grouped[item].map((i) => { - const item = - p.propertyName === i.propertyName) }> - - {`- ${i.propertyName}`} - - ; - index += 1; - return item; - })} - - )); - - return {items}; - }, [config.properties]); - - const token = (option, { onRemove }, index) => ( - - {`${option.propertyName}`} - - ); + const properties = useProperties(); + const loading = usePropertiesLoading(); const addProperties = (props) => { - const parsed = props.reduce((coll, prop, idx) => { if (prop.isCategory) { return [...coll, ...properties.filter(p => p.category === prop.category)]; @@ -77,17 +37,20 @@ export function ConfigurationForm({ configuration = {}, errors = [], schema, onS } }, []); - setConfig({ - ...config, - properties: [ - ...config.properties, - ...parsed, - ] - }); - setSelected([]); + prepend(parsed); }; - React.useEffect(() => console.log(selected), [selected]); + const saveConfig = (formValues) => { + const parsed = formValues.properties.map(p => ({ + propertyName: p.propertyName, + propertyValue: p.propertyValue, + configFile: p.configFile, + })); + onSave({ + ...formValues, + properties: parsed + }); + }; return (<>
@@ -95,7 +58,7 @@ export function ConfigurationForm({ configuration = {}, errors = [], schema, onS

-
-
-
-
- - select(selected)} - options={[...properties]} - selected={selected} - labelKey={option => `${option.propertyName}`} - filterBy={['propertyName', 'category', 'displayType']} - renderMenu={ menu } - multiple={ true } - renderToken={ token } - > - {({ isMenuShown, toggleMenu }) => ( - toggleMenu()}> - Options - - )} - +
+
+
+ + Name + + +
+
+
+
+
+
-
-
-
-
-
- +
+
+
@@ -154,20 +102,27 @@ export function ConfigurationForm({ configuration = {}, errors = [], schema, onS - {config.properties.map((p, idx) => ( - + {fields.map((p, idx) => ( +
{ p.propertyName } { p.category } { p.displayType } - - - + {p.displayType !== 'boolean' ? + + + + : + + } - @@ -176,10 +131,9 @@ export function ConfigurationForm({ configuration = {}, errors = [], schema, onS ))}
- +
-
+
) -} -/**/ \ No newline at end of file +} \ No newline at end of file diff --git a/ui/src/app/admin/component/PropertySelector.js b/ui/src/app/admin/component/PropertySelector.js new file mode 100644 index 000000000..44cdfd085 --- /dev/null +++ b/ui/src/app/admin/component/PropertySelector.js @@ -0,0 +1,92 @@ +import React, { Fragment, useCallback } from 'react'; +import { groupBy } from 'lodash'; +import { Highlighter, Menu, MenuItem, Token, Typeahead } from 'react-bootstrap-typeahead'; +import Button from 'react-bootstrap/Button'; + +import { ToggleButton } from '../../form/component/ToggleButton'; + +export function PropertySelector ({ properties, options, onAddProperties }) { + + // React.useEffect(() => console.log(properties), [properties]); + + const menu = useCallback((results, menuProps, state) => { + let index = 0; + const mapped = results.map(p => !p.category || p.category === '?' ? { ...p, category: 'Misc' } : p); + const grouped = groupBy(mapped, 'category'); + const items = Object.keys(grouped).sort().map((item) => ( + + {index !== 0 && } + + + {item} - Add all + + + {grouped[item].map((i) => { + const item = + p.propertyName === i.propertyName) }> + + {`- ${i.propertyName}`} + + ; + index += 1; + return item; + })} + + )); + + return {items}; + }, [properties]); + + const token = (option, { onRemove }, index) => ( + + {`${option.propertyName}`} + + ); + + const select = (data) => { + setSelected(data); + }; + + const [selected, setSelected] = React.useState([]); + + const add = (s) => { + onAddProperties(s); + setSelected([]); + } + + return ( + +
+ + select(selected)} + options={[...options]} + selected={selected} + labelKey={option => `${option.propertyName}`} + filterBy={['propertyName', 'category', 'displayType']} + renderMenu={ menu } + multiple={ true } + renderToken={ token } + > + {({ isMenuShown, toggleMenu }) => ( + toggleMenu()}> + Options + + )} + +
+ +
+ ) +} + +export default PropertySelector; \ No newline at end of file diff --git a/ui/src/app/admin/container/ConfigurationList.js b/ui/src/app/admin/container/ConfigurationList.js index fcad47048..4acffc1c2 100644 --- a/ui/src/app/admin/container/ConfigurationList.js +++ b/ui/src/app/admin/container/ConfigurationList.js @@ -1,5 +1,5 @@ import React from 'react'; -import { faDownload, faEdit, faPlusCircle, faTrash } from '@fortawesome/free-solid-svg-icons'; +import { faDownload, faPlusCircle, faTrash } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import Button from 'react-bootstrap/Button'; @@ -46,13 +46,17 @@ export function ConfigurationList({ configurations, onDelete }) { {(configurations?.length > 0) ? configurations.map((c, i) => - {c.name} + + + {c.name} + + - +
diff --git a/ui/src/app/admin/container/NewConfiguration.js b/ui/src/app/admin/container/NewConfiguration.js index d2ece36a9..a358c1f84 100644 --- a/ui/src/app/admin/container/NewConfiguration.js +++ b/ui/src/app/admin/container/NewConfiguration.js @@ -21,11 +21,11 @@ export function NewConfiguration() { const [blocking, setBlocking] = React.useState(false); - async function save(property) { + async function save(config) { let toast; - const resp = await post(``, property); + const resp = await post(``, config); if (response.ok) { - gotoDetail({ refresh: true }); + gotoList({ refresh: true }); toast = createNotificationAction(`Added property successfully.`, NotificationTypes.SUCCESS); } else { toast = createNotificationAction(`${resp.errorCode} - ${translator(resp.errorMessage)}`, NotificationTypes.ERROR); @@ -36,14 +36,16 @@ export function NewConfiguration() { }; const cancel = () => { - gotoDetail(); + gotoList(); }; - const gotoDetail = (state = null) => { + const gotoList = (state = null) => { setBlocking(false); - history.push(`/properties`, state); + history.push(`/configurations`, state); }; + const [configuration] = React.useState({}); + return (
{(schema) => - - {(data, errors) => - save(data)} - onCancel={() => cancel()} />} - } + save(data)} + onCancel={() => cancel()} />}
diff --git a/ui/src/app/admin/hoc/ConfigurationsProvider.js b/ui/src/app/admin/hoc/ConfigurationsProvider.js index 661c00d80..aa23ddd45 100644 --- a/ui/src/app/admin/hoc/ConfigurationsProvider.js +++ b/ui/src/app/admin/hoc/ConfigurationsProvider.js @@ -15,7 +15,7 @@ export function ConfigurationsProvider({ children, cache = 'no-cache' }) { }); async function loadConfigurations() { - const list = await get(`assets/data/configurations.json`); + const list = await get(`shib/property/set`); if (response.ok) { setConfigurations(list); } diff --git a/ui/src/app/admin/hoc/PropertiesProvider.js b/ui/src/app/admin/hoc/PropertiesProvider.js index 55dde0696..bf62be7cc 100644 --- a/ui/src/app/admin/hoc/PropertiesProvider.js +++ b/ui/src/app/admin/hoc/PropertiesProvider.js @@ -1,8 +1,6 @@ import React from 'react'; import useFetch from 'use-http'; -import API_BASE_PATH, { BASE_PATH } from '../../App.constant'; -import has from 'lodash/has'; -import { groupBy } from 'lodash'; +import API_BASE_PATH from '../../App.constant'; const PropertiesContext = React.createContext(); diff --git a/ui/src/app/admin/hooks.js b/ui/src/app/admin/hooks.js index 50f0b51c7..11184e55e 100644 --- a/ui/src/app/admin/hooks.js +++ b/ui/src/app/admin/hooks.js @@ -1,7 +1,7 @@ import useFetch from 'use-http'; import isNil from 'lodash/isNil'; import {isValidRegex} from '../core/utility/is_valid_regex'; -import API_BASE_PATH, { BASE_PATH } from '../App.constant'; +import API_BASE_PATH from '../App.constant'; export function useGroups (opts = { cachePolicy: 'no-cache' }) { return useFetch(`${API_BASE_PATH}/admin/groups`, opts); @@ -48,11 +48,11 @@ export function useRoleUiSchema() { } export function useConfigurations (opts = { cachePolicy: 'no-cache' }) { - return useFetch(`${BASE_PATH}/`, opts); + return useFetch(`${API_BASE_PATH}/`, opts); } -export function useConfiguration(id, opts = { cachePolicy: 'no-cache' }) { - return useFetch(`${API_BASE_PATH}/admin/configuration/${id}`, opts); +export function useConfiguration(opts = { cachePolicy: 'no-cache' }) { + return useFetch(`${API_BASE_PATH}/shib/property/set`, opts); } export function useConfigurationUiSchema () { diff --git a/ui/src/theme/project/configuration.scss b/ui/src/theme/project/configuration.scss new file mode 100644 index 000000000..0da05f1ff --- /dev/null +++ b/ui/src/theme/project/configuration.scss @@ -0,0 +1,11 @@ +#property-selector { + .dropdown-header { + padding-right: 0rem; + padding-left: 0rem; + font-size: 1rem; + + .dropdown-item { + font-weight: bold; + } + } +} \ No newline at end of file diff --git a/ui/src/theme/project/index.scss b/ui/src/theme/project/index.scss index 6d0de6f9a..fd2b6a070 100644 --- a/ui/src/theme/project/index.scss +++ b/ui/src/theme/project/index.scss @@ -14,6 +14,7 @@ @import './notifications'; @import './filters'; @import './typeahead'; +@import './configuration'; html, body { height: 100%; From fef8cbbc5279ae44c729bdd7dcd5adcedc6cdd49 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Mon, 29 Aug 2022 14:45:49 -0700 Subject: [PATCH 20/71] NOJIRA fixed typo --- .../admin/ui/controller/ShibPropertiesController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesController.java index b5895db41..f90392108 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesController.java @@ -58,7 +58,7 @@ public ResponseEntity getAllPropertySets() { return ResponseEntity.ok(service.getAllPropertySets()); } - @GetMapping(value="/property/set/{resourceId}", produces="applcation/json") + @GetMapping(value="/property/set/{resourceId}", produces="application/json") @Transactional(readOnly = true) @Operation(description = "Return the property set with the given resourceId", summary = "Return the property set with the given resourceId", method = "GET") From 4945eb2458a3f3a4a90a14c5f3143ce041930427 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Mon, 29 Aug 2022 15:14:28 -0700 Subject: [PATCH 21/71] NOJIRA fixed typo --- .../admin/ui/controller/ShibPropertiesController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesController.java index b5895db41..f90392108 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesController.java @@ -58,7 +58,7 @@ public ResponseEntity getAllPropertySets() { return ResponseEntity.ok(service.getAllPropertySets()); } - @GetMapping(value="/property/set/{resourceId}", produces="applcation/json") + @GetMapping(value="/property/set/{resourceId}", produces="application/json") @Transactional(readOnly = true) @Operation(description = "Return the property set with the given resourceId", summary = "Return the property set with the given resourceId", method = "GET") From c4315a44bf42a658e595cc3ac56726b9381dc535 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 30 Aug 2022 09:52:46 -0700 Subject: [PATCH 22/71] SHIBUI-2270 Adding export file as a single property file option --- .../controller/ShibPropertiesController.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesController.java index f90392108..b613c2b4f 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesController.java @@ -76,6 +76,16 @@ public ResponseEntity getPropertySetAsZip(@PathVariable Integer resourceId) t return ResponseEntity.ok().header("Content-Disposition", sb.toString()).body(prepDownloadAsZip(convertPropertiesToMaps(set.getProperties()))); } + @GetMapping(value="/property/set/{resourceId}/onefile", produces="application/zip") + @Transactional(readOnly = true) + @Operation(description = "Return the property set with the given resourceId as a zip file of a single properties files", + summary = "Return the property set with the given resourceId as a zip file of a single properties files", method = "GET") + public ResponseEntity getPropertySetOneFileAsZip(@PathVariable Integer resourceId) throws EntityNotFoundException, IOException { + ShibPropertySet set = service.getSet(resourceId); + StringBuilder sb = new StringBuilder("attachment; filename=\"").append(set.getName()).append(".zip\""); + return ResponseEntity.ok().header("Content-Disposition", sb.toString()).body(prepDownloadAsZipWithSingleFile(convertPropertiesToMaps(set.getProperties()))); + } + private Map> convertPropertiesToMaps(List properties) { HashMap> result = new HashMap<>(); for (ShibPropertySetting setting:properties){ @@ -90,6 +100,25 @@ private Map> convertPropertiesToMaps(List> propertiesFiles) throws IOException { + ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream(); + ZipOutputStream zipOutputStream = new ZipOutputStream(byteOutputStream); + zipOutputStream.putNextEntry(new ZipEntry("shibboleth.properties")); + + for (String filename : propertiesFiles.keySet()) { + Map properties = propertiesFiles.get(filename); + StringBuilder props = new StringBuilder(); + for (String key : properties.keySet()) { + props.append(key).append("=").append(properties.get(key)).append("\n"); + } + ByteArrayInputStream inputStream = new ByteArrayInputStream(props.toString().getBytes()); + IOUtils.copy(inputStream, zipOutputStream); + } + zipOutputStream.closeEntry(); + zipOutputStream.close(); + return byteOutputStream.toByteArray(); + } + private byte[] prepDownloadAsZip(Map> propertiesFiles) throws IOException { ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream(); ZipOutputStream zipOutputStream = new ZipOutputStream(byteOutputStream); From 4b4bf4e097bf664b2c66bef1e09984199fda04a0 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 30 Aug 2022 09:59:56 -0700 Subject: [PATCH 23/71] Added spinners --- .../app/admin/component/ConfigurationForm.js | 11 ++++--- .../app/admin/container/ConfigurationList.js | 29 +++++++++++++------ .../app/admin/container/EditConfiguration.js | 22 ++++++++------ 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/ui/src/app/admin/component/ConfigurationForm.js b/ui/src/app/admin/component/ConfigurationForm.js index e48062f01..61e82dba6 100644 --- a/ui/src/app/admin/component/ConfigurationForm.js +++ b/ui/src/app/admin/component/ConfigurationForm.js @@ -7,12 +7,12 @@ import { faSpinner, faSave, faTrash } from '@fortawesome/free-solid-svg-icons'; import Translate from '../../i18n/components/translate'; import PropertySelector from './PropertySelector'; -import { useProperties, usePropertiesLoading } from '../hoc/PropertiesProvider'; +import { useProperties } from '../hoc/PropertiesProvider'; import Form from 'react-bootstrap/Form'; import FloatingLabel from 'react-bootstrap/FloatingLabel'; -export function ConfigurationForm({ configuration = {}, schema, onSave, onCancel }) { +export function ConfigurationForm({ configuration = {}, loading, onSave, onCancel }) { const { control, register, getValues, watch, formState: { errors } } = useForm({ defaultValues: { @@ -26,7 +26,6 @@ export function ConfigurationForm({ configuration = {}, schema, onSave, onCancel }); const properties = useProperties(); - const loading = usePropertiesLoading(); const addProperties = (props) => { const parsed = props.reduce((coll, prop, idx) => { @@ -52,6 +51,8 @@ export function ConfigurationForm({ configuration = {}, schema, onSave, onCancel }); }; + React.useEffect(() => console.log(configuration), [configuration]); + return (<>
@@ -66,7 +67,9 @@ export function ConfigurationForm({ configuration = {}, schema, onSave, onCancel diff --git a/ui/src/app/admin/container/ConfigurationList.js b/ui/src/app/admin/container/ConfigurationList.js index 4acffc1c2..527f65c50 100644 --- a/ui/src/app/admin/container/ConfigurationList.js +++ b/ui/src/app/admin/container/ConfigurationList.js @@ -1,15 +1,16 @@ import React from 'react'; -import { faDownload, faPlusCircle, faTrash } from '@fortawesome/free-solid-svg-icons'; +import { faDownload, faEdit, faPlusCircle, faSpinner, faTrash } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import Button from 'react-bootstrap/Button'; +import ButtonGroup from 'react-bootstrap/ButtonGroup'; import { Link } from 'react-router-dom'; import { Translate } from '../../i18n/components/translate'; import { DeleteConfirmation } from '../../core/components/DeleteConfirmation'; -export function ConfigurationList({ configurations, onDelete }) { +export function ConfigurationList({ configurations, onDelete, loading }) { const remove = (id) => { onDelete(id); @@ -19,6 +20,11 @@ export function ConfigurationList({ configurations, onDelete }) { {(block) =>
+ {loading ? +
+ +
+ :
@@ -52,16 +58,20 @@ export function ConfigurationList({ configurations, onDelete }) { - - - + + + +   Edit + + - + ) : @@ -73,6 +83,7 @@ export function ConfigurationList({ configurations, onDelete }) {
+ }
}
diff --git a/ui/src/app/admin/container/EditConfiguration.js b/ui/src/app/admin/container/EditConfiguration.js index 7ff66b46d..692c353c9 100644 --- a/ui/src/app/admin/container/EditConfiguration.js +++ b/ui/src/app/admin/container/EditConfiguration.js @@ -10,6 +10,8 @@ import { createNotificationAction, NotificationTypes, useNotificationDispatcher import { useTranslator } from '../../i18n/hooks'; import { BASE_PATH } from '../../App.constant'; import { PropertiesProvider } from '../hoc/PropertiesProvider'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faSpinner } from '@fortawesome/free-solid-svg-icons'; export function EditConfiguration() { const history = useHistory(); @@ -73,17 +75,19 @@ export function EditConfiguration() {
+ {loading ? +
+ +
+ : - - {(schema) => - save(data)} - onCancel={() => cancel()} />} - + {configuration && save(data)} + onCancel={() => cancel()} /> } + }
From 44ca5c8297f6028ce180ce7ebdd00b7a43841244 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 30 Aug 2022 10:42:04 -0700 Subject: [PATCH 24/71] Fixed label --- backend/src/main/resources/i18n/messages.properties | 1 + ui/src/app/admin/container/EditConfiguration.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index ddfa6947f..19ab8999c 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -538,6 +538,7 @@ label.role=Role label.configuration-management=Manage Shibboleth configurations label.configuration-name=Shibboleth configuration sets label.new-configuration=Create new configuration set +label.edit-configuration=Edit configuration set message.delete-role-title=Delete Role? diff --git a/ui/src/app/admin/container/EditConfiguration.js b/ui/src/app/admin/container/EditConfiguration.js index 692c353c9..bad543b69 100644 --- a/ui/src/app/admin/container/EditConfiguration.js +++ b/ui/src/app/admin/container/EditConfiguration.js @@ -70,7 +70,7 @@ export function EditConfiguration() {
- Create new configuration set + Edit configuration set
From 0e19312b38bfdd11edeb85a609d368f8eba50168 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 30 Aug 2022 11:49:16 -0700 Subject: [PATCH 25/71] SHIBUI-2270 Adding category and dsiplay type --- .../ui/domain/shib/properties/ShibPropertySetting.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/shib/properties/ShibPropertySetting.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/shib/properties/ShibPropertySetting.java index 2fa85ff2b..1fd4d73fd 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/shib/properties/ShibPropertySetting.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/shib/properties/ShibPropertySetting.java @@ -26,4 +26,10 @@ public class ShibPropertySetting { @Column private String propertyValue; + @Column + private String category; + + @Column + private String displayType; + } \ No newline at end of file From ba1f58e75e0c9f5e960ac75178aa10933318953c Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 30 Aug 2022 11:52:42 -0700 Subject: [PATCH 26/71] SHIBUI-2270 Adding category and dsiplay type --- .../admin/ui/service/ShibConfigurationServiceImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ShibConfigurationServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ShibConfigurationServiceImpl.java index 74d9e3637..1c3c2a513 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ShibConfigurationServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ShibConfigurationServiceImpl.java @@ -118,8 +118,11 @@ private ShibPropertySet save(ShibPropertySet incomingPropSet) { } else { // get the entity from the map, update it, save to update list ShibPropertySetting updatedEntity = existingPropMap.get(prop.getPropertyName()); + // the value is really the only thing that should change... updatedEntity.setConfigFile(prop.getConfigFile()); updatedEntity.setPropertyValue(prop.getPropertyValue()); + updatedEntity.setCategory(prop.getCategory()); + updatedEntity.setDisplayType(prop.getDisplayType()); propertiesToUpdate.add(shibPropertySettingRepository.save(updatedEntity)); } }); From 43b9ec0c4310937404a99918c9e9b1d6ea24c5f7 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 30 Aug 2022 13:01:25 -0700 Subject: [PATCH 27/71] Fixed invalid duration setting --- backend/src/main/resources/i18n/messages.properties | 1 + .../provider/definition/BaseProviderDefinition.js | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index 92f1edb6f..9e1392ecd 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -535,6 +535,7 @@ message.delete-role-title=Delete Role? message.delete-role-body=You are requesting to delete a role. If you complete this process the role will be removed. This cannot be undone. Do you wish to continue? message.duration=Requires a valid ISO 8601 duration (ex. PT2D) +message.invalid-duration=Invalid duration for this field. 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? diff --git a/ui/src/app/metadata/domain/provider/definition/BaseProviderDefinition.js b/ui/src/app/metadata/domain/provider/definition/BaseProviderDefinition.js index 12e61ae0f..b94258159 100644 --- a/ui/src/app/metadata/domain/provider/definition/BaseProviderDefinition.js +++ b/ui/src/app/metadata/domain/provider/definition/BaseProviderDefinition.js @@ -1,5 +1,6 @@ import { metadataFilterProcessor } from '../utility/providerFilterProcessor'; import { MetadataFilterTypes } from '../../filter'; +import { has } from 'lodash'; export const BaseProviderDefinition = { schemaPreprocessor: metadataFilterProcessor, @@ -18,6 +19,18 @@ export const BaseProviderDefinition = { errors.xmlId.addError('message.id-unique'); } + if (has(formData, 'reloadableMetadataResolverAttributes.minRefreshDelay')) { + if (formData.reloadableMetadataResolverAttributes.minRefreshDelay === 'PT0S') { + errors.reloadableMetadataResolverAttributes.minRefreshDelay.addError('message.invalid-duration'); + } + } + + if (has(formData, 'reloadableMetadataResolverAttributes.maxRefreshDelay')) { + if (formData.reloadableMetadataResolverAttributes.maxRefreshDelay === 'PT0S') { + errors.reloadableMetadataResolverAttributes.maxRefreshDelay.addError('message.invalid-duration'); + } + } + return errors; } }, From 49f4196cc31fb5ed260d7e9ab9490ec2b39b5622 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 30 Aug 2022 14:43:00 -0700 Subject: [PATCH 28/71] SHIBUI-2341 Adding capacity to handle long character descriptions --- .../admin/ui/domain/Description.java | 4 +++- .../main/resources/db/changelog/changelog.sql | 22 ++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/Description.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/Description.java index db994740a..b86c86b1d 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/Description.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/Description.java @@ -6,6 +6,7 @@ import javax.annotation.Nullable; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.Lob; @Entity @EqualsAndHashCode(callSuper = true) @@ -16,6 +17,7 @@ public class Description extends AbstractXMLObject implements org.opensaml.saml. private String xmlLang; @Column(name = "descriptionValue") + @Lob private String value; @Nullable @@ -39,4 +41,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/resources/db/changelog/changelog.sql b/backend/src/main/resources/db/changelog/changelog.sql index 0a63846a3..f1494b2ca 100644 --- a/backend/src/main/resources/db/changelog/changelog.sql +++ b/backend/src/main/resources/db/changelog/changelog.sql @@ -175,4 +175,24 @@ 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 +update resource_backed_metadata_resolver_aud set max_refresh_delay ='PT4H'; + +-- changeset liquibase:1.13.0.1 dbms:mariadb,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 description ALTER COLUMN descriptionValue LONGTEXT; +GO +ALTER TABLE description)aud ALTER COLUMN descriptionValue LONGTEXT; +GO + +-- changeset liquibase:1.13.0.2 dbms:postgresql,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 */ + +ALTER TABLE description ALTER COLUMN descriptionValue TEXT; +GO +ALTER TABLE description_aud ALTER COLUMN descriptionValue TEXT; +GO \ No newline at end of file From 0a1de8328097ea3976afdf2a7d00f265bb282280 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Wed, 31 Aug 2022 11:46:08 -0700 Subject: [PATCH 29/71] Implemented download buttons --- .../main/resources/i18n/messages.properties | 16 +++++ .../app/admin/component/ConfigurationForm.js | 36 ++++++---- .../app/admin/component/PropertySelector.js | 2 +- .../app/admin/container/ConfigurationList.js | 71 +++++++++++++++++-- .../app/admin/container/EditConfiguration.js | 2 - .../app/admin/hoc/ConfigurationsProvider.js | 2 +- ui/src/app/admin/hooks.js | 8 ++- .../{download_as_xml.js => download_as.js} | 7 +- .../app/core/utility/download_as_xml.test.js | 2 +- .../app/metadata/hoc/FilterTargetPreview.js | 2 +- ui/src/app/metadata/view/MetadataXml.js | 2 +- ui/src/theme/project/forms.scss | 4 ++ 12 files changed, 123 insertions(+), 31 deletions(-) rename ui/src/app/core/utility/{download_as_xml.js => download_as.js} (54%) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index 19ab8999c..816a0bf80 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -757,6 +757,22 @@ tooltip.role-description=A description of the purpose of the role. tooltip.contact-information=Add a contact to organization information. Contacts provide information about how to contact the organization responsible for standing up the entity. +tooltip.download-single-config=Putting all the properties in one file can make it easier for deploying or moving among environments. +tooltip.download-multi-config=Putting the properties into individual files will follow the distribution layout and more closely align with the Shibboleth wiki page sections describing each property. +action.download-single-config=Single file +action.download-multi-config=Separated files +label.download-config=Downloads +message.configurations-none=No configurations defined. +label.configuration-name=Name +label.configuration-name-placeholder=Enter name +label.configuration-property=Property +label.configuration-category=Category +label.configuration-type=Type +label.configuration-value=Value +label.configuration-action=Action +message.delete-property-title=Delete Configuration? +message.delete-property-body=You are requesting to delete a configuration set. If you complete this process the set will be removed. This cannot be undone. Do you wish to continue? + label.external-description=Description tooltip.external-description=A brief description of the purpose of this filter. diff --git a/ui/src/app/admin/component/ConfigurationForm.js b/ui/src/app/admin/component/ConfigurationForm.js index 61e82dba6..87a8739dc 100644 --- a/ui/src/app/admin/component/ConfigurationForm.js +++ b/ui/src/app/admin/component/ConfigurationForm.js @@ -11,6 +11,7 @@ import { useProperties } from '../hoc/PropertiesProvider'; import Form from 'react-bootstrap/Form'; import FloatingLabel from 'react-bootstrap/FloatingLabel'; +import { useTranslator } from '../../i18n/hooks'; export function ConfigurationForm({ configuration = {}, loading, onSave, onCancel }) { @@ -20,7 +21,7 @@ export function ConfigurationForm({ configuration = {}, loading, onSave, onCance } }); - const { fields, prepend, remove } = useFieldArray({ + const { fields, append, remove } = useFieldArray({ control, name: "properties", }); @@ -36,7 +37,7 @@ export function ConfigurationForm({ configuration = {}, loading, onSave, onCance } }, []); - prepend(parsed); + append(parsed); }; const saveConfig = (formValues) => { @@ -44,6 +45,8 @@ export function ConfigurationForm({ configuration = {}, loading, onSave, onCance propertyName: p.propertyName, propertyValue: p.propertyValue, configFile: p.configFile, + category: p.category, + displayType: p.displayType })); onSave({ ...formValues, @@ -51,7 +54,7 @@ export function ConfigurationForm({ configuration = {}, loading, onSave, onCance }); }; - React.useEffect(() => console.log(configuration), [configuration]); + const translator = useTranslator(); return (<>
@@ -79,8 +82,8 @@ export function ConfigurationForm({ configuration = {}, loading, onSave, onCance
- Name - + Name +
@@ -97,11 +100,11 @@ export function ConfigurationForm({ configuration = {}, loading, onSave, onCance - - - - - + + + + + @@ -114,20 +117,23 @@ export function ConfigurationForm({ configuration = {}, loading, onSave, onCance {p.displayType !== 'boolean' ? - + label={translator('label.configuration-value')}> + : } - diff --git a/ui/src/app/admin/component/PropertySelector.js b/ui/src/app/admin/component/PropertySelector.js index 44cdfd085..976e0d220 100644 --- a/ui/src/app/admin/component/PropertySelector.js +++ b/ui/src/app/admin/component/PropertySelector.js @@ -82,7 +82,7 @@ export function PropertySelector ({ properties, options, onAddProperties }) { diff --git a/ui/src/app/admin/container/ConfigurationList.js b/ui/src/app/admin/container/ConfigurationList.js index 527f65c50..688535642 100644 --- a/ui/src/app/admin/container/ConfigurationList.js +++ b/ui/src/app/admin/container/ConfigurationList.js @@ -4,11 +4,17 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import Button from 'react-bootstrap/Button'; import ButtonGroup from 'react-bootstrap/ButtonGroup'; +import Popover from 'react-bootstrap/Popover'; import { Link } from 'react-router-dom'; import { Translate } from '../../i18n/components/translate'; import { DeleteConfirmation } from '../../core/components/DeleteConfirmation'; +import OverlayTrigger from 'react-bootstrap/esm/OverlayTrigger'; +import { useTranslator } from '../../i18n/hooks'; +import useFetch from 'use-http'; +import API_BASE_PATH from '../../App.constant'; +import { downloadAsZip } from '../../core/utility/download_as'; export function ConfigurationList({ configurations, onDelete, loading }) { @@ -16,6 +22,25 @@ export function ConfigurationList({ configurations, onDelete, loading }) { onDelete(id); } + const translate = useTranslator(); + + const downloader = useFetch(`${API_BASE_PATH}/shib/property/set`, { + cachePolicy: 'no-cache', + headers: { + 'Content-Type': 'application/zip', + 'Accept': 'application/zip' + } + }); + + const download = async (id, type) => { + await downloader.get(`/${id}${ type === 'single' ? '/onefile' : '' }`); + const file = await downloader.response.blob(); + if (downloader.response.ok) { + downloadAsZip('configuration', file); + console.log(file); + } + }; + return ( {(block) => @@ -46,7 +71,12 @@ export function ConfigurationList({ configurations, onDelete, loading }) { - + + @@ -57,17 +87,42 @@ export function ConfigurationList({ configurations, onDelete, loading }) { {c.name} + ) : - + }
PropertyCategoryTypeValueActionPropertyCategoryTypeValueAction
+
Configuration Name (label) Actions + Download + + Actions +
+
+ + + + + )} + aria-label={translate('')}> + + +
+ + + + )} + aria-label={translate('')}> + + + {downloader.loading && } +
+
-   Edit - @@ -75,7 +130,9 @@ export function ConfigurationList({ configurations, onDelete, loading }) {
No configurations. + No configurations. +
diff --git a/ui/src/app/admin/container/EditConfiguration.js b/ui/src/app/admin/container/EditConfiguration.js index bad543b69..d164c20e0 100644 --- a/ui/src/app/admin/container/EditConfiguration.js +++ b/ui/src/app/admin/container/EditConfiguration.js @@ -3,12 +3,10 @@ import React from 'react'; import { Prompt, useHistory, useParams } from 'react-router-dom'; import Translate from '../../i18n/components/translate'; import { useConfiguration } from '../hooks'; -import { Schema } from '../../form/Schema'; import { ConfigurationForm } from '../component/ConfigurationForm'; import { createNotificationAction, NotificationTypes, useNotificationDispatcher } from '../../notifications/hoc/Notifications'; import { useTranslator } from '../../i18n/hooks'; -import { BASE_PATH } from '../../App.constant'; import { PropertiesProvider } from '../hoc/PropertiesProvider'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faSpinner } from '@fortawesome/free-solid-svg-icons'; diff --git a/ui/src/app/admin/hoc/ConfigurationsProvider.js b/ui/src/app/admin/hoc/ConfigurationsProvider.js index aa23ddd45..2cd146260 100644 --- a/ui/src/app/admin/hoc/ConfigurationsProvider.js +++ b/ui/src/app/admin/hoc/ConfigurationsProvider.js @@ -23,7 +23,7 @@ export function ConfigurationsProvider({ children, cache = 'no-cache' }) { async function removeConfiguration(id) { let toast; - const resp = await del(`/${id}`); + const resp = await del(`shib/property/set/${id}`); if (response.ok) { loadConfigurations(); toast = createNotificationAction(`Deleted property successfully.`, NotificationTypes.SUCCESS); diff --git a/ui/src/app/admin/hooks.js b/ui/src/app/admin/hooks.js index 11184e55e..54d9d3117 100644 --- a/ui/src/app/admin/hooks.js +++ b/ui/src/app/admin/hooks.js @@ -61,4 +61,10 @@ export function useConfigurationUiSchema () { 'ui:widget': 'textarea' } }; -} \ No newline at end of file +} + +export function useConfigDownload () { + return useFetch(`${API_BASE_PATH}/shib/property/set`, { + cachePolicy: 'no-cache' + }); +} diff --git a/ui/src/app/core/utility/download_as_xml.js b/ui/src/app/core/utility/download_as.js similarity index 54% rename from ui/src/app/core/utility/download_as_xml.js rename to ui/src/app/core/utility/download_as.js index a9256fc63..4fc0cc4fd 100644 --- a/ui/src/app/core/utility/download_as_xml.js +++ b/ui/src/app/core/utility/download_as.js @@ -1,6 +1,11 @@ import * as FileSaver from 'file-saver'; +export const downloadAsZip = (fileName, data) => { + // const blob = new Blob([data], { type: 'text/zip;charset=utf-8' }); + FileSaver.saveAs(data, `${fileName}.zip`); +} + export const downloadAsXml = (fileName, xml) => { const blob = new Blob([xml], { type: 'text/xml;charset=utf-8' }); FileSaver.saveAs(blob, `${fileName}.xml`); -} \ No newline at end of file +} diff --git a/ui/src/app/core/utility/download_as_xml.test.js b/ui/src/app/core/utility/download_as_xml.test.js index 38a87e6fe..3e8583fe9 100644 --- a/ui/src/app/core/utility/download_as_xml.test.js +++ b/ui/src/app/core/utility/download_as_xml.test.js @@ -1,5 +1,5 @@ import * as FileSaver from 'file-saver'; -import { downloadAsXml } from './download_as_xml'; +import { downloadAsXml } from './download_as'; jest.mock('file-saver'); it('attempts to save the provided content', () => { diff --git a/ui/src/app/metadata/hoc/FilterTargetPreview.js b/ui/src/app/metadata/hoc/FilterTargetPreview.js index 8bd8550d3..2fd81e4c3 100644 --- a/ui/src/app/metadata/hoc/FilterTargetPreview.js +++ b/ui/src/app/metadata/hoc/FilterTargetPreview.js @@ -4,7 +4,7 @@ import { useFetch } from 'use-http'; import Modal from 'react-bootstrap/Modal'; import Button from 'react-bootstrap/Button'; import Translate from '../../i18n/components/translate'; -import { downloadAsXml } from '../../core/utility/download_as_xml'; +import { downloadAsXml } from '../../core/utility/download_as'; export function FilterTargetPreview ({ entityId, children }) { diff --git a/ui/src/app/metadata/view/MetadataXml.js b/ui/src/app/metadata/view/MetadataXml.js index 17e79d26a..fa6252cd9 100644 --- a/ui/src/app/metadata/view/MetadataXml.js +++ b/ui/src/app/metadata/view/MetadataXml.js @@ -9,7 +9,7 @@ import { MetadataObjectContext } from '../hoc/MetadataSelector'; import { MetadataXmlContext } from '../hoc/MetadataXmlLoader'; import { MetadataViewToggle } from '../component/MetadataViewToggle'; -import { downloadAsXml } from '../../core/utility/download_as_xml'; +import { downloadAsXml } from '../../core/utility/download_as'; export function MetadataXml () { const { xml, reload } = React.useContext(MetadataXmlContext); diff --git a/ui/src/theme/project/forms.scss b/ui/src/theme/project/forms.scss index b60471ce0..daa0d8cb9 100644 --- a/ui/src/theme/project/forms.scss +++ b/ui/src/theme/project/forms.scss @@ -124,6 +124,10 @@ mark { } } +.form-floating > label { + color:#9299A0; +} + @media only screen and (max-width: 1200px) { .form-section:not(:first-child) { border-left: 0px; From 3f9a99d8640d2d14817161cdbe835f2a86724870 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Wed, 31 Aug 2022 13:21:14 -0700 Subject: [PATCH 30/71] Fixed flicker in search --- .../app/admin/component/ConfigurationForm.js | 3 + .../app/admin/component/PropertySelector.js | 71 +++++++++++-------- 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/ui/src/app/admin/component/ConfigurationForm.js b/ui/src/app/admin/component/ConfigurationForm.js index 87a8739dc..cc13aa791 100644 --- a/ui/src/app/admin/component/ConfigurationForm.js +++ b/ui/src/app/admin/component/ConfigurationForm.js @@ -29,8 +29,11 @@ export function ConfigurationForm({ configuration = {}, loading, onSave, onCance const properties = useProperties(); const addProperties = (props) => { + const parsed = props.reduce((coll, prop, idx) => { if (prop.isCategory) { + console.log(properties.filter(p => p.category === prop.category)) + return [...coll, ...properties.filter(p => p.category === prop.category)]; } else { return [...coll, prop]; diff --git a/ui/src/app/admin/component/PropertySelector.js b/ui/src/app/admin/component/PropertySelector.js index 976e0d220..f0016e42e 100644 --- a/ui/src/app/admin/component/PropertySelector.js +++ b/ui/src/app/admin/component/PropertySelector.js @@ -1,5 +1,5 @@ import React, { Fragment, useCallback } from 'react'; -import { groupBy } from 'lodash'; +import { groupBy, orderBy } from 'lodash'; import { Highlighter, Menu, MenuItem, Token, Typeahead } from 'react-bootstrap-typeahead'; import Button from 'react-bootstrap/Button'; @@ -7,34 +7,44 @@ import { ToggleButton } from '../../form/component/ToggleButton'; export function PropertySelector ({ properties, options, onAddProperties }) { - // React.useEffect(() => console.log(properties), [properties]); - const menu = useCallback((results, menuProps, state) => { let index = 0; - const mapped = results.map(p => !p.category || p.category === '?' ? { ...p, category: 'Misc' } : p); - const grouped = groupBy(mapped, 'category'); - const items = Object.keys(grouped).sort().map((item) => ( - - {index !== 0 && } - - - {item} - Add all - - - {grouped[item].map((i) => { - const item = - p.propertyName === i.propertyName) }> - - {`- ${i.propertyName}`} - - ; - index += 1; - return item; - })} - - )); + const mapped = results.map((p, idx) => !p.category || p.category === '?' ? { ...p, category: 'Misc' } : p); + const ordered = orderBy(mapped, 'category'); + const grouped = groupBy(ordered, 'category'); + const items = Object.keys(grouped).sort().map((item) => { + index = index + 1; + const used = grouped[item].filter((i) => properties.some((p) => p.propertyName === i.propertyName)); + if (used.length >= grouped[item].length) { + return + } + return ( + + {index !== 0 && } + + + {item} - Add all + + + {grouped[item].map((i) => { + if (!properties.some((p) => p.propertyName === i.propertyName)) { + index = index + 1; + const item = + + + {`- ${i.propertyName}`} + + ; + return item; + } + return null; + })} + + ); + }); return {items}; }, [properties]); @@ -66,14 +76,15 @@ export function PropertySelector ({ properties, options, onAddProperties }) { select(selected)} - options={[...options]} + options={options} selected={selected} labelKey={option => `${option.propertyName}`} filterBy={['propertyName', 'category', 'displayType']} renderMenu={ menu } + paginate={false} multiple={ true } - renderToken={ token } - > + maxResults={options.length} + renderToken={ token }> {({ isMenuShown, toggleMenu }) => ( toggleMenu()}> Options From a2fe6259a9238951a2eedf2a6d8160384edef04b Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Wed, 31 Aug 2022 13:37:43 -0700 Subject: [PATCH 31/71] Fixed build error --- ui/src/app/admin/container/ConfigurationList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/app/admin/container/ConfigurationList.js b/ui/src/app/admin/container/ConfigurationList.js index 688535642..cef6880b2 100644 --- a/ui/src/app/admin/container/ConfigurationList.js +++ b/ui/src/app/admin/container/ConfigurationList.js @@ -10,7 +10,7 @@ import { Link } from 'react-router-dom'; import { Translate } from '../../i18n/components/translate'; import { DeleteConfirmation } from '../../core/components/DeleteConfirmation'; -import OverlayTrigger from 'react-bootstrap/esm/OverlayTrigger'; +import OverlayTrigger from 'react-bootstrap/OverlayTrigger'; import { useTranslator } from '../../i18n/hooks'; import useFetch from 'use-http'; import API_BASE_PATH from '../../App.constant'; From 80ec45c166c8ce53421de3672330eb7e02f89def Mon Sep 17 00:00:00 2001 From: chasegawa Date: Wed, 31 Aug 2022 16:20:10 -0700 Subject: [PATCH 32/71] SHIBUI-2341 Fixing logic to correctly import the XML --- .../ui/controller/EntityDescriptorController.java | 6 ++++-- .../admin/ui/domain/AttributeConsumingService.java | 11 ++++++++++- .../shibboleth/admin/ui/domain/SPSSODescriptor.java | 4 ++-- .../admin/ui/service/EntityDescriptorService.java | 2 ++ .../ui/service/JPAEntityDescriptorServiceImpl.java | 10 ++++++++-- .../controller/EntityDescriptorControllerTests.groovy | 8 ++++++-- testbed/postgres/docker-compose.yml | 2 ++ 7 files changed, 34 insertions(+), 9 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java index c2d9b81a0..a31838f1a 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java @@ -9,6 +9,7 @@ import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects; import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorService; import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorVersionService; +import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tags; import lombok.extern.slf4j.Slf4j; @@ -33,6 +34,7 @@ import javax.annotation.PostConstruct; import java.net.URI; import java.util.ConcurrentModificationException; +import java.util.Optional; @RestController @RequestMapping("/api") @@ -127,8 +129,8 @@ public ResponseEntity getSpecificVersion(@PathVariable String resourceId, @Pa private ResponseEntity handleUploadingEntityDescriptorXml(byte[] rawXmlBytes, String spName) throws Exception { final EntityDescriptor ed = EntityDescriptor.class.cast(openSamlObjects.unmarshalFromXml(rawXmlBytes)); ed.setServiceProviderName(spName); - - EntityDescriptorRepresentation persistedEd = entityDescriptorService.createNew(ed); + + EntityDescriptorRepresentation persistedEd = entityDescriptorService.createNewEntityDescriptorFromXMLOrigin(ed); return ResponseEntity.created(getResourceUriFor(persistedEd.getId())).body(persistedEd); } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AttributeConsumingService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AttributeConsumingService.java index 632bcb888..9adb45e2e 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AttributeConsumingService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AttributeConsumingService.java @@ -2,6 +2,7 @@ import lombok.EqualsAndHashCode; import org.hibernate.envers.Audited; +import org.opensaml.core.xml.XMLObject; import org.opensaml.core.xml.schema.XSBooleanValue; import javax.persistence.CascadeType; @@ -17,7 +18,6 @@ @EqualsAndHashCode(callSuper = true) @Audited public class AttributeConsumingService extends AbstractXMLObject implements org.opensaml.saml.saml2.metadata.AttributeConsumingService { - private int acsIndex; private boolean isDefault; @@ -93,4 +93,13 @@ public List getRequestedAtt public void setRequestedAttributes(List requestedAttributes) { this.requestedAttributes = requestedAttributes; } + + @Override + public List getOrderedChildren() { + List childXMLObjects = new ArrayList<>(); + childXMLObjects.addAll(serviceNames); + childXMLObjects.addAll(serviceDescriptions); + childXMLObjects.addAll(requestedAttributes); + return childXMLObjects; + } } \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SPSSODescriptor.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SPSSODescriptor.java index e90542c5a..52d37bf1f 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SPSSODescriptor.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SPSSODescriptor.java @@ -95,7 +95,7 @@ public AssertionConsumerService getDefaultAssertionConsumerService() { @Override public List getAttributeConsumingServices() { - return Lists.newArrayList(attributeConsumingServices); + return (List)(List) attributeConsumingServices; } public void setAttributeConsumingServices(List attributeConsumingServices) { @@ -124,4 +124,4 @@ public List getOrderedChildren() { public Optional getOptionalExtensions() { return Optional.ofNullable(this.getExtensions()); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java index b2bf96ac3..ed3f7be0e 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java @@ -114,4 +114,6 @@ EntityDescriptorRepresentation update(EntityDescriptorRepresentation edRepresent void updateDescriptorFromRepresentation(final org.opensaml.saml.saml2.metadata.EntityDescriptor entityDescriptor, final EntityDescriptorRepresentation representation); EntityDescriptorRepresentation updateEntityDescriptorEnabledStatus(String resourceId, boolean status) throws EntityNotFoundException, ForbiddenException; + + EntityDescriptorRepresentation createNewEntityDescriptorFromXMLOrigin(EntityDescriptor ed); } \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java index f6c419b31..be79e3097 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java @@ -102,11 +102,17 @@ public EntityDescriptor createDescriptorFromRepresentation(final EntityDescripto } @Override - public EntityDescriptorRepresentation createNew(EntityDescriptor ed) - throws ForbiddenException, ObjectIdExistsException, InvalidPatternMatchException { + public EntityDescriptorRepresentation createNew(EntityDescriptor ed) throws ForbiddenException, ObjectIdExistsException, InvalidPatternMatchException { return createNew(createRepresentationFromDescriptor(ed)); } + @Override + public EntityDescriptorRepresentation createNewEntityDescriptorFromXMLOrigin(EntityDescriptor ed) { + ed.setIdOfOwner(userService.getCurrentUserGroup().getOwnerId()); + EntityDescriptor savedEntity = entityDescriptorRepository.save(ed); + return createRepresentationFromDescriptor(savedEntity); + } + @Override public EntityDescriptorRepresentation createNew(EntityDescriptorRepresentation edRep) throws ForbiddenException, ObjectIdExistsException, InvalidPatternMatchException { diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy index 8861d1613..94de774b3 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy @@ -530,6 +530,11 @@ class EntityDescriptorControllerTests extends AbstractBaseDataJpaTest { urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified + + Shrink Space + Shrink Space Authenticator + + ''' @@ -551,7 +556,6 @@ class EntityDescriptorControllerTests extends AbstractBaseDataJpaTest { .andExpect(jsonPath("\$.assertionConsumerServices[0].binding").value("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST")) .andExpect(jsonPath("\$.assertionConsumerServices[0].makeDefault").value(false)) .andExpect(jsonPath("\$.assertionConsumerServices[0].locationUrl").value("https://test.scaldingspoon.org/test1/acs")) - } @WithMockAdmin @@ -691,4 +695,4 @@ class EntityDescriptorControllerTests extends AbstractBaseDataJpaTest { e instanceof ConcurrentModificationException } } -} +} \ No newline at end of file diff --git a/testbed/postgres/docker-compose.yml b/testbed/postgres/docker-compose.yml index c66b591a8..1a3dd4d82 100644 --- a/testbed/postgres/docker-compose.yml +++ b/testbed/postgres/docker-compose.yml @@ -18,9 +18,11 @@ services: - 8080:8080 - 5005:5005 - 8443:8443 + - 8000:8000 volumes: - ./conf:/conf - ./conf/application.yml:/application.yml + entrypoint: ["/usr/bin/java", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000", "-jar", "app.war"] networks: - front depends_on: From 854e03bc66873eb81731bc51e4e3a822896f6f0f Mon Sep 17 00:00:00 2001 From: chasegawa Date: Wed, 31 Aug 2022 16:38:13 -0700 Subject: [PATCH 33/71] SHIBUI-2341 Fixing logic to correctly save SurName --- .../edu/internet2/tier/shibboleth/admin/ui/domain/SurName.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SurName.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SurName.java index b6be50f64..031dc8eec 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SurName.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SurName.java @@ -18,6 +18,6 @@ public String getValue() { @Override public void setValue(String name) { - this.value = value; + this.value = name; } } \ No newline at end of file From ca71156771f481c5fc30f794cfa2e68072adab6b Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 1 Sep 2022 13:02:46 -0700 Subject: [PATCH 34/71] Fixed issue with duplicate properties --- ui/src/app/admin/component/ConfigurationForm.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/ui/src/app/admin/component/ConfigurationForm.js b/ui/src/app/admin/component/ConfigurationForm.js index cc13aa791..a97b1051e 100644 --- a/ui/src/app/admin/component/ConfigurationForm.js +++ b/ui/src/app/admin/component/ConfigurationForm.js @@ -12,6 +12,7 @@ import { useProperties } from '../hoc/PropertiesProvider'; import Form from 'react-bootstrap/Form'; import FloatingLabel from 'react-bootstrap/FloatingLabel'; import { useTranslator } from '../../i18n/hooks'; +import { includes } from 'lodash'; export function ConfigurationForm({ configuration = {}, loading, onSave, onCancel }) { @@ -27,20 +28,23 @@ export function ConfigurationForm({ configuration = {}, loading, onSave, onCance }); const properties = useProperties(); + const selected = watch('properties'); const addProperties = (props) => { const parsed = props.reduce((coll, prop, idx) => { if (prop.isCategory) { - console.log(properties.filter(p => p.category === prop.category)) - return [...coll, ...properties.filter(p => p.category === prop.category)]; } else { return [...coll, prop]; } }, []); - append(parsed); + const names = selected.map(p => p.propertyName); + + const filtered = parsed.filter(p => includes(names, p.propertyName) ? false : true); + + append(filtered); }; const saveConfig = (formValues) => { From 88c510e101fc999b94527957b0562f8bf09a1bf1 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 1 Sep 2022 13:47:02 -0700 Subject: [PATCH 35/71] Fixed issue with validation on name field --- .../main/resources/i18n/messages.properties | 1 + ui/src/app/admin/IdpConfiguration.js | 13 +++++- .../app/admin/component/ConfigurationForm.js | 40 ++++++++++++++++--- .../app/admin/container/EditConfiguration.js | 3 +- .../app/admin/container/NewConfiguration.js | 3 +- .../app/admin/hoc/ConfigurationsProvider.js | 2 +- 6 files changed, 51 insertions(+), 11 deletions(-) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index fcdf71519..5ce496eca 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -773,6 +773,7 @@ label.configuration-value=Value label.configuration-action=Action message.delete-property-title=Delete Configuration? message.delete-property-body=You are requesting to delete a configuration set. If you complete this process the set will be removed. This cannot be undone. Do you wish to continue? +message.name-required=Name is required. label.external-description=Description diff --git a/ui/src/app/admin/IdpConfiguration.js b/ui/src/app/admin/IdpConfiguration.js index 6f774d9ea..50bacf1e6 100644 --- a/ui/src/app/admin/IdpConfiguration.js +++ b/ui/src/app/admin/IdpConfiguration.js @@ -20,10 +20,19 @@ export function IdpConfiguration() { } /> - + + {(configurations) => + + } + + } /> - + + {(configurations) => + + } + } /> diff --git a/ui/src/app/admin/component/ConfigurationForm.js b/ui/src/app/admin/component/ConfigurationForm.js index a97b1051e..3744a61df 100644 --- a/ui/src/app/admin/component/ConfigurationForm.js +++ b/ui/src/app/admin/component/ConfigurationForm.js @@ -14,12 +14,16 @@ import FloatingLabel from 'react-bootstrap/FloatingLabel'; import { useTranslator } from '../../i18n/hooks'; import { includes } from 'lodash'; -export function ConfigurationForm({ configuration = {}, loading, onSave, onCancel }) { +export function ConfigurationForm({ configurations, configuration = {}, loading, onSave, onCancel }) { - const { control, register, getValues, watch, formState: { errors } } = useForm({ + const [names, setNames] = React.useState([]); + + const { control, register, getValues, watch, formState: { errors, isValid }, handleSubmit } = useForm({ defaultValues: { ...configuration - } + }, + reValidateMode: 'onChange', + mode: 'onChange', }); const { fields, append, remove } = useFieldArray({ @@ -63,6 +67,16 @@ export function ConfigurationForm({ configuration = {}, loading, onSave, onCance const translator = useTranslator(); + React.useEffect(() => { + setNames(configurations.map(p => p.name)); + }, [configurations]); + + React.useEffect(() => console.log(errors, names), [errors, names]); + + const onNext = (data) => { + console.log(data); + }; + return (<>
@@ -70,7 +84,7 @@ export function ConfigurationForm({ configuration = {}, loading, onSave, onCance

-
+
Name - + !includes(names, v) + } + })} /> + + {errors?.name?.type === 'unique' && } + {errors?.name?.type === 'required' && } +
diff --git a/ui/src/app/admin/container/EditConfiguration.js b/ui/src/app/admin/container/EditConfiguration.js index d164c20e0..f3749f2a0 100644 --- a/ui/src/app/admin/container/EditConfiguration.js +++ b/ui/src/app/admin/container/EditConfiguration.js @@ -11,7 +11,7 @@ import { PropertiesProvider } from '../hoc/PropertiesProvider'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faSpinner } from '@fortawesome/free-solid-svg-icons'; -export function EditConfiguration() { +export function EditConfiguration({ configurations }) { const history = useHistory(); const notifier = useNotificationDispatcher(); const translator = useTranslator(); @@ -81,6 +81,7 @@ export function EditConfiguration() { {configuration && save(data)} onCancel={() => cancel()} /> } diff --git a/ui/src/app/admin/container/NewConfiguration.js b/ui/src/app/admin/container/NewConfiguration.js index 84477fe40..34a587b45 100644 --- a/ui/src/app/admin/container/NewConfiguration.js +++ b/ui/src/app/admin/container/NewConfiguration.js @@ -11,7 +11,7 @@ import { useTranslator } from '../../i18n/hooks'; import { BASE_PATH } from '../../App.constant'; import { PropertiesProvider } from '../hoc/PropertiesProvider'; -export function NewConfiguration() { +export function NewConfiguration({ configurations }) { const history = useHistory(); const notifier = useNotificationDispatcher(); const translator = useTranslator(); @@ -67,6 +67,7 @@ export function NewConfiguration() { {(schema) => save(data)} diff --git a/ui/src/app/admin/hoc/ConfigurationsProvider.js b/ui/src/app/admin/hoc/ConfigurationsProvider.js index 2cd146260..99220c94c 100644 --- a/ui/src/app/admin/hoc/ConfigurationsProvider.js +++ b/ui/src/app/admin/hoc/ConfigurationsProvider.js @@ -39,4 +39,4 @@ export function ConfigurationsProvider({ children, cache = 'no-cache' }) { React.useEffect(() => { loadConfigurations() }, []); return (<>{children(configurations, removeConfiguration, loading)}); -} \ No newline at end of file +} From f82492f5b0fc94e541b3aac4344b601dad118265 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 1 Sep 2022 13:49:02 -0700 Subject: [PATCH 36/71] Removed console log --- ui/src/app/admin/component/ConfigurationForm.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ui/src/app/admin/component/ConfigurationForm.js b/ui/src/app/admin/component/ConfigurationForm.js index 3744a61df..49f8abb7f 100644 --- a/ui/src/app/admin/component/ConfigurationForm.js +++ b/ui/src/app/admin/component/ConfigurationForm.js @@ -71,11 +71,7 @@ export function ConfigurationForm({ configurations, configuration = {}, loading, setNames(configurations.map(p => p.name)); }, [configurations]); - React.useEffect(() => console.log(errors, names), [errors, names]); - - const onNext = (data) => { - console.log(data); - }; + const onNext = (data) => {}; return (<>
From 69a4bf3ec094de8b183482c09e64bc8b9ef297a9 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 1 Sep 2022 13:58:23 -0700 Subject: [PATCH 37/71] Fixed sets without properties --- backend/src/main/resources/i18n/messages.properties | 1 + ui/src/app/admin/component/ConfigurationForm.js | 12 +++++++++++- ui/src/app/admin/component/PropertySelector.js | 3 +-- ui/src/app/admin/hoc/PropertiesProvider.js | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index 5ce496eca..dcd97aee4 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -774,6 +774,7 @@ label.configuration-action=Action message.delete-property-title=Delete Configuration? message.delete-property-body=You are requesting to delete a configuration set. If you complete this process the set will be removed. This cannot be undone. Do you wish to continue? message.name-required=Name is required. +message.properties-none=At least one property is required. label.external-description=Description diff --git a/ui/src/app/admin/component/ConfigurationForm.js b/ui/src/app/admin/component/ConfigurationForm.js index 49f8abb7f..90bd31db9 100644 --- a/ui/src/app/admin/component/ConfigurationForm.js +++ b/ui/src/app/admin/component/ConfigurationForm.js @@ -29,6 +29,9 @@ export function ConfigurationForm({ configurations, configuration = {}, loading, const { fields, append, remove } = useFieldArray({ control, name: "properties", + rules: { + minLength: 1 + } }); const properties = useProperties(); @@ -80,7 +83,7 @@ export function ConfigurationForm({ configurations, configuration = {}, loading,
diff --git a/ui/src/app/admin/component/PropertySelector.js b/ui/src/app/admin/component/PropertySelector.js index f0016e42e..85da52888 100644 --- a/ui/src/app/admin/component/PropertySelector.js +++ b/ui/src/app/admin/component/PropertySelector.js @@ -9,8 +9,7 @@ export function PropertySelector ({ properties, options, onAddProperties }) { const menu = useCallback((results, menuProps, state) => { let index = 0; - const mapped = results.map((p, idx) => !p.category || p.category === '?' ? { ...p, category: 'Misc' } : p); - const ordered = orderBy(mapped, 'category'); + const ordered = orderBy(results, 'category'); const grouped = groupBy(ordered, 'category'); const items = Object.keys(grouped).sort().map((item) => { index = index + 1; diff --git a/ui/src/app/admin/hoc/PropertiesProvider.js b/ui/src/app/admin/hoc/PropertiesProvider.js index 95bbc5d04..5ab7bde75 100644 --- a/ui/src/app/admin/hoc/PropertiesProvider.js +++ b/ui/src/app/admin/hoc/PropertiesProvider.js @@ -30,7 +30,7 @@ function PropertiesProvider({ children, cache = 'no-cache' }) { function useProperties() { const { properties } = React.useContext(PropertiesContext); - return properties; + return properties.map((p, idx) => !p.category || p.category === '?' ? { ...p, category: 'Misc' } : p);; } function usePropertiesLoading() { From 38b5d335107ca11b6476a814ff0523afd2587b3d Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 1 Sep 2022 14:43:14 -0700 Subject: [PATCH 38/71] Updated text for notifications --- ui/src/app/admin/component/PropertySelector.js | 4 ++-- ui/src/app/admin/container/EditConfiguration.js | 2 +- ui/src/app/admin/container/NewConfiguration.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ui/src/app/admin/component/PropertySelector.js b/ui/src/app/admin/component/PropertySelector.js index 85da52888..375b75747 100644 --- a/ui/src/app/admin/component/PropertySelector.js +++ b/ui/src/app/admin/component/PropertySelector.js @@ -11,11 +11,11 @@ export function PropertySelector ({ properties, options, onAddProperties }) { let index = 0; const ordered = orderBy(results, 'category'); const grouped = groupBy(ordered, 'category'); - const items = Object.keys(grouped).sort().map((item) => { + const items = Object.keys(grouped).sort().map((item, idx) => { index = index + 1; const used = grouped[item].filter((i) => properties.some((p) => p.propertyName === i.propertyName)); if (used.length >= grouped[item].length) { - return + return } return ( diff --git a/ui/src/app/admin/container/EditConfiguration.js b/ui/src/app/admin/container/EditConfiguration.js index f3749f2a0..dfa90aa8e 100644 --- a/ui/src/app/admin/container/EditConfiguration.js +++ b/ui/src/app/admin/container/EditConfiguration.js @@ -28,7 +28,7 @@ export function EditConfiguration({ configurations }) { const resp = await put(`${config.resourceId}`, config); if (response.ok) { gotoList({ refresh: true }); - toast = createNotificationAction(`Added property successfully.`, NotificationTypes.SUCCESS); + toast = createNotificationAction(`Updated configuration successfully.`, NotificationTypes.SUCCESS); } else { toast = createNotificationAction(`${resp.errorCode} - ${translator(resp.errorMessage)}`, NotificationTypes.ERROR); } diff --git a/ui/src/app/admin/container/NewConfiguration.js b/ui/src/app/admin/container/NewConfiguration.js index 34a587b45..d9a1bf33c 100644 --- a/ui/src/app/admin/container/NewConfiguration.js +++ b/ui/src/app/admin/container/NewConfiguration.js @@ -25,7 +25,7 @@ export function NewConfiguration({ configurations }) { const resp = await post(``, config); if (response.ok) { gotoList({ refresh: true }); - toast = createNotificationAction(`Added property successfully.`, NotificationTypes.SUCCESS); + toast = createNotificationAction(`Added configuration successfully.`, NotificationTypes.SUCCESS); } else { toast = createNotificationAction(`${resp.errorCode} - ${translator(resp.errorMessage)}`, NotificationTypes.ERROR); } From d58d82783d3dc80902b4854889edd273e505c4b6 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 2 Sep 2022 10:00:34 -0700 Subject: [PATCH 39/71] SHIBUI-2270 / SHIBUI-2373 Fixing output JSON for the UI so type values are correct --- .../shib/properties/ShibPropertySetting.java | 2 + .../ShibPropertySettingJacksonSerializer.java | 43 +++++++++++++ .../ShibPropertiesControllerTests.groovy | 60 +++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/shib/properties/ShibPropertySettingJacksonSerializer.java diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/shib/properties/ShibPropertySetting.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/shib/properties/ShibPropertySetting.java index 1fd4d73fd..aeb1bd579 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/shib/properties/ShibPropertySetting.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/shib/properties/ShibPropertySetting.java @@ -1,5 +1,6 @@ package edu.internet2.tier.shibboleth.admin.ui.domain.shib.properties; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.Data; import org.hibernate.envers.Audited; @@ -12,6 +13,7 @@ @Entity(name = "shib_property_setting") @Audited @Data +@JsonSerialize(using = ShibPropertySettingJacksonSerializer.class) public class ShibPropertySetting { @Id @GeneratedValue diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/shib/properties/ShibPropertySettingJacksonSerializer.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/shib/properties/ShibPropertySettingJacksonSerializer.java new file mode 100644 index 000000000..6bd5b926c --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/shib/properties/ShibPropertySettingJacksonSerializer.java @@ -0,0 +1,43 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.shib.properties; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +import java.io.IOException; + +public class ShibPropertySettingJacksonSerializer extends StdSerializer { + public ShibPropertySettingJacksonSerializer() { + this(null); + } + + public ShibPropertySettingJacksonSerializer(Class t) { + super(t); + } + + @Override + public void serialize(ShibPropertySetting sps, JsonGenerator generator, SerializerProvider provider) throws IOException { + generator.writeStartObject(); + generator.writeNumberField("resourceId", sps.getResourceId()); + generator.writeStringField("configFile", sps.getConfigFile()); + generator.writeStringField("propertyName", sps.getPropertyName()); + if (sps.getCategory() != null) { + generator.writeStringField("category", sps.getCategory()); + } + generator.writeStringField("displayType", sps.getDisplayType()); + + switch (sps.getDisplayType()) { + case "boolean": + generator.writeBooleanField("propertyValue", Boolean.valueOf(sps.getPropertyValue())); + break; + case "number": + generator.writeNumberField("propertyValue", Long.parseLong(sps.getPropertyValue())); + break; + default: + generator.writeStringField("propertyValue", sps.getPropertyValue()); + } + + generator.writeEndObject(); + } + +} \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesControllerTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesControllerTests.groovy index e5c418f9d..c5ab4a003 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesControllerTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesControllerTests.groovy @@ -63,6 +63,7 @@ class ShibPropertiesControllerTests extends AbstractBaseDataJpaTest { it.propertyName = 'foo' it.configFile = 'defaults.properties' it.propertyValue = 'bar' + it.displayType = 'string' it } @@ -71,6 +72,7 @@ class ShibPropertiesControllerTests extends AbstractBaseDataJpaTest { it.propertyName = 'foo2' it.configFile = 'defaults.properties' it.propertyValue = 'bar2' + it.displayType = 'string' it } @@ -151,6 +153,7 @@ class ShibPropertiesControllerTests extends AbstractBaseDataJpaTest { it.propertyName = 'food.for.thought' it.configFile = 'defaults.properties' it.propertyValue = 'true' + it.displayType = 'boolean' it } @@ -158,6 +161,7 @@ class ShibPropertiesControllerTests extends AbstractBaseDataJpaTest { it.propertyName = 'food2.for2.thought' it.configFile = 'defaults.properties' it.propertyValue = 'true' + it.displayType = 'boolean' it } @@ -207,4 +211,60 @@ class ShibPropertiesControllerTests extends AbstractBaseDataJpaTest { result.andExpect(status().isOk()).andExpect(jsonPath("\$.name").value("newName")) propertySetRepo.findByResourceId(defaultSetResourceId).name.equals("newName") } + + @WithMockAdmin + def "Validate that JSON data is correct for UI"() { + given: + ShibPropertySetting prop = new ShibPropertySetting().with { it -> + it.propertyName = 'asBoolean' + it.configFile = 'defaults.properties' + it.propertyValue = 'true' + it.displayType = 'boolean' + + it + } + propertySettingRepo.save(prop) + ShibPropertySetting prop2 = new ShibPropertySetting().with { it -> + it.propertyName = 'asNumber' + it.configFile = 'defaults.properties' + it.propertyValue = '33' + it.displayType = 'number' + + it + } + propertySettingRepo.save(prop2) + ShibPropertySetting prop3 = new ShibPropertySetting().with { it -> + it.propertyName = 'anythingElse' + it.configFile = 'defaults.properties' + it.propertyValue = '33' + it.displayType = 'string' + + it + } + propertySettingRepo.save(prop3) + ShibPropertySet set = new ShibPropertySet().with {it -> + it.properties.add(prop) + it.properties.add(prop2) + it.properties.add(prop3) + it.name = 'somerandom' + + it + } + def savedSet = propertySetRepo.save(set) + entityManager.flush() + entityManager.clear() + + when: + def result = mockMvc.perform(get("/api/shib/property/set/" + savedSet.getResourceId())) + System.println(result.andReturn().getResponse().getContentAsString()) + then: + result.andExpect(status().isOk()) + .andExpect(jsonPath("\$.resourceId").value(savedSet.getResourceId())) + .andExpect(jsonPath("\$.properties[0].propertyName").value("asBoolean")) + .andExpect(jsonPath("\$.properties[0].propertyValue").value(Boolean.TRUE)) + .andExpect(jsonPath("\$.properties[1].propertyName").value("asNumber")) + .andExpect(jsonPath("\$.properties[1].propertyValue").value(33)) + .andExpect(jsonPath("\$.properties[2].propertyName").value("anythingElse")) + .andExpect(jsonPath("\$.properties[2].propertyValue").value("33")) + } } \ No newline at end of file From e0bd2c33d9ae04ddb11dc2b7f8c6f71c2b93fdcd Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 2 Sep 2022 10:15:53 -0700 Subject: [PATCH 40/71] SHIBUI-2374 Added logic so that entities with the same entity id won't be created. --- .../admin/ui/controller/EntityDescriptorController.java | 4 ++++ .../admin/ui/service/EntityDescriptorService.java | 2 ++ .../admin/ui/service/JPAEntityDescriptorServiceImpl.java | 5 +++++ .../ui/controller/EntityDescriptorControllerTests.groovy | 7 +++++++ 4 files changed, 18 insertions(+) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java index a31838f1a..81d62a1ad 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java @@ -128,6 +128,10 @@ public ResponseEntity getSpecificVersion(@PathVariable String resourceId, @Pa private ResponseEntity handleUploadingEntityDescriptorXml(byte[] rawXmlBytes, String spName) throws Exception { final EntityDescriptor ed = EntityDescriptor.class.cast(openSamlObjects.unmarshalFromXml(rawXmlBytes)); + if (entityDescriptorService.entityExists(ed.getEntityID())) { + throw new ObjectIdExistsException("Entity with ID: " + ed.getEntityID() + "exists"); + } + ed.setServiceProviderName(spName); EntityDescriptorRepresentation persistedEd = entityDescriptorService.createNewEntityDescriptorFromXMLOrigin(ed); diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java index ed3f7be0e..6ecf9073e 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java @@ -116,4 +116,6 @@ EntityDescriptorRepresentation update(EntityDescriptorRepresentation edRepresent EntityDescriptorRepresentation updateEntityDescriptorEnabledStatus(String resourceId, boolean status) throws EntityNotFoundException, ForbiddenException; EntityDescriptorRepresentation createNewEntityDescriptorFromXMLOrigin(EntityDescriptor ed); + + boolean entityExists(String entityID); } \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java index be79e3097..ec5c28048 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java @@ -113,6 +113,11 @@ public EntityDescriptorRepresentation createNewEntityDescriptorFromXMLOrigin(Ent return createRepresentationFromDescriptor(savedEntity); } + @Override + public boolean entityExists(String entityID) { + return entityDescriptorRepository.findByEntityID(entityID) != null ; + } + @Override public EntityDescriptorRepresentation createNew(EntityDescriptorRepresentation edRep) throws ForbiddenException, ObjectIdExistsException, InvalidPatternMatchException { diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy index 94de774b3..35bd77ea2 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy @@ -556,6 +556,13 @@ class EntityDescriptorControllerTests extends AbstractBaseDataJpaTest { .andExpect(jsonPath("\$.assertionConsumerServices[0].binding").value("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST")) .andExpect(jsonPath("\$.assertionConsumerServices[0].makeDefault").value(false)) .andExpect(jsonPath("\$.assertionConsumerServices[0].locationUrl").value("https://test.scaldingspoon.org/test1/acs")) + + try { + mockMvc.perform(post("/api/EntityDescriptor").contentType(APPLICATION_XML).content(postedBody).param("spName", spName)) + } + catch (Exception e) { + e instanceof ObjectIdExistsException + } } @WithMockAdmin From 2e692dd5a014b9e4fb70d76912685ef9a6319f3b Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 2 Sep 2022 10:49:47 -0700 Subject: [PATCH 41/71] SHIBUI-2270 fixed broken test --- .../ui/service/ShibConfigurationServiceTests.groovy | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/ShibConfigurationServiceTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/ShibConfigurationServiceTests.groovy index 36f548215..4454ef8ca 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/ShibConfigurationServiceTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/ShibConfigurationServiceTests.groovy @@ -30,7 +30,7 @@ class ShibConfigurationServiceTests extends AbstractBaseDataJpaTest { * We use the object mapper to transform to json and then back to new objects so that what we send to the service is never * the actual hibernate entity from the db, but an unattached copy (ie what the service would be getting as input in reality) */ - def ObjectMapper objectMapper = new ObjectMapper(); + ObjectMapper objectMapper = new ObjectMapper() @Transactional def setup() { @@ -38,6 +38,7 @@ class ShibConfigurationServiceTests extends AbstractBaseDataJpaTest { it.propertyName = 'foo' it.configFile = 'defaults.properties' it.propertyValue = 'bar' + it.displayType = 'string' it } @@ -46,6 +47,7 @@ class ShibConfigurationServiceTests extends AbstractBaseDataJpaTest { it.propertyName = 'foo2' it.configFile = 'defaults.properties' it.propertyValue = 'bar2' + it.displayType = 'string' it } @@ -68,8 +70,8 @@ class ShibConfigurationServiceTests extends AbstractBaseDataJpaTest { def "check delete"() { given: - def long setCount = propertySetRepo.count() - def long propsCount = propertySettingRepo.count() + long setCount = propertySetRepo.count() + long propsCount = propertySettingRepo.count() expect: setCount == 1 @@ -120,6 +122,7 @@ class ShibConfigurationServiceTests extends AbstractBaseDataJpaTest { it.propertyName = 'food.for.thought' it.configFile = 'defaults.properties' it.propertyValue = 'true' + it.displayType = 'boolean' it } From 7b8cb43263f7ebea6e8eddbb9a98a3eb6b389c31 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Fri, 2 Sep 2022 11:06:28 -0700 Subject: [PATCH 42/71] Fixed x mark in dropdown --- ui/src/theme/project/typeahead.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/theme/project/typeahead.scss b/ui/src/theme/project/typeahead.scss index 0fca115fa..5bf91a8ca 100644 --- a/ui/src/theme/project/typeahead.scss +++ b/ui/src/theme/project/typeahead.scss @@ -35,7 +35,7 @@ height: 1em; padding: .25em .25em; color: inherit; - background: transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#007bff' %3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat; + background: transparent center/1em auto no-repeat; border: 0; border-radius: .375rem; } From 3c154e691289fbfcedaa574b51500ad8e6a8911d Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Fri, 2 Sep 2022 12:19:42 -0700 Subject: [PATCH 43/71] Fixed issue with validation of set names --- ui/src/app/admin/component/ConfigurationForm.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/src/app/admin/component/ConfigurationForm.js b/ui/src/app/admin/component/ConfigurationForm.js index 90bd31db9..e4088f98d 100644 --- a/ui/src/app/admin/component/ConfigurationForm.js +++ b/ui/src/app/admin/component/ConfigurationForm.js @@ -110,8 +110,9 @@ export function ConfigurationForm({ configurations, configuration = {}, loading, placeholder={translator('label.configuration-name-placeholder')} {...register(`name`, { required: true, + value: configuration.value || null, validate: { - unique: v => !includes(names, v) + unique: v => v.trim() === configuration.name || !includes(names, v) } })} /> From 59aa6f41b91049fc88a8bd7dd2fe23dde1c4e622 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Fri, 2 Sep 2022 12:34:15 -0700 Subject: [PATCH 44/71] Fixed issue with duplicated properties from categories --- .../app/admin/component/PropertySelector.js | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/ui/src/app/admin/component/PropertySelector.js b/ui/src/app/admin/component/PropertySelector.js index 375b75747..9f219e403 100644 --- a/ui/src/app/admin/component/PropertySelector.js +++ b/ui/src/app/admin/component/PropertySelector.js @@ -1,11 +1,12 @@ import React, { Fragment, useCallback } from 'react'; -import { groupBy, orderBy } from 'lodash'; +import { groupBy, includes, orderBy } from 'lodash'; import { Highlighter, Menu, MenuItem, Token, Typeahead } from 'react-bootstrap-typeahead'; import Button from 'react-bootstrap/Button'; import { ToggleButton } from '../../form/component/ToggleButton'; export function PropertySelector ({ properties, options, onAddProperties }) { + const [selected, setSelected] = React.useState([]); const menu = useCallback((results, menuProps, state) => { let index = 0; @@ -14,17 +15,20 @@ export function PropertySelector ({ properties, options, onAddProperties }) { const items = Object.keys(grouped).sort().map((item, idx) => { index = index + 1; const used = grouped[item].filter((i) => properties.some((p) => p.propertyName === i.propertyName)); - if (used.length >= grouped[item].length) { + if (used.length >= grouped[item].length || includes(selected, item)) { return } + const cat = {category: item, propertyName: item, isCategory: true}; + const catSelected = selected.some(s => s.propertyName === item); return ( {index !== 0 && } + className="fw-bold" + disabled={catSelected}> {item} - Add all @@ -32,7 +36,7 @@ export function PropertySelector ({ properties, options, onAddProperties }) { if (!properties.some((p) => p.propertyName === i.propertyName)) { index = index + 1; const item = - + s.propertyName === i.propertyName)}> {`- ${i.propertyName}`} @@ -46,7 +50,7 @@ export function PropertySelector ({ properties, options, onAddProperties }) { }); return {items}; - }, [properties]); + }, [properties, selected]); const token = (option, { onRemove }, index) => ( { onAddProperties(s); setSelected([]); - } + }; return ( From b9ddd1421dc5fae47642fa6eed7b53137d96dfce Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 6 Sep 2022 09:50:20 -0700 Subject: [PATCH 45/71] Fixed issue with duplicate properties --- ui/src/app/admin/component/ConfigurationForm.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ui/src/app/admin/component/ConfigurationForm.js b/ui/src/app/admin/component/ConfigurationForm.js index e4088f98d..751e94310 100644 --- a/ui/src/app/admin/component/ConfigurationForm.js +++ b/ui/src/app/admin/component/ConfigurationForm.js @@ -12,7 +12,7 @@ import { useProperties } from '../hoc/PropertiesProvider'; import Form from 'react-bootstrap/Form'; import FloatingLabel from 'react-bootstrap/FloatingLabel'; import { useTranslator } from '../../i18n/hooks'; -import { includes } from 'lodash'; +import { includes, uniqBy } from 'lodash'; export function ConfigurationForm({ configurations, configuration = {}, loading, onSave, onCancel }) { @@ -51,7 +51,9 @@ export function ConfigurationForm({ configurations, configuration = {}, loading, const filtered = parsed.filter(p => includes(names, p.propertyName) ? false : true); - append(filtered); + const deduped = uniqBy(filtered, (i) => i.propertyName); + + append(deduped); }; const saveConfig = (formValues) => { From 038f087741f340898a41c2e3b7348f5173266a98 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 6 Sep 2022 13:32:44 -0700 Subject: [PATCH 46/71] SHIBUI-2270 Added cleanup of settings to the danger controller --- .../admin/ui/controller/DangerController.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/DangerController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/DangerController.java index 2ab357a03..7af217eb2 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/DangerController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/DangerController.java @@ -7,6 +7,8 @@ import edu.internet2.tier.shibboleth.admin.ui.repository.FilterRepository; import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository; import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolversPositionOrderContainerRepository; +import edu.internet2.tier.shibboleth.admin.ui.repository.ShibPropertySetRepository; +import edu.internet2.tier.shibboleth.admin.ui.repository.ShibPropertySettingRepository; import edu.internet2.tier.shibboleth.admin.ui.security.repository.GroupsRepository; import edu.internet2.tier.shibboleth.admin.ui.security.repository.OwnershipRepository; import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; @@ -59,6 +61,12 @@ public class DangerController { @Autowired private OwnershipRepository ownershipRepository; + @Autowired + private ShibPropertySetRepository shibPropertySetRepository; + + @Autowired + private ShibPropertySettingRepository shibPropertySettingRepository; + @Autowired UserRepository userRepository; @@ -84,9 +92,18 @@ public ResponseEntity wipeOut() { clearUsersAndGroups(); + clearShibSettings(); + return ResponseEntity.ok("yes, you did it"); } + private void clearShibSettings() { + shibPropertySetRepository.findAll().forEach(shibPropSet -> { + shibPropertySettingRepository.deleteAll(shibPropSet.getProperties()); + shibPropertySetRepository.delete(shibPropSet); + }); + } + private void clearUsersAndGroups() { groupRepository.deleteAll(); ownershipRepository.clearAllOwnedByGroup(); @@ -99,4 +116,4 @@ private void clearUsersAndGroups() { groupService.ensureAdminGroupExists(); devConfig.createDevUsersAndGroups(); } -} +} \ No newline at end of file From ef0807574b9a7ee01ba298e5a40ce33de25647d6 Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Wed, 7 Sep 2022 10:29:50 -0400 Subject: [PATCH 47/71] SHIBUI-2270 Added selenium tests for properties CRUD operations. --- .../admin/ui/SeleniumSIDETest.groovy | 2 + .../integration/resources/SHIBUI-2270-1.side | 562 +++++ .../integration/resources/SHIBUI-2270-2.side | 2143 +++++++++++++++++ 3 files changed, 2707 insertions(+) create mode 100644 backend/src/integration/resources/SHIBUI-2270-1.side create mode 100644 backend/src/integration/resources/SHIBUI-2270-2.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 beb593a70..4a903610e 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 @@ -157,6 +157,8 @@ class SeleniumSIDETest extends Specification { 'SHIBUI-1674: Verify metadata source tooltips' | '/SHIBUI-1674-1.side' 'SHIBUI-1674: Verify metadata provider tooltips' | '/SHIBUI-1674-2.side' 'SHIBUI-1674: Verify advanced menu tooltips' | '/SHIBUI-1674-3.side' + 'SHIBUI-2270: Verify property set CRUD' | '/SHIBUI-2270-1.side' + 'SHIBUI-2270: Verify full property set' | '/SHIBUI-2270-2.side' 'SHIBUI-2268: Verify Algorithm Filter' | '/SHIBUI-2268.side' 'SHIBUI-2269: Verify XML generation of external filters' | '/SHIBUI-2269.side' } diff --git a/backend/src/integration/resources/SHIBUI-2270-1.side b/backend/src/integration/resources/SHIBUI-2270-1.side new file mode 100644 index 000000000..b9d67cff4 --- /dev/null +++ b/backend/src/integration/resources/SHIBUI-2270-1.side @@ -0,0 +1,562 @@ +{ + "id": "1b31a551-eb09-4bd4-8db9-694bf1539a46", + "version": "2.0", + "name": "SHIBUI-2270-1", + "url": "http://localhost:10101", + "tests": [{ + "id": "841ade0e-83bd-4a4b-94f2-de6bd5c536b2", + "name": "SHIBUI-2270-1", + "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": "d388e4d3-79b7-4948-a6f6-907d0a46f35c", + "comment": "", + "command": "click", + "target": "id=advanced-nav-dropdown-toggle", + "targets": [ + ["id=advanced-nav-dropdown-toggle", "id"], + ["css=#advanced-nav-dropdown-toggle", "css:finder"], + ["xpath=//button[@id='advanced-nav-dropdown-toggle']", "xpath:attributes"], + ["xpath=//div[@id='advanced-nav-dropdown']/button", "xpath:idRelative"], + ["xpath=//div[3]/button", "xpath:position"], + ["xpath=//button[contains(.,'Advanced')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "14841cc4-c8f1-48c2-9f85-a7aaf9f0a91d", + "comment": "", + "command": "click", + "target": "id=advanced-nav-dropdown-properties", + "targets": [ + ["id=advanced-nav-dropdown-properties", "id"], + ["linkText=Shibboleth configurations", "linkText"], + ["css=#advanced-nav-dropdown-properties", "css:finder"], + ["xpath=//a[contains(text(),'Shibboleth configurations')]", "xpath:link"], + ["xpath=//a[@id='advanced-nav-dropdown-properties']", "xpath:attributes"], + ["xpath=//div[@id='advanced-nav-dropdown']/div/a[5]", "xpath:idRelative"], + ["xpath=//a[contains(@href, '/configurations')]", "xpath:href"], + ["xpath=//a[5]", "xpath:position"], + ["xpath=//a[contains(.,'Shibboleth configurations')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "8a824b21-89be-4531-baa3-db217375dfb1", + "comment": "", + "command": "click", + "target": "linkText=Create Shibboleth configuration set", + "targets": [ + ["linkText=Create Shibboleth configuration set", "linkText"], + ["css=.btn-success", "css:finder"], + ["xpath=//div[@id='root']/div/main/div/section/div/div[2]/div/a", "xpath:idRelative"], + ["xpath=//a[contains(@href, '/configurations/new')]", "xpath:href"], + ["xpath=//div[2]/div/a", "xpath:position"], + ["xpath=//a[contains(.,'  Create Shibboleth configuration set')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "da25d3be-ebb4-4ad7-8264-dfb688ef157d", + "comment": "", + "command": "type", + "target": "id=formName", + "targets": [ + ["id=formName", "id"], + ["name=name", "name"], + ["css=#formName", "css:finder"], + ["xpath=//input[@id='formName']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div/div/div/input", "xpath:idRelative"], + ["xpath=//input", "xpath:position"] + ], + "value": "Test Configuration" + }, { + "id": "7d40119c-c87f-4743-bdfb-3368f556ce89", + "comment": "", + "command": "click", + "target": "css=.rbt-input-main", + "targets": [ + ["css=.rbt-input-main", "css:finder"], + ["xpath=//input[@value='']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/div/div/div/input", "xpath:idRelative"], + ["xpath=//div/div/div/div/input", "xpath:position"] + ], + "value": "" + }, { + "id": "a9ae0330-b553-49d6-aafd-0566d6ef8015", + "comment": "", + "command": "click", + "target": "id=property-selector-item-2", + "targets": [ + ["id=property-selector-item-2", "id"], + ["linkText=- idp.resolvertest.accessPolicy", "linkText"], + ["css=#property-selector-item-2", "css:finder"], + ["xpath=//a[contains(text(),'- idp.resolvertest.accessPolicy')]", "xpath:link"], + ["xpath=//a[@id='property-selector-item-2']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[2]", "xpath:href"], + ["xpath=//div[2]/div/div/div/div/div[2]/a", "xpath:position"], + ["xpath=//a[contains(.,'- idp.resolvertest.accessPolicy')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "e9a4a85f-b6bb-4d3a-9042-4d873c3b6cc6", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[8]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "e4bc2487-9f04-45ee-b6ac-dd2b0de2b54e", + "comment": "", + "command": "click", + "target": "id=property-selector-item-10", + "targets": [ + ["id=property-selector-item-10", "id"], + ["linkText=- idp.lockout.defaultAuthenticationMethods", "linkText"], + ["css=#property-selector-item-10", "css:finder"], + ["xpath=//a[contains(text(),'- idp.lockout.defaultAuthenticationMethods')]", "xpath:link"], + ["xpath=//a[@id='property-selector-item-10']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/a[8]", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[10]", "xpath:href"], + ["xpath=//a[8]", "xpath:position"], + ["xpath=//a[contains(.,'- idp.lockout.defaultAuthenticationMethods')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "1384295d-fed8-42f4-9651-27a900fbb2ac", + "comment": "", + "command": "click", + "target": "css=.ms-2", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[10]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" + }, { + "id": "e90d0c3a-ef37-4c83-a7d1-1fc053e6404c", + "comment": "", + "command": "type", + "target": "id=valueInput-idp.resolvertest.accessPolicy", + "targets": [ + ["id=valueInput-idp.resolvertest.accessPolicy", "id"], + ["name=properties.0.propertyValue", "name"], + ["css=#valueInput-idp\\.resolvertest\\.accessPolicy", "css:finder"], + ["xpath=//input[@id='valueInput-idp.resolvertest.accessPolicy']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[4]/div/table/tbody/tr/td[4]/div/input", "xpath:idRelative"], + ["xpath=//td[4]/div/input", "xpath:position"] + ], + "value": "test1" + }, { + "id": "fa61e81b-309a-4e32-b5ce-61f7dcd06eb3", + "comment": "", + "command": "type", + "target": "id=valueInput-idp.lockout.defaultAuthenticationMethods", + "targets": [ + ["id=valueInput-idp.lockout.defaultAuthenticationMethods", "id"], + ["name=properties.1.propertyValue", "name"], + ["css=#valueInput-idp\\.lockout\\.defaultAuthenticationMethods", "css:finder"], + ["xpath=//input[@id='valueInput-idp.lockout.defaultAuthenticationMethods']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[4]/div/table/tbody/tr[2]/td[4]/div/input", "xpath:idRelative"], + ["xpath=//tr[2]/td[4]/div/input", "xpath:position"] + ], + "value": "test2" + }, { + "id": "18d127f8-a5b9-4634-bf44-d4432fe4122d", + "comment": "", + "command": "click", + "target": "css=tr:nth-child(2) .svg-inline--fa", + "targets": [ + ["css=tr:nth-child(2) .svg-inline--fa", "css:finder"] + ], + "value": "" + }, { + "id": "63f4e5a3-8846-4d80-8c42-3d1f5d8ec5c9", + "comment": "", + "command": "click", + "target": "css=.rbt-input-main", + "targets": [ + ["css=.rbt-input-main", "css:finder"], + ["xpath=//input[@value='']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/div/div/div/input", "xpath:idRelative"], + ["xpath=//div/div/div/div/input", "xpath:position"] + ], + "value": "" + }, { + "id": "420da5f7-5e5d-46c9-b58c-ff33e51bcd04", + "comment": "", + "command": "click", + "target": "id=property-selector-item-10", + "targets": [ + ["id=property-selector-item-10", "id"], + ["linkText=- idp.lockout.defaultAuthenticationMethods", "linkText"], + ["css=#property-selector-item-10", "css:finder"], + ["xpath=//a[contains(text(),'- idp.lockout.defaultAuthenticationMethods')]", "xpath:link"], + ["xpath=//a[@id='property-selector-item-10']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/a[8]", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[10]", "xpath:href"], + ["xpath=//a[8]", "xpath:position"], + ["xpath=//a[contains(.,'- idp.lockout.defaultAuthenticationMethods')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "f54f3946-a1f5-4392-99c0-0e1ce5958993", + "comment": "", + "command": "click", + "target": "css=.ms-2", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[9]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" + }, { + "id": "7206299c-901e-4273-86f2-7f14002ff78b", + "comment": "", + "command": "type", + "target": "id=valueInput-idp.lockout.defaultAuthenticationMethods", + "targets": [ + ["id=valueInput-idp.lockout.defaultAuthenticationMethods", "id"], + ["name=properties.1.propertyValue", "name"], + ["css=#valueInput-idp\\.lockout\\.defaultAuthenticationMethods", "css:finder"], + ["xpath=//input[@id='valueInput-idp.lockout.defaultAuthenticationMethods']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[4]/div/table/tbody/tr[2]/td[4]/div/input", "xpath:idRelative"], + ["xpath=//tr[2]/td[4]/div/input", "xpath:position"] + ], + "value": "test3" + }, { + "id": "23de6d39-9745-47a5-a3e1-84c0fb35d1e1", + "comment": "", + "command": "click", + "target": "css=.btn-info", + "targets": [ + ["css=.btn-info", "css:finder"], + ["xpath=(//button[@type='button'])[5]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,' Save')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "dfaa87c9-7a0b-445d-aa7a-942bc73d2f02", + "comment": "", + "command": "click", + "target": "linkText=Edit", + "targets": [ + ["linkText=Edit", "linkText"], + ["css=.btn-primary", "css:finder"], + ["xpath=//a[contains(text(),'Edit')]", "xpath:link"], + ["xpath=//div[@id='root']/div/main/div/section/div/div[2]/div[2]/table/tbody/tr/td[3]/div/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '/configurations/28/edit')])[2]", "xpath:href"], + ["xpath=//td[3]/div/a", "xpath:position"], + ["xpath=//a[contains(.,'  Edit')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "ed029697-17af-4ca6-9299-862ba5c43864", + "comment": "", + "command": "click", + "target": "css=.rbt-input-main", + "targets": [ + ["css=.rbt-input-main", "css:finder"], + ["xpath=//input[@value='']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/div/div/div/input", "xpath:idRelative"], + ["xpath=//div/div/div/div/input", "xpath:position"] + ], + "value": "" + }, { + "id": "9b66c662-75a5-4ad8-9e19-ebe65905a108", + "comment": "", + "command": "click", + "target": "id=property-selector-item-58", + "targets": [ + ["id=property-selector-item-58", "id"], + ["linkText=- idp.csrf.token.parameter", "linkText"], + ["css=#property-selector-item-58", "css:finder"], + ["xpath=//a[contains(text(),'- idp.csrf.token.parameter')]", "xpath:link"], + ["xpath=//a[@id='property-selector-item-58']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/a[51]", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[58]", "xpath:href"], + ["xpath=//a[51]", "xpath:position"], + ["xpath=//a[contains(.,'- idp.csrf.token.parameter')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "2c2ccf47-4386-4e3d-8a2b-0b3e183462a7", + "comment": "", + "command": "click", + "target": "css=.ms-2", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[9]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" + }, { + "id": "e5a94855-f4c7-404c-8fa6-06c19f0f16f6", + "comment": "", + "command": "type", + "target": "id=valueInput-idp.csrf.token.parameter", + "targets": [ + ["id=valueInput-idp.csrf.token.parameter", "id"], + ["name=properties.2.propertyValue", "name"], + ["css=#valueInput-idp\\.csrf\\.token\\.parameter", "css:finder"], + ["xpath=//input[@id='valueInput-idp.csrf.token.parameter']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[4]/div/table/tbody/tr[3]/td[4]/div/input", "xpath:idRelative"], + ["xpath=//tr[3]/td[4]/div/input", "xpath:position"] + ], + "value": "test4" + }, { + "id": "4e763745-940a-410b-9e49-89483a0927fd", + "comment": "", + "command": "click", + "target": "css=.btn-info", + "targets": [ + ["css=.btn-info", "css:finder"], + ["xpath=(//button[@type='button'])[5]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,' Save')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "137da111-edeb-4e27-a9f0-8b00d8f44e9f", + "comment": "", + "command": "click", + "target": "linkText=Create Shibboleth configuration set", + "targets": [ + ["linkText=Create Shibboleth configuration set", "linkText"], + ["css=.btn-success", "css:finder"], + ["xpath=//div[@id='root']/div/main/div/section/div/div[2]/div/a", "xpath:idRelative"], + ["xpath=//a[contains(@href, '/configurations/new')]", "xpath:href"], + ["xpath=//div[2]/div/a", "xpath:position"], + ["xpath=//a[contains(.,'  Create Shibboleth configuration set')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "3348ed8d-812e-46cc-bfb4-bc751893291a", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[7]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "a74652db-1910-473f-8f3a-7c955182895d", + "comment": "", + "command": "click", + "target": "id=property-selector-item-17", + "targets": [ + ["id=property-selector-item-17", "id"], + ["linkText=AttendedRestartConfiguration - Add all", "linkText"], + ["css=#property-selector-item-17", "css:finder"], + ["xpath=//a[@id='property-selector-item-17']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[6]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[17]", "xpath:href"], + ["xpath=//div[6]/a", "xpath:position"], + ["xpath=//a[contains(.,'AttendedRestartConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "a7279237-b6c7-47ca-a16b-145405569c44", + "comment": "", + "command": "type", + "target": "id=formName", + "targets": [ + ["id=formName", "id"], + ["name=name", "name"], + ["css=#formName", "css:finder"], + ["xpath=//input[@id='formName']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div/div/div/input", "xpath:idRelative"], + ["xpath=//input", "xpath:position"] + ], + "value": "Test Configuration 2" + }, { + "id": "eadfb399-b11f-46d1-a665-a526a53f90b0", + "comment": "", + "command": "click", + "target": "css=.ms-2", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[9]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" + }, { + "id": "309348c8-22c7-4ff6-90c2-43a0aa2c68cc", + "comment": "", + "command": "assertText", + "target": "css=tr:nth-child(7) > td:nth-child(1)", + "targets": [ + ["css=tr:nth-child(7) > td:nth-child(1)", "css:finder"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[4]/div/table/tbody/tr[7]/td", "xpath:idRelative"], + ["xpath=//tr[7]/td", "xpath:position"], + ["xpath=//td[contains(.,'idp.unlock-keys.authenticated')]", "xpath:innerText"] + ], + "value": "idp.unlock-keys.authenticated" + }, { + "id": "2be9a988-be21-4258-9c8f-21928e860a24", + "comment": "", + "command": "click", + "target": "css=.fa-floppy-disk > path", + "targets": [ + ["css=.fa-floppy-disk > path", "css:finder"] + ], + "value": "" + }, { + "id": "728c88fd-020a-49dc-a979-ba123f7ed53a", + "comment": "", + "command": "click", + "target": "css=tr:nth-child(1) .btn-danger", + "targets": [ + ["css=tr:nth-child(1) .btn-danger", "css:finder"], + ["xpath=(//button[@type='button'])[7]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div/div[2]/div[2]/table/tbody/tr/td[3]/div/button", "xpath:idRelative"], + ["xpath=//td[3]/div/button", "xpath:position"], + ["xpath=//button[contains(.,'  Delete')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "9c03d978-0d3b-4590-af7e-3b024c699e15", + "comment": "", + "command": "click", + "target": "css=.btn-danger:nth-child(1)", + "targets": [ + ["css=.btn-danger:nth-child(1)", "css:finder"], + ["xpath=(//button[@type='button'])[11]", "xpath:attributes"], + ["xpath=//div[4]/div/div/div[3]/button", "xpath:position"] + ], + "value": "" + }, { + "id": "a8a0060c-a5d9-4597-ba57-f390073fc98b", + "comment": "", + "command": "click", + "target": "css=.btn-danger", + "targets": [ + ["css=.btn-danger", "css:finder"], + ["xpath=(//button[@type='button'])[7]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div/div[2]/div[2]/table/tbody/tr/td[3]/div/button", "xpath:idRelative"], + ["xpath=//td[3]/div/button", "xpath:position"], + ["xpath=//button[contains(.,'  Delete')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "7dc604df-8358-43bb-9401-49717be23ac6", + "comment": "", + "command": "click", + "target": "css=.btn-danger:nth-child(1)", + "targets": [ + ["css=.btn-danger:nth-child(1)", "css:finder"], + ["xpath=(//button[@type='button'])[8]", "xpath:attributes"], + ["xpath=//div[4]/div/div/div[3]/button", "xpath:position"] + ], + "value": "" + }, { + "id": "e339a2e6-6e87-4a37-899c-8f7e9e309866", + "comment": "", + "command": "open", + "target": "/api/heheheheheheheWipeout", + "targets": [], + "value": "" + }, { + "id": "7e35b427-036a-49f6-a9f2-b31bc916490c", + "comment": "", + "command": "assertText", + "target": "css=body", + "targets": [], + "value": "yes, you did it" + }] + }], + "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 diff --git a/backend/src/integration/resources/SHIBUI-2270-2.side b/backend/src/integration/resources/SHIBUI-2270-2.side new file mode 100644 index 000000000..2872ad331 --- /dev/null +++ b/backend/src/integration/resources/SHIBUI-2270-2.side @@ -0,0 +1,2143 @@ +{ + "id": "1b31a551-eb09-4bd4-8db9-694bf1539a46", + "version": "2.0", + "name": "SHIBUI-2270-2", + "url": "http://localhost:10101", + "tests": [{ + "id": "841ade0e-83bd-4a4b-94f2-de6bd5c536b2", + "name": "SHIBUI-2270-2", + "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": "d388e4d3-79b7-4948-a6f6-907d0a46f35c", + "comment": "", + "command": "click", + "target": "id=advanced-nav-dropdown-toggle", + "targets": [ + ["id=advanced-nav-dropdown-toggle", "id"], + ["css=#advanced-nav-dropdown-toggle", "css:finder"], + ["xpath=//button[@id='advanced-nav-dropdown-toggle']", "xpath:attributes"], + ["xpath=//div[@id='advanced-nav-dropdown']/button", "xpath:idRelative"], + ["xpath=//div[3]/button", "xpath:position"], + ["xpath=//button[contains(.,'Advanced')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "14841cc4-c8f1-48c2-9f85-a7aaf9f0a91d", + "comment": "", + "command": "click", + "target": "id=advanced-nav-dropdown-properties", + "targets": [ + ["id=advanced-nav-dropdown-properties", "id"], + ["linkText=Shibboleth configurations", "linkText"], + ["css=#advanced-nav-dropdown-properties", "css:finder"], + ["xpath=//a[contains(text(),'Shibboleth configurations')]", "xpath:link"], + ["xpath=//a[@id='advanced-nav-dropdown-properties']", "xpath:attributes"], + ["xpath=//div[@id='advanced-nav-dropdown']/div/a[5]", "xpath:idRelative"], + ["xpath=//a[contains(@href, '/configurations')]", "xpath:href"], + ["xpath=//a[5]", "xpath:position"], + ["xpath=//a[contains(.,'Shibboleth configurations')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "8a824b21-89be-4531-baa3-db217375dfb1", + "comment": "", + "command": "click", + "target": "linkText=Create Shibboleth configuration set", + "targets": [ + ["linkText=Create Shibboleth configuration set", "linkText"], + ["css=.btn-success", "css:finder"], + ["xpath=//div[@id='root']/div/main/div/section/div/div[2]/div/a", "xpath:idRelative"], + ["xpath=//a[contains(@href, '/configurations/new')]", "xpath:href"], + ["xpath=//div[2]/div/a", "xpath:position"], + ["xpath=//a[contains(.,'  Create Shibboleth configuration set')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "da25d3be-ebb4-4ad7-8264-dfb688ef157d", + "comment": "", + "command": "type", + "target": "id=formName", + "targets": [ + ["id=formName", "id"], + ["name=name", "name"], + ["css=#formName", "css:finder"], + ["xpath=//input[@id='formName']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div/div/div/input", "xpath:idRelative"], + ["xpath=//input", "xpath:position"] + ], + "value": "Test Configuration" + }, { + "id": "3fae037d-0e59-4b9d-adf2-dbd624b72613", + "comment": "", + "command": "click", + "target": "css=.rbt-input-main", + "targets": [ + ["css=.rbt-input-main", "css:finder"], + ["xpath=//input[@value='']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/div/div/div/input", "xpath:idRelative"], + ["xpath=//div/div/div/div/input", "xpath:position"] + ], + "value": "" + }, { + "id": "2fe0a124-dfe0-4c40-a3b3-b1d8861505a8", + "comment": "", + "command": "click", + "target": "id=property-selector-item-1", + "targets": [ + ["id=property-selector-item-1", "id"], + ["linkText=AACLI - Add all", "linkText"], + ["css=#property-selector-item-1", "css:finder"], + ["xpath=//a[@id='property-selector-item-1']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[2]/a", "xpath:idRelative"], + ["xpath=//a[contains(@href, '#')]", "xpath:href"], + ["xpath=//div[2]/a", "xpath:position"], + ["xpath=//a[contains(.,'AACLI - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "be761931-fb77-4030-bc2c-2577d3a99580", + "comment": "", + "command": "click", + "target": "css=.rbt-input-main", + "targets": [ + ["css=.rbt-input-main", "css:finder"], + ["xpath=//input[@value='']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/div/div/div[2]/input", "xpath:idRelative"], + ["xpath=//div[2]/input", "xpath:position"] + ], + "value": "" + }, { + "id": "eb50041f-bf6e-4ef4-92ee-9319f79b8336", + "comment": "", + "command": "click", + "target": "id=property-selector-item-9", + "targets": [ + ["id=property-selector-item-9", "id"], + ["linkText=AccountLockoutManagement - Add all", "linkText"], + ["css=#property-selector-item-9", "css:finder"], + ["xpath=//a[@id='property-selector-item-9']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[4]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[9]", "xpath:href"], + ["xpath=//div[4]/a", "xpath:position"], + ["xpath=//a[contains(.,'AccountLockoutManagement - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "de63d0c0-9504-4339-b76f-ce21b7c9f5f8", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[9]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "9f0ee002-e494-4409-9461-35d70ec30bf3", + "comment": "", + "command": "click", + "target": "id=property-selector-item-17", + "targets": [ + ["id=property-selector-item-17", "id"], + ["linkText=AttendedRestartConfiguration - Add all", "linkText"], + ["css=#property-selector-item-17", "css:finder"], + ["xpath=//a[@id='property-selector-item-17']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[6]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[17]", "xpath:href"], + ["xpath=//div[6]/a", "xpath:position"], + ["xpath=//a[contains(.,'AttendedRestartConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "b1cb5ac9-027c-45f2-b7c2-d1a661378928", + "comment": "", + "command": "click", + "target": "css=.rbt-input-main", + "targets": [ + ["css=.rbt-input-main", "css:finder"], + ["xpath=//input[@value='']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/div/div/div[4]/input", "xpath:idRelative"], + ["xpath=//div[4]/input", "xpath:position"] + ], + "value": "" + }, { + "id": "53354967-a636-428a-8dea-c771e2ee3add", + "comment": "", + "command": "click", + "target": "id=property-selector-item-25", + "targets": [ + ["id=property-selector-item-25", "id"], + ["linkText=AttributePostLoginC14NConfiguration - Add all", "linkText"], + ["css=#property-selector-item-25", "css:finder"], + ["xpath=//a[@id='property-selector-item-25']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[8]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[25]", "xpath:href"], + ["xpath=//div[8]/a", "xpath:position"], + ["xpath=//a[contains(.,'AttributePostLoginC14NConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "ff91bfaf-f6ce-42c2-9dd4-1c52268d140d", + "comment": "", + "command": "click", + "target": "css=.fa-caret-down", + "targets": [ + ["css=.fa-caret-down", "css:finder"] + ], + "value": "" + }, { + "id": "825680dd-0180-4b92-a2df-40d041c24831", + "comment": "", + "command": "click", + "target": "id=property-selector-item-33", + "targets": [ + ["id=property-selector-item-33", "id"], + ["linkText=AuditLoggingConfiguration - Add all", "linkText"], + ["css=#property-selector-item-33", "css:finder"], + ["xpath=//a[@id='property-selector-item-33']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[10]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[33]", "xpath:href"], + ["xpath=//div[10]/a", "xpath:position"], + ["xpath=//a[contains(.,'AuditLoggingConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "1c671949-1992-4cbd-930c-0153e1fea983", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[12]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "7e6f1147-95fa-4f2e-b71c-bdc2265c8537", + "comment": "", + "command": "click", + "target": "id=property-selector-item-49", + "targets": [ + ["id=property-selector-item-49", "id"], + ["linkText=AuthenticationConfiguration - Add all", "linkText"], + ["css=#property-selector-item-49", "css:finder"], + ["xpath=//a[@id='property-selector-item-49']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[12]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[49]", "xpath:href"], + ["xpath=//div[12]/a", "xpath:position"], + ["xpath=//a[contains(.,'AuthenticationConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "384ea0fc-0bc1-4f63-b736-7e1d67277662", + "comment": "", + "command": "click", + "target": "css=.rbt-input-main", + "targets": [ + ["css=.rbt-input-main", "css:finder"], + ["xpath=//input[@value='']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/div/div/div[7]/input", "xpath:idRelative"], + ["xpath=//div[7]/input", "xpath:position"] + ], + "value": "" + }, { + "id": "2158cbdc-85be-4082-938c-00a14e0d6d63", + "comment": "", + "command": "click", + "target": "id=property-selector-item-59", + "targets": [ + ["id=property-selector-item-59", "id"], + ["linkText=CSRF - Add all", "linkText"], + ["css=#property-selector-item-59", "css:finder"], + ["xpath=//a[@id='property-selector-item-59']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[14]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[59]", "xpath:href"], + ["xpath=//div[14]/a", "xpath:position"], + ["xpath=//a[contains(.,'CSRF - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "a861c6d1-277e-438f-a49c-d47521f67dcc", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[14]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "f71b15c0-ff1b-4f26-8630-b755e1af00aa", + "comment": "", + "command": "click", + "target": "id=property-selector-item-62", + "targets": [ + ["id=property-selector-item-62", "id"], + ["linkText=CasProtocolConfiguration - Add all", "linkText"], + ["css=#property-selector-item-62", "css:finder"], + ["xpath=//a[@id='property-selector-item-62']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[16]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[62]", "xpath:href"], + ["xpath=//div[16]/a", "xpath:position"], + ["xpath=//a[contains(.,'CasProtocolConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "50f0c334-c0ca-43dc-8464-6d5d5b64de3e", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[15]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "ab25fbad-3959-4b65-ae5b-cd8cf81679d3", + "comment": "", + "command": "click", + "target": "id=property-selector-item-66", + "targets": [ + ["id=property-selector-item-66", "id"], + ["linkText=ConsentConfiguration - Add all", "linkText"], + ["css=#property-selector-item-66", "css:finder"], + ["xpath=//a[@id='property-selector-item-66']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[18]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[66]", "xpath:href"], + ["xpath=//div[18]/a", "xpath:position"], + ["xpath=//a[contains(.,'ConsentConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "5b5e0325-1735-4b9a-9920-5dac993cbb13", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[16]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "d06957b0-f5fa-4960-ac87-750566eb8484", + "comment": "", + "command": "click", + "target": "id=property-selector-item-84", + "targets": [ + ["id=property-selector-item-84", "id"], + ["linkText=Core - Add all", "linkText"], + ["css=#property-selector-item-84", "css:finder"], + ["xpath=//a[@id='property-selector-item-84']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[20]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[84]", "xpath:href"], + ["xpath=//div[20]/a", "xpath:position"], + ["xpath=//a[contains(.,'Core - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "cf7d85ba-7edc-4bf1-938a-a88fd04c7252", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[17]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "630e9dc2-89d6-435e-bd3d-040814109f16", + "comment": "", + "command": "click", + "target": "id=property-selector-item-100", + "targets": [ + ["id=property-selector-item-100", "id"], + ["linkText=DuoAuthnConfiguration - Add all", "linkText"], + ["css=#property-selector-item-100", "css:finder"], + ["xpath=//a[@id='property-selector-item-100']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[22]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[100]", "xpath:href"], + ["xpath=//div[22]/a", "xpath:position"], + ["xpath=//a[contains(.,'DuoAuthnConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "9f2f0c50-7465-4879-bb68-822bca1f0fa3", + "comment": "", + "command": "click", + "target": "css=.rbt-input-main", + "targets": [ + ["css=.rbt-input-main", "css:finder"], + ["xpath=//input[@value='']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/div/div/div[12]/input", "xpath:idRelative"], + ["xpath=//div[12]/input", "xpath:position"] + ], + "value": "" + }, { + "id": "6f28c9cc-1006-456b-ae72-b70006636829", + "comment": "", + "command": "click", + "target": "id=property-selector-item-127", + "targets": [ + ["id=property-selector-item-127", "id"], + ["linkText=DuoOIDCAuthnConfiguration - Add all", "linkText"], + ["css=#property-selector-item-127", "css:finder"], + ["xpath=//a[@id='property-selector-item-127']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[24]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[127]", "xpath:href"], + ["xpath=//div[24]/a", "xpath:position"], + ["xpath=//a[contains(.,'DuoOIDCAuthnConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "3b326c6f-96d3-4f6c-ba82-e9ffd95517f1", + "comment": "", + "command": "click", + "target": "css=.fa-caret-down", + "targets": [ + ["css=.fa-caret-down", "css:finder"] + ], + "value": "" + }, { + "id": "ec3ac03f-c46b-4e1c-a89d-e2dc9826ca98", + "comment": "", + "command": "click", + "target": "id=property-selector-item-169", + "targets": [ + ["id=property-selector-item-169", "id"], + ["linkText=ErrorHandlingConfiguration - Add all", "linkText"], + ["css=#property-selector-item-169", "css:finder"], + ["xpath=//a[@id='property-selector-item-169']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[26]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[169]", "xpath:href"], + ["xpath=//div[26]/a", "xpath:position"], + ["xpath=//a[contains(.,'ErrorHandlingConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "ce43ffb1-3979-4381-a155-9a2a59d1ac95", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[20]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "62d42fb7-00e2-400d-a1be-adcbf826ce3a", + "comment": "", + "command": "click", + "target": "id=property-selector-item-175", + "targets": [ + ["id=property-selector-item-175", "id"], + ["linkText=ExternalAuthnConfiguration - Add all", "linkText"], + ["css=#property-selector-item-175", "css:finder"], + ["xpath=//a[@id='property-selector-item-175']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[28]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[175]", "xpath:href"], + ["xpath=//div[28]/a", "xpath:position"], + ["xpath=//a[contains(.,'ExternalAuthnConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "b1c01f80-778c-4ea3-b952-dd84c18e5904", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[21]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "8a3757ee-2564-436e-abc5-e0584a59a82e", + "comment": "", + "command": "click", + "target": "id=property-selector-item-192", + "targets": [ + ["id=property-selector-item-192", "id"], + ["linkText=FTICKSLoggingConfiguration - Add all", "linkText"], + ["css=#property-selector-item-192", "css:finder"], + ["xpath=//a[@id='property-selector-item-192']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[30]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[192]", "xpath:href"], + ["xpath=//div[30]/a", "xpath:position"], + ["xpath=//a[contains(.,'FTICKSLoggingConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "c6bfe838-9027-4c25-990e-e451e9d04a4d", + "comment": "", + "command": "click", + "target": "css=.fa-caret-down", + "targets": [ + ["css=.fa-caret-down", "css:finder"] + ], + "value": "" + }, { + "id": "0c462504-cb92-421d-aeb0-8afecac90aec", + "comment": "", + "command": "click", + "target": "id=property-selector-item-199", + "targets": [ + ["id=property-selector-item-199", "id"], + ["linkText=FunctionAuthnConfiguration - Add all", "linkText"], + ["css=#property-selector-item-199", "css:finder"], + ["xpath=//a[@id='property-selector-item-199']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[32]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[199]", "xpath:href"], + ["xpath=//div[32]/a", "xpath:position"], + ["xpath=//a[contains(.,'FunctionAuthnConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "892d14a0-9ab0-4c05-945b-bd96d461eba8", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[23]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "9a809145-1f01-4a6b-8eaf-836f91a9bd5a", + "comment": "", + "command": "click", + "target": "id=property-selector-item-214", + "targets": [ + ["id=property-selector-item-214", "id"], + ["linkText=HelloWorldConfiguration - Add all", "linkText"], + ["css=#property-selector-item-214", "css:finder"], + ["xpath=//a[@id='property-selector-item-214']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[34]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[214]", "xpath:href"], + ["xpath=//div[34]/a", "xpath:position"], + ["xpath=//a[contains(.,'HelloWorldConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "8e3dc610-99f9-4a85-a0c0-cd572ccf0a84", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[24]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "fa182a6d-bba7-4f50-a6d8-a5391b592004", + "comment": "", + "command": "click", + "target": "id=property-selector-item-222", + "targets": [ + ["id=property-selector-item-222", "id"], + ["linkText=IPAddressAuthnConfiguration - Add all", "linkText"], + ["css=#property-selector-item-222", "css:finder"], + ["xpath=//a[@id='property-selector-item-222']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[36]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[222]", "xpath:href"], + ["xpath=//div[36]/a", "xpath:position"], + ["xpath=//a[contains(.,'IPAddressAuthnConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "17e45a4b-9d00-478f-9add-c1a7138a7959", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[25]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "2a3578cb-56d5-4805-8e82-2058e17c3ad5", + "comment": "", + "command": "click", + "target": "id=property-selector-item-237", + "targets": [ + ["id=property-selector-item-237", "id"], + ["linkText=JAASAuthnConfiguration - Add all", "linkText"], + ["css=#property-selector-item-237", "css:finder"], + ["xpath=//a[@id='property-selector-item-237']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[38]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[237]", "xpath:href"], + ["xpath=//div[38]/a", "xpath:position"], + ["xpath=//a[contains(.,'JAASAuthnConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "3aedee37-3445-4679-afe8-62e53b348e52", + "comment": "", + "command": "click", + "target": "css=.fa-caret-down > path", + "targets": [ + ["css=.fa-caret-down > path", "css:finder"] + ], + "value": "" + }, { + "id": "fce00a94-ffe3-4771-b33d-e6c8cde6c690", + "comment": "", + "command": "click", + "target": "id=property-selector-item-240", + "targets": [ + ["id=property-selector-item-240", "id"], + ["linkText=KerberosAuthnConfiguration - Add all", "linkText"], + ["css=#property-selector-item-240", "css:finder"], + ["xpath=//a[@id='property-selector-item-240']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[40]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[240]", "xpath:href"], + ["xpath=//div[40]/a", "xpath:position"], + ["xpath=//a[contains(.,'KerberosAuthnConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "37642e97-2b2a-4cfd-9b71-d150c13b1b2d", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[27]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "fdae4c41-909b-44b1-b245-469c430a09a0", + "comment": "", + "command": "click", + "target": "id=property-selector-item-245", + "targets": [ + ["id=property-selector-item-245", "id"], + ["linkText=LDAPAuthnConfiguration - Add all", "linkText"], + ["css=#property-selector-item-245", "css:finder"], + ["xpath=//a[@id='property-selector-item-245']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[42]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[245]", "xpath:href"], + ["xpath=//div[42]/a", "xpath:position"], + ["xpath=//a[contains(.,'LDAPAuthnConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "f34f0217-ff82-441b-a73b-b25f791bc546", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[28]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "d30d9da8-65e0-41a1-b27f-c4cc998c97fd", + "comment": "", + "command": "click", + "target": "id=property-selector-item-281", + "targets": [ + ["id=property-selector-item-281", "id"], + ["linkText=LogoutConfiguration - Add all", "linkText"], + ["css=#property-selector-item-281", "css:finder"], + ["xpath=//a[@id='property-selector-item-281']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[44]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[281]", "xpath:href"], + ["xpath=//div[44]/a", "xpath:position"], + ["xpath=//a[contains(.,'LogoutConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "cb442dbe-c609-4b8b-ac55-2d32362be80b", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[29]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "19b1de66-7601-4e41-a345-657c5417f23f", + "comment": "", + "command": "click", + "target": "id=property-selector-item-288", + "targets": [ + ["id=property-selector-item-288", "id"], + ["linkText=MetadataQuery - Add all", "linkText"], + ["css=#property-selector-item-288", "css:finder"], + ["xpath=//a[@id='property-selector-item-288']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[46]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[288]", "xpath:href"], + ["xpath=//div[46]/a", "xpath:position"], + ["xpath=//a[contains(.,'MetadataQuery - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "513c8bd3-cbb4-443f-9a90-8a2ae9d5c0ce", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[30]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "515cc435-61ee-430a-8cdc-ac41e3926fbc", + "comment": "", + "command": "click", + "target": "id=property-selector-item-296", + "targets": [ + ["id=property-selector-item-296", "id"], + ["linkText=MetadataReload - Add all", "linkText"], + ["css=#property-selector-item-296", "css:finder"], + ["xpath=//a[@id='property-selector-item-296']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[48]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[296]", "xpath:href"], + ["xpath=//div[48]/a", "xpath:position"], + ["xpath=//a[contains(.,'MetadataReload - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "6d5dcd3a-0d08-4140-9634-196e2e2fdb90", + "comment": "", + "command": "click", + "target": "css=.fa-caret-down", + "targets": [ + ["css=.fa-caret-down", "css:finder"] + ], + "value": "" + }, { + "id": "2b2a05d9-4e8b-45cf-882f-08328cb0b6e5", + "comment": "", + "command": "click", + "target": "id=property-selector-item-304", + "targets": [ + ["id=property-selector-item-304", "id"], + ["linkText=Metadatagen - Add all", "linkText"], + ["css=#property-selector-item-304", "css:finder"], + ["xpath=//a[@id='property-selector-item-304']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[50]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[304]", "xpath:href"], + ["xpath=//div[50]/a", "xpath:position"], + ["xpath=//a[contains(.,'Metadatagen - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "f1709162-b102-48da-81b0-5862158fd74d", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[32]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "643c1db8-10f8-4146-94fb-bf920b007c00", + "comment": "", + "command": "click", + "target": "id=property-selector-item-313", + "targets": [ + ["id=property-selector-item-313", "id"], + ["linkText=MetricsConfiguration - Add all", "linkText"], + ["css=#property-selector-item-313", "css:finder"], + ["xpath=//a[@id='property-selector-item-313']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[52]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[313]", "xpath:href"], + ["xpath=//div[52]/a", "xpath:position"], + ["xpath=//a[contains(.,'MetricsConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "206468ff-7786-4e32-96dd-4c0e9a2194b7", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[33]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "00f2e151-13aa-4ac0-bb0c-d7e531f422a5", + "comment": "", + "command": "click", + "target": "id=property-selector-item-320", + "targets": [ + ["id=property-selector-item-320", "id"], + ["linkText=Misc - Add all", "linkText"], + ["css=#property-selector-item-320", "css:finder"], + ["xpath=//a[@id='property-selector-item-320']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[54]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[320]", "xpath:href"], + ["xpath=//div[54]/a", "xpath:position"], + ["xpath=//a[contains(.,'Misc - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "c06b4caf-e093-49b4-8cac-f71bda476995", + "comment": "", + "command": "click", + "target": "css=.fa-caret-down", + "targets": [ + ["css=.fa-caret-down", "css:finder"] + ], + "value": "" + }, { + "id": "031e88e8-bde7-4d25-8aab-919bc8882901", + "comment": "", + "command": "click", + "target": "id=property-selector-item-326", + "targets": [ + ["id=property-selector-item-326", "id"], + ["linkText=MultiFactorAuthnConfiguration - Add all", "linkText"], + ["css=#property-selector-item-326", "css:finder"], + ["xpath=//a[@id='property-selector-item-326']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[56]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[326]", "xpath:href"], + ["xpath=//div[56]/a", "xpath:position"], + ["xpath=//a[contains(.,'MultiFactorAuthnConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "7ab63a23-e0ab-4a07-8ef8-9fdb6af9f59b", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[35]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "34cbdae8-4b4c-4faa-a38c-f3a9c5475e45", + "comment": "", + "command": "click", + "target": "id=property-selector-item-342", + "targets": [ + ["id=property-selector-item-342", "id"], + ["linkText=NameIDConsumptionConfiguration - Add all", "linkText"], + ["css=#property-selector-item-342", "css:finder"], + ["xpath=//a[@id='property-selector-item-342']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[58]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[342]", "xpath:href"], + ["xpath=//div[58]/a", "xpath:position"], + ["xpath=//a[contains(.,'NameIDConsumptionConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "15c61405-c967-475f-b494-6bdb461b5283", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[36]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "6e13ab35-510b-4e7b-976c-457d59f65606", + "comment": "", + "command": "click", + "target": "id=property-selector-item-345", + "targets": [ + ["id=property-selector-item-345", "id"], + ["linkText=NameIDGenerationConfiguration - Add all", "linkText"], + ["css=#property-selector-item-345", "css:finder"], + ["xpath=//a[@id='property-selector-item-345']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[60]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[345]", "xpath:href"], + ["xpath=//div[60]/a", "xpath:position"], + ["xpath=//a[contains(.,'NameIDGenerationConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "74505e9c-1a4b-441d-9e21-fce8077576b4", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[37]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "ec03564e-9ff9-4c53-914e-e33e8efec3b8", + "comment": "", + "command": "click", + "target": "id=property-selector-item-349", + "targets": [ + ["id=property-selector-item-349", "id"], + ["linkText=OAuth2ClientAuthnConfiguration - Add all", "linkText"], + ["css=#property-selector-item-349", "css:finder"], + ["xpath=//a[@id='property-selector-item-349']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[62]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[349]", "xpath:href"], + ["xpath=//div[62]/a", "xpath:position"], + ["xpath=//a[contains(.,'OAuth2ClientAuthnConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "9bc758f1-8c06-429e-abf4-78fadd181d56", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[38]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "a81e8d28-41b8-47d1-901b-6d36fb90398d", + "comment": "", + "command": "click", + "target": "id=property-selector-item-358", + "targets": [ + ["id=property-selector-item-358", "id"], + ["linkText=OIDC OP - Add all", "linkText"], + ["css=#property-selector-item-358", "css:finder"], + ["xpath=//a[@id='property-selector-item-358']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[64]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[358]", "xpath:href"], + ["xpath=//div[64]/a", "xpath:position"], + ["xpath=//a[contains(.,'OIDC OP - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "5e1646f3-7841-4b97-96c9-639c6f7ef3ca", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[39]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "f3865e29-6b36-49ab-99a4-44370b5ed974", + "comment": "", + "command": "click", + "target": "id=property-selector-item-371", + "targets": [ + ["id=property-selector-item-371", "id"], + ["linkText=OPAuthorization - Add all", "linkText"], + ["css=#property-selector-item-371", "css:finder"], + ["xpath=//a[@id='property-selector-item-371']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[66]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[371]", "xpath:href"], + ["xpath=//div[66]/a", "xpath:position"], + ["xpath=//a[contains(.,'OPAuthorization - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "821c3a6d-b9a6-45bf-bda3-46c2f1e87303", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[40]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "72620249-22a8-436b-b506-670fad77fefa", + "comment": "", + "command": "click", + "target": "id=property-selector-item-378", + "targets": [ + ["id=property-selector-item-378", "id"], + ["linkText=OPClientAuthentication - Add all", "linkText"], + ["css=#property-selector-item-378", "css:finder"], + ["xpath=//a[@id='property-selector-item-378']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[68]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[378]", "xpath:href"], + ["xpath=//div[68]/a", "xpath:position"], + ["xpath=//a[contains(.,'OPClientAuthentication - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "e8d736c8-be22-4411-87d4-0a1eefcc821e", + "comment": "", + "command": "click", + "target": "css=.fa-caret-down", + "targets": [ + ["css=.fa-caret-down", "css:finder"] + ], + "value": "" + }, { + "id": "d8ef3cf9-1398-4bcd-b976-92a2a471ce1c", + "comment": "", + "command": "click", + "target": "id=property-selector-item-380", + "targets": [ + ["id=property-selector-item-380", "id"], + ["linkText=OPClientCredentialsGrant - Add all", "linkText"], + ["css=#property-selector-item-380", "css:finder"], + ["xpath=//a[@id='property-selector-item-380']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[70]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[380]", "xpath:href"], + ["xpath=//div[70]/a", "xpath:position"], + ["xpath=//a[contains(.,'OPClientCredentialsGrant - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "ed236cf8-e185-4b41-a47f-2a9219eab773", + "comment": "", + "command": "click", + "target": "css=.fa-caret-down", + "targets": [ + ["css=.fa-caret-down", "css:finder"] + ], + "value": "" + }, { + "id": "d4965727-9cc9-465a-9d4d-9e3a16c9507a", + "comment": "", + "command": "click", + "target": "id=property-selector-item-383", + "targets": [ + ["id=property-selector-item-383", "id"], + ["linkText=OPClientResolution - Add all", "linkText"], + ["css=#property-selector-item-383", "css:finder"], + ["xpath=//a[@id='property-selector-item-383']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[72]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[383]", "xpath:href"], + ["xpath=//div[72]/a", "xpath:position"], + ["xpath=//a[contains(.,'OPClientResolution - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "899a5897-0786-4f40-8d1f-2c3cc64f4666", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[43]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "a08f536a-166d-45e0-a477-b7aece98a6bc", + "comment": "", + "command": "click", + "target": "id=property-selector-item-387", + "targets": [ + ["id=property-selector-item-387", "id"], + ["linkText=OPCustomFilterRegistration - Add all", "linkText"], + ["css=#property-selector-item-387", "css:finder"], + ["xpath=//a[@id='property-selector-item-387']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[74]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[387]", "xpath:href"], + ["xpath=//div[74]/a", "xpath:position"], + ["xpath=//a[contains(.,'OPCustomFilterRegistration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "90ec186d-d13c-49a1-9912-744f62873feb", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[44]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "185cd9b2-0f1b-4f64-a4a5-b62f5a881d45", + "comment": "", + "command": "click", + "target": "css=.p-3", + "targets": [ + ["css=.p-3", "css:finder"], + ["xpath=//div[@id='root']/div/main/div", "xpath:idRelative"], + ["xpath=//main/div", "xpath:position"] + ], + "value": "" + }, { + "id": "2a295dc3-422a-436e-8450-03dbcc88a1b0", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[44]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "6fdf6ef4-52e8-44a9-8dc5-8126e2ba11b0", + "comment": "", + "command": "click", + "target": "id=property-selector-item-389", + "targets": [ + ["id=property-selector-item-389", "id"], + ["linkText=OPDiscovery - Add all", "linkText"], + ["css=#property-selector-item-389", "css:finder"], + ["xpath=//a[@id='property-selector-item-389']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[76]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[389]", "xpath:href"], + ["xpath=//div[76]/a", "xpath:position"], + ["xpath=//a[contains(.,'OPDiscovery - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "614f715d-8fcc-4e84-8d0d-dd947fc7c99f", + "comment": "", + "command": "click", + "target": "css=.fa-caret-down", + "targets": [ + ["css=.fa-caret-down", "css:finder"] + ], + "value": "" + }, { + "id": "a3bbcc78-ce50-4b17-9419-f228664dc9fc", + "comment": "", + "command": "click", + "target": "id=property-selector-item-392", + "targets": [ + ["id=property-selector-item-392", "id"], + ["linkText=OPDynamicClientRegistration - Add all", "linkText"], + ["css=#property-selector-item-392", "css:finder"], + ["xpath=//a[@id='property-selector-item-392']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[78]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[392]", "xpath:href"], + ["xpath=//div[78]/a", "xpath:position"], + ["xpath=//a[contains(.,'OPDynamicClientRegistration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "ec8f2a2b-b45d-4345-af4b-dd5965f9dc54", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[46]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "ba6779d8-9a40-4981-a41f-c8c22df7027a", + "comment": "", + "command": "click", + "target": "id=property-selector-item-407", + "targets": [ + ["id=property-selector-item-407", "id"], + ["linkText=OPMetadataPolicies - Add all", "linkText"], + ["css=#property-selector-item-407", "css:finder"], + ["xpath=//a[@id='property-selector-item-407']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[80]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[407]", "xpath:href"], + ["xpath=//div[80]/a", "xpath:position"], + ["xpath=//a[contains(.,'OPMetadataPolicies - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "b93aed8b-bd95-496a-ad07-b9bfe23f8522", + "comment": "", + "command": "click", + "target": "css=.fa-caret-down > path", + "targets": [ + ["css=.fa-caret-down > path", "css:finder"] + ], + "value": "" + }, { + "id": "57fc676c-34fc-4220-915e-be3c30821030", + "comment": "", + "command": "click", + "target": "id=property-selector-item-409", + "targets": [ + ["id=property-selector-item-409", "id"], + ["linkText=OPRevocation - Add all", "linkText"], + ["css=#property-selector-item-409", "css:finder"], + ["xpath=//a[@id='property-selector-item-409']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[82]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[409]", "xpath:href"], + ["xpath=//div[82]/a", "xpath:position"], + ["xpath=//a[contains(.,'OPRevocation - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "85efb0c2-9a2b-4816-b77d-4c84816f3499", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[48]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "0c424441-f80c-4f42-9a4a-2df0be1ad937", + "comment": "", + "command": "click", + "target": "id=property-selector-item-412", + "targets": [ + ["id=property-selector-item-412", "id"], + ["linkText=OPSecurity - Add all", "linkText"], + ["css=#property-selector-item-412", "css:finder"], + ["xpath=//a[@id='property-selector-item-412']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[84]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[412]", "xpath:href"], + ["xpath=//div[84]/a", "xpath:position"], + ["xpath=//a[contains(.,'OPSecurity - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "686dc5ad-4686-4364-865e-e8c95210f7e3", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[49]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "da318a35-6cdf-4346-b357-3aadeaf46640", + "comment": "", + "command": "click", + "target": "id=property-selector-item-420", + "targets": [ + ["id=property-selector-item-420", "id"], + ["linkText=OPSubClaim - Add all", "linkText"], + ["css=#property-selector-item-420", "css:finder"], + ["xpath=//a[@id='property-selector-item-420']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[86]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[420]", "xpath:href"], + ["xpath=//div[86]/a", "xpath:position"], + ["xpath=//a[contains(.,'OPSubClaim - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "5f8f249d-2052-4b6f-be83-9cdde0f5a06d", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[50]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "f36fb2c2-bf28-4fb0-8a6e-083b8a7d854e", + "comment": "", + "command": "click", + "target": "id=property-selector-item-424", + "targets": [ + ["id=property-selector-item-424", "id"], + ["linkText=OPToken - Add all", "linkText"], + ["css=#property-selector-item-424", "css:finder"], + ["xpath=//a[@id='property-selector-item-424']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[88]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[424]", "xpath:href"], + ["xpath=//div[88]/a", "xpath:position"], + ["xpath=//a[contains(.,'OPToken - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "5e7fc6cc-c7e3-4d4b-b682-ec939c8a5db1", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[51]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "24fa8f94-9a62-4e11-9125-a6c576695e77", + "comment": "", + "command": "click", + "target": "id=property-selector-item-436", + "targets": [ + ["id=property-selector-item-436", "id"], + ["linkText=PersistentNameIDGenerationConfiguration - Add all", "linkText"], + ["css=#property-selector-item-436", "css:finder"], + ["xpath=//a[@id='property-selector-item-436']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[90]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[436]", "xpath:href"], + ["xpath=//div[90]/a", "xpath:position"], + ["xpath=//a[contains(.,'PersistentNameIDGenerationConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "f7c7f42d-b4cb-4f92-997f-d9677a00758f", + "comment": "", + "command": "click", + "target": "css=.fa-caret-down", + "targets": [ + ["css=.fa-caret-down", "css:finder"] + ], + "value": "" + }, { + "id": "7bfdfde0-3399-4161-9cbc-e67f10ae44b5", + "comment": "", + "command": "click", + "target": "id=property-selector-item-460", + "targets": [ + ["id=property-selector-item-460", "id"], + ["linkText=ReloadableServices - Add all", "linkText"], + ["css=#property-selector-item-460", "css:finder"], + ["xpath=//a[@id='property-selector-item-460']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[92]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[460]", "xpath:href"], + ["xpath=//div[92]/a", "xpath:position"], + ["xpath=//a[contains(.,'ReloadableServices - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "5a3ad5c4-37e2-4060-88bd-ed96b94d037e", + "comment": "", + "command": "click", + "target": "css=.fa-caret-down", + "targets": [ + ["css=.fa-caret-down", "css:finder"] + ], + "value": "" + }, { + "id": "db192d5c-0857-4059-869d-d1ff40fd8844", + "comment": "", + "command": "click", + "target": "id=property-selector-item-501", + "targets": [ + ["id=property-selector-item-501", "id"], + ["linkText=RelyingPartyConfiguration - Add all", "linkText"], + ["css=#property-selector-item-501", "css:finder"], + ["xpath=//a[@id='property-selector-item-501']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[94]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[501]", "xpath:href"], + ["xpath=//div[94]/a", "xpath:position"], + ["xpath=//a[contains(.,'RelyingPartyConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "46e1fd14-ca91-4f92-a919-695dcff58622", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[54]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "bf5ba1a6-ba55-4397-91fa-7f1c1cd28e0d", + "comment": "", + "command": "click", + "target": "id=property-selector-item-507", + "targets": [ + ["id=property-selector-item-507", "id"], + ["linkText=RemoteUserAuthnConfiguration - Add all", "linkText"], + ["css=#property-selector-item-507", "css:finder"], + ["xpath=//a[@id='property-selector-item-507']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[96]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[507]", "xpath:href"], + ["xpath=//div[96]/a", "xpath:position"], + ["xpath=//a[contains(.,'RemoteUserAuthnConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "fde12162-843c-4425-bc3e-f404f52cd232", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.fa-caret-down", "css:finder"] + ], + "value": "" + }, { + "id": "e1313d05-d1ff-4196-8ae7-eb04c1088afd", + "comment": "", + "command": "click", + "target": "id=property-selector-item-524", + "targets": [ + ["id=property-selector-item-524", "id"], + ["linkText=RemoteUserInternalAuthnConfiguration - Add all", "linkText"], + ["css=#property-selector-item-524", "css:finder"], + ["xpath=//a[@id='property-selector-item-524']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[98]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[524]", "xpath:href"], + ["xpath=//div[98]/a", "xpath:position"], + ["xpath=//a[contains(.,'RemoteUserInternalAuthnConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "1b2b7432-6d03-4b84-922c-59b9cee6ccc5", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[56]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "31fff123-cc89-4473-9943-a7b5d1206de7", + "comment": "", + "command": "click", + "target": "id=property-selector-item-549", + "targets": [ + ["id=property-selector-item-549", "id"], + ["linkText=SAML2ProxyTransformPostLoginC14NConfiguration - Add all", "linkText"], + ["css=#property-selector-item-549", "css:finder"], + ["xpath=//a[@id='property-selector-item-549']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[100]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[549]", "xpath:href"], + ["xpath=//div[100]/a", "xpath:position"], + ["xpath=//a[contains(.,'SAML2ProxyTransformPostLoginC14NConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "10926b24-5952-4685-be81-802f5fc7ca4a", + "comment": "", + "command": "click", + "target": "css=.fa-caret-down", + "targets": [ + ["css=.fa-caret-down", "css:finder"] + ], + "value": "" + }, { + "id": "746398e5-d85c-412c-8a64-45c6d2a669ee", + "comment": "", + "command": "click", + "target": "id=property-selector-item-552", + "targets": [ + ["id=property-selector-item-552", "id"], + ["linkText=SAMLAuthnConfiguration - Add all", "linkText"], + ["css=#property-selector-item-552", "css:finder"], + ["xpath=//a[@id='property-selector-item-552']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[102]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[552]", "xpath:href"], + ["xpath=//div[102]/a", "xpath:position"], + ["xpath=//a[contains(.,'SAMLAuthnConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "5558c433-213a-49de-b68d-e6d9ac396b86", + "comment": "", + "command": "click", + "target": "css=.fa-caret-down", + "targets": [ + ["css=.fa-caret-down", "css:finder"] + ], + "value": "" + }, { + "id": "a85d9957-d3f3-4304-bd85-dd25ae70592b", + "comment": "", + "command": "click", + "target": "id=property-selector-item-572", + "targets": [ + ["id=property-selector-item-572", "id"], + ["linkText=SPNEGOAuthnConfiguration - Add all", "linkText"], + ["css=#property-selector-item-572", "css:finder"], + ["xpath=//a[@id='property-selector-item-572']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[104]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[572]", "xpath:href"], + ["xpath=//div[104]/a", "xpath:position"], + ["xpath=//a[contains(.,'SPNEGOAuthnConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "62dcb81a-9265-4f8f-ac8e-6ae7027a3601", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[59]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "18da3cfc-943f-43e5-ab16-6a9070336d5c", + "comment": "", + "command": "click", + "target": "id=property-selector-item-592", + "targets": [ + ["id=property-selector-item-592", "id"], + ["linkText=SecurityConfiguration - Add all", "linkText"], + ["css=#property-selector-item-592", "css:finder"], + ["xpath=//a[@id='property-selector-item-592']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[106]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[592]", "xpath:href"], + ["xpath=//div[106]/a", "xpath:position"], + ["xpath=//a[contains(.,'SecurityConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "894853a1-2202-4ff4-bc06-f0f7faf32505", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[60]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "12440bab-1419-4d7d-948c-71811b067df2", + "comment": "", + "command": "click", + "target": "id=property-selector-item-626", + "targets": [ + ["id=property-selector-item-626", "id"], + ["linkText=SessionConfiguration - Add all", "linkText"], + ["css=#property-selector-item-626", "css:finder"], + ["xpath=//a[@id='property-selector-item-626']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[108]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[626]", "xpath:href"], + ["xpath=//div[108]/a", "xpath:position"], + ["xpath=//a[contains(.,'SessionConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "5bf0b70b-e413-49eb-bfcb-f97a4265c70b", + "comment": "", + "command": "click", + "target": "css=.fa-caret-down > path", + "targets": [ + ["css=.fa-caret-down > path", "css:finder"] + ], + "value": "" + }, { + "id": "eb83e85f-6924-44ac-9922-9c5a1fcbcbc5", + "comment": "", + "command": "click", + "target": "id=property-selector-item-639", + "targets": [ + ["id=property-selector-item-639", "id"], + ["linkText=SimplePostLoginC14NConfiguration - Add all", "linkText"], + ["css=#property-selector-item-639", "css:finder"], + ["xpath=//a[@id='property-selector-item-639']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[110]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[639]", "xpath:href"], + ["xpath=//div[110]/a", "xpath:position"], + ["xpath=//a[contains(.,'SimplePostLoginC14NConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "d941d154-a6a3-4684-ad04-ca9d45acf2aa", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[62]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "cd98777e-1800-417f-af35-9f6d531decfa", + "comment": "", + "command": "click", + "target": "css=form", + "targets": [ + ["css=form", "css:finder"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form", "xpath:idRelative"], + ["xpath=//form", "xpath:position"] + ], + "value": "" + }, { + "id": "2ac41455-f406-4e71-88c0-8c30b7c23eab", + "comment": "", + "command": "click", + "target": "css=.fa-caret-down", + "targets": [ + ["css=.fa-caret-down", "css:finder"] + ], + "value": "" + }, { + "id": "a729126e-0c39-4db6-882c-b506db087119", + "comment": "", + "command": "click", + "target": "id=property-selector-item-643", + "targets": [ + ["id=property-selector-item-643", "id"], + ["linkText=Status - Add all", "linkText"], + ["css=#property-selector-item-643", "css:finder"], + ["xpath=//a[@id='property-selector-item-643']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[112]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[643]", "xpath:href"], + ["xpath=//div[112]/a", "xpath:position"], + ["xpath=//a[contains(.,'Status - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "602156fa-9fed-4a42-9182-4aa66338dd24", + "comment": "", + "command": "click", + "target": "css=td", + "targets": [ + ["css=td", "css:finder"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[4]/div/table/tbody/tr/td", "xpath:idRelative"], + ["xpath=//td", "xpath:position"], + ["xpath=//td[contains(.,'At least one property is required.')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "878447bd-6424-440f-8dcf-461f994a6478", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[63]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "3b964802-50ee-4a2a-8db6-d24a51a61483", + "comment": "", + "command": "click", + "target": "id=property-selector-item-651", + "targets": [ + ["id=property-selector-item-651", "id"], + ["linkText=StorageConfiguration - Add all", "linkText"], + ["css=#property-selector-item-651", "css:finder"], + ["xpath=//a[@id='property-selector-item-651']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[114]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[651]", "xpath:href"], + ["xpath=//div[114]/a", "xpath:position"], + ["xpath=//a[contains(.,'StorageConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "eca7bf2d-db81-4cad-873b-eba9440bd0e5", + "comment": "", + "command": "click", + "target": "css=.fa-caret-down", + "targets": [ + ["css=.fa-caret-down", "css:finder"] + ], + "value": "" + }, { + "id": "40ca1af5-e808-4b69-a5dd-3b545c1b233d", + "comment": "", + "command": "click", + "target": "id=property-selector-item-659", + "targets": [ + ["id=property-selector-item-659", "id"], + ["linkText=TOTP - Add all", "linkText"], + ["css=#property-selector-item-659", "css:finder"], + ["xpath=//a[@id='property-selector-item-659']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[116]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[659]", "xpath:href"], + ["xpath=//div[116]/a", "xpath:position"], + ["xpath=//a[contains(.,'TOTP - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "d6e986cb-865d-4472-b791-ea9ba459a849", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[65]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "26be9d61-f3c2-482e-8d0d-759a00c9b28f", + "comment": "", + "command": "click", + "target": "id=property-selector-item-677", + "targets": [ + ["id=property-selector-item-677", "id"], + ["linkText=X500PostLoginC14NConfiguration - Add all", "linkText"], + ["css=#property-selector-item-677", "css:finder"], + ["xpath=//a[@id='property-selector-item-677']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[118]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[677]", "xpath:href"], + ["xpath=//div[118]/a", "xpath:position"], + ["xpath=//a[contains(.,'X500PostLoginC14NConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "966c35be-39a4-4fa9-aded-8ba6fa1394a2", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[66]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "5124a661-4c33-4468-9c08-505268f78ff0", + "comment": "", + "command": "click", + "target": "id=property-selector-item-683", + "targets": [ + ["id=property-selector-item-683", "id"], + ["linkText=X509AuthnConfiguration - Add all", "linkText"], + ["css=#property-selector-item-683", "css:finder"], + ["xpath=//a[@id='property-selector-item-683']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[120]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[683]", "xpath:href"], + ["xpath=//div[120]/a", "xpath:position"], + ["xpath=//a[contains(.,'X509AuthnConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "a11e93fd-5a1b-4456-a875-f0b8a8582058", + "comment": "", + "command": "click", + "target": "css=.fa-caret-down > path", + "targets": [ + ["css=.fa-caret-down > path", "css:finder"] + ], + "value": "" + }, { + "id": "299da229-ce40-43ac-87c6-2bb6c1122d93", + "comment": "", + "command": "click", + "target": "id=property-selector-item-699", + "targets": [ + ["id=property-selector-item-699", "id"], + ["linkText=X509InternalAuthnConfiguration - Add all", "linkText"], + ["css=#property-selector-item-699", "css:finder"], + ["xpath=//a[@id='property-selector-item-699']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[122]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[699]", "xpath:href"], + ["xpath=//div[122]/a", "xpath:position"], + ["xpath=//a[contains(.,'X509InternalAuthnConfiguration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "2a8c3086-a40d-4e9c-857a-7fda2bd2e8f5", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[68]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "93a9c033-0fcc-4af9-85b5-7e18d882bf68", + "comment": "", + "command": "click", + "target": "css=.col-12 > .d-flex", + "targets": [ + ["css=.col-12 > .d-flex", "css:finder"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div", "xpath:position"] + ], + "value": "" + }, { + "id": "d06a3e9a-849f-4b8d-83a1-797f8abf6794", + "comment": "", + "command": "click", + "target": "css=.ms-2", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" + }, { + "id": "1e726b4f-8ae7-40eb-ba52-747c88ae2e89", + "comment": "", + "command": "assertText", + "target": "css=tr:nth-child(653) > td:nth-child(1)", + "targets": [ + ["css=tr:nth-child(653) > td:nth-child(1)", "css:finder"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[4]/div/table/tbody/tr[653]/td", "xpath:idRelative"], + ["xpath=//tr[653]/td", "xpath:position"], + ["xpath=//td[contains(.,'idp.authn.X509Internal.discoveryRequired')]", "xpath:innerText"] + ], + "value": "idp.authn.X509Internal.discoveryRequired" + }, { + "id": "9af817b8-7f25-4f90-8b9a-f24582b7c19b", + "comment": "", + "command": "click", + "target": "css=.btn-info", + "targets": [ + ["css=.btn-info", "css:finder"], + ["xpath=(//button[@type='button'])[5]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,' Save')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "0e2f3bef-0c6c-457f-83c0-d1b464508daa", + "comment": "", + "command": "click", + "target": "linkText=Edit", + "targets": [ + ["linkText=Edit", "linkText"], + ["css=.btn-primary", "css:finder"], + ["xpath=//a[contains(text(),'Edit')]", "xpath:link"], + ["xpath=//div[@id='root']/div/main/div/section/div/div[2]/div[2]/table/tbody/tr/td[3]/div/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '/configurations/831/edit')])[2]", "xpath:href"], + ["xpath=//td[3]/div/a", "xpath:position"], + ["xpath=//a[contains(.,'  Edit')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "caeb6c0b-c99d-4e4f-87b1-874ac54f30a8", + "comment": "", + "command": "click", + "target": "id=valueInput-idp.resolvertest.accessPolicy", + "targets": [ + ["id=valueInput-idp.resolvertest.accessPolicy", "id"], + ["name=properties.0.propertyValue", "name"], + ["css=#valueInput-idp\\.resolvertest\\.accessPolicy", "css:finder"], + ["xpath=//input[@id='valueInput-idp.resolvertest.accessPolicy']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[4]/div/table/tbody/tr/td[4]/div/input", "xpath:idRelative"], + ["xpath=//td[4]/div/input", "xpath:position"] + ], + "value": "" + }, { + "id": "812d8a90-f462-470a-9a4d-efd2cca679c2", + "comment": "", + "command": "type", + "target": "id=valueInput-idp.resolvertest.accessPolicy", + "targets": [ + ["id=valueInput-idp.resolvertest.accessPolicy", "id"], + ["name=properties.0.propertyValue", "name"], + ["css=#valueInput-idp\\.resolvertest\\.accessPolicy", "css:finder"], + ["xpath=//input[@id='valueInput-idp.resolvertest.accessPolicy']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[4]/div/table/tbody/tr/td[4]/div/input", "xpath:idRelative"], + ["xpath=//td[4]/div/input", "xpath:position"] + ], + "value": "foo" + }, { + "id": "8c98218b-9d71-42ac-8682-36d2aeb0f39e", + "comment": "", + "command": "click", + "target": "id=valueInput-idp.resolvertest.logging", + "targets": [ + ["id=valueInput-idp.resolvertest.logging", "id"], + ["name=properties.1.propertyValue", "name"], + ["css=#valueInput-idp\\.resolvertest\\.logging", "css:finder"], + ["xpath=//input[@id='valueInput-idp.resolvertest.logging']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[4]/div/table/tbody/tr[2]/td[4]/div/input", "xpath:idRelative"], + ["xpath=//tr[2]/td[4]/div/input", "xpath:position"] + ], + "value": "" + }, { + "id": "948ac5c1-aa09-44af-a024-c0dc898616d1", + "comment": "", + "command": "type", + "target": "id=valueInput-idp.resolvertest.logging", + "targets": [ + ["id=valueInput-idp.resolvertest.logging", "id"], + ["name=properties.1.propertyValue", "name"], + ["css=#valueInput-idp\\.resolvertest\\.logging", "css:finder"], + ["xpath=//input[@id='valueInput-idp.resolvertest.logging']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[4]/div/table/tbody/tr[2]/td[4]/div/input", "xpath:idRelative"], + ["xpath=//tr[2]/td[4]/div/input", "xpath:position"] + ], + "value": "bar" + }, { + "id": "46d0e1ac-4706-47cf-9336-683b7b6519f2", + "comment": "", + "command": "click", + "target": "name=properties.2.propertyValue", + "targets": [ + ["name=properties.2.propertyValue", "name"], + ["css=tr:nth-child(3) .form-check-input", "css:finder"], + ["xpath=//input[@name='properties.2.propertyValue']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[4]/div/table/tbody/tr[3]/td[4]/div/input", "xpath:idRelative"], + ["xpath=//tr[3]/td[4]/div/input", "xpath:position"] + ], + "value": "" + }, { + "id": "d3898399-e0c0-4ac1-9f66-ab1ef682cc4e", + "comment": "", + "command": "click", + "target": "css=.btn-info", + "targets": [ + ["css=.btn-info", "css:finder"], + ["xpath=(//button[@type='button'])[5]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,' Save')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "47617f08-9b12-47f0-b8bc-bf97636014fb", + "comment": "", + "command": "click", + "target": "css=.fa-pen-to-square > path", + "targets": [ + ["css=.fa-pen-to-square > path", "css:finder"] + ], + "value": "" + }, { + "id": "aaab6ac3-6c55-4b8f-8e97-4913e4d658d6", + "comment": "", + "command": "click", + "target": "name=properties.2.propertyValue", + "targets": [ + ["name=properties.2.propertyValue", "name"], + ["css=tr:nth-child(3) .form-check-input", "css:finder"], + ["xpath=//input[@name='properties.2.propertyValue']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[4]/div/table/tbody/tr[3]/td[4]/div/input", "xpath:idRelative"], + ["xpath=//tr[3]/td[4]/div/input", "xpath:position"] + ], + "value": "" + }, { + "id": "dea3ef04-ea08-40ea-8dce-eafc87ab2051", + "comment": "", + "command": "click", + "target": "name=properties.3.propertyValue", + "targets": [ + ["name=properties.3.propertyValue", "name"], + ["css=tr:nth-child(4) .form-check-input", "css:finder"], + ["xpath=//input[@name='properties.3.propertyValue']", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[4]/div/table/tbody/tr[4]/td[4]/div/input", "xpath:idRelative"], + ["xpath=//tr[4]/td[4]/div/input", "xpath:position"] + ], + "value": "" + }, { + "id": "fea5a053-a52e-4b5c-8477-51325b5baf40", + "comment": "", + "command": "click", + "target": "css=.btn-info", + "targets": [ + ["css=.btn-info", "css:finder"], + ["xpath=(//button[@type='button'])[5]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,' Save')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "cd64daba-9c2c-4523-a17d-8168f91b4f93", + "comment": "", + "command": "click", + "target": "css=.btn-danger", + "targets": [ + ["css=.btn-danger", "css:finder"], + ["xpath=(//button[@type='button'])[7]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div/div[2]/div[2]/table/tbody/tr/td[3]/div/button", "xpath:idRelative"], + ["xpath=//td[3]/div/button", "xpath:position"], + ["xpath=//button[contains(.,'  Delete')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "debe5850-a226-47d1-b38b-17015449edf9", + "comment": "", + "command": "click", + "target": "css=.btn-danger:nth-child(1)", + "targets": [ + ["css=.btn-danger:nth-child(1)", "css:finder"], + ["xpath=(//button[@type='button'])[8]", "xpath:attributes"], + ["xpath=//div[4]/div/div/div[3]/button", "xpath:position"] + ], + "value": "" + }, { + "id": "efc6da0e-490c-4c8b-b4d2-07b71059d0ef", + "comment": "", + "command": "open", + "target": "/api/heheheheheheheWipeout", + "targets": [], + "value": "" + }, { + "id": "80cfb61f-79a5-429b-9b7e-b5991b8e279f", + "comment": "", + "command": "assertText", + "target": "css=body", + "targets": [], + "value": "yes, you did it" + }] + }], + "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 1f13272d545dd300c3c44db1003a62bd3a0ce411 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Wed, 7 Sep 2022 09:23:02 -0700 Subject: [PATCH 48/71] Fixed responsive table --- .../app/admin/component/ConfigurationForm.js | 98 ++++++++++--------- 1 file changed, 50 insertions(+), 48 deletions(-) diff --git a/ui/src/app/admin/component/ConfigurationForm.js b/ui/src/app/admin/component/ConfigurationForm.js index 751e94310..747a70452 100644 --- a/ui/src/app/admin/component/ConfigurationForm.js +++ b/ui/src/app/admin/component/ConfigurationForm.js @@ -134,56 +134,58 @@ export function ConfigurationForm({ configurations, configuration = {}, loading,
- - - - - - - - - - - - {fields.map((p, idx) => ( - - - - - - +
PropertyCategoryTypeValueAction
{ p.propertyName }{ p.category }{ p.displayType } - {p.displayType !== 'boolean' ? - - - - : - - } - - +
+ + + + + + + + + + + + {fields.map((p, idx) => ( + + + + + + + + ))} + {fields.length === 0 && + + - ))} - {fields.length === 0 && - - - - } - -
PropertyCategoryTypeValueAction
{ p.propertyName }{ p.category }{ p.displayType } + {p.displayType !== 'boolean' ? + + + + : + + } + + +
+ At least one property is required.
- At least one property is required. -
+ } +
+
From c884af3c11bc8b2ae27bf89c7c75777fa9250fd1 Mon Sep 17 00:00:00 2001 From: Sean Porth Date: Wed, 7 Sep 2022 15:03:34 -0400 Subject: [PATCH 49/71] shibui-2378 move bulk-upload into repo --- bulk-upload/README.md | 43 +++ bulk-upload/docker-build/Dockerfile | 10 + bulk-upload/docker-build/README.txt | 1 + bulk-upload/docker-build/shibui-md-upload.pl | 337 +++++++++++++++++++ bulk-upload/run.sh | 15 + bulk-upload/upload.conf | 35 ++ 6 files changed, 441 insertions(+) create mode 100644 bulk-upload/README.md create mode 100644 bulk-upload/docker-build/Dockerfile create mode 100644 bulk-upload/docker-build/README.txt create mode 100755 bulk-upload/docker-build/shibui-md-upload.pl create mode 100755 bulk-upload/run.sh create mode 100644 bulk-upload/upload.conf diff --git a/bulk-upload/README.md b/bulk-upload/README.md new file mode 100644 index 000000000..c436394e8 --- /dev/null +++ b/bulk-upload/README.md @@ -0,0 +1,43 @@ +This script can be used to bulk upload metadata files into the Shibboleth IdP UI + +### requirements ### +The shibui must be configured without SAML authentication enabled. The API is currently only accessible using Basic auth. +If shibui is using SAML auth, you can temporarily disable it by setting pac4j-enabled: false in application.yml and restarting shibui. +After uploading you can re-enable SAML auth by setting pac4j-enabled: true in application.yml and restarting shibui. + +### usage ### +`./run.sh -e` + +Where is one of: + +path to a dir containing individual metadata files, aggregate files, or a mix of both +path to one metadata file or aggregate file. + +-e enable metadata source after upload + +### configuration ### +Configuration is done in upload.conf. This file must reside in the same dir as run.sh +At a minimum it must contain the shibui api info. It can also be used to add entity attributes to the metadata as it is uploaded (examples are in upload.conf). + +#a entity attribute configuration in upload.conf like: +attr[0][FriendlyName] = signAssertions +attr[0][Name] = http://shibboleth.net/ns/profiles/saml2/sso/browser/signAssertions +attr[0][type] = xsd:boolean +attr[0][Value] = false + +#turns into: +```xml + + false + +``` + +### docker image ### +run.sh will pull the shibui-bulk-upload image from dockerhub and run the script within +If you need to build the image yourself, `cd docker-build;docker build -t unicon/shibui-bulk-upload .` + +### running without docker ### +The docker-build/shibui-md-upload.pl script can be run manually. +Depending on OS you may need to install some additional non dist Perl modules. REST::Client , XML::LibXML , JSON , Config::File +`perl shibui-md-upload.pl -c -m -e (enable metadata source after upload)` + diff --git a/bulk-upload/docker-build/Dockerfile b/bulk-upload/docker-build/Dockerfile new file mode 100644 index 000000000..dd7384667 --- /dev/null +++ b/bulk-upload/docker-build/Dockerfile @@ -0,0 +1,10 @@ +FROM debian:stable-slim +MAINTAINER sporth@unicon.net + +RUN apt-get clean \ + && apt-get -y update \ + && apt-get install -y librest-client-perl libconfig-file-perl jq libxml-libxml-perl libjson-perl + +WORKDIR /opt +COPY shibui-md-upload.pl /opt/shibui-md-upload.pl +ENTRYPOINT ["/opt/shibui-md-upload.pl"] diff --git a/bulk-upload/docker-build/README.txt b/bulk-upload/docker-build/README.txt new file mode 100644 index 000000000..823f746c5 --- /dev/null +++ b/bulk-upload/docker-build/README.txt @@ -0,0 +1 @@ +docker build -t unicon/shibui-bulk-upload . diff --git a/bulk-upload/docker-build/shibui-md-upload.pl b/bulk-upload/docker-build/shibui-md-upload.pl new file mode 100755 index 000000000..3aae45aa8 --- /dev/null +++ b/bulk-upload/docker-build/shibui-md-upload.pl @@ -0,0 +1,337 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Getopt::Std; +use Config::File; +use REST::Client; +use MIME::Base64; +use HTTP::Cookies; +use XML::LibXML; +use XML::LibXML::XPathContext; +use Encode; +use JSON; + +##process arguments +our ($opt_e,$opt_m,$opt_c); +getopts('em:c:'); +my $enable = ($opt_e) ? 'true' : 'false'; +my $md = ($opt_m) ? $opt_m : '/opt/metadata/'; +my $uc = ($opt_c) ? $opt_c : '/opt/conf/upload.conf'; +## + +#config file is required, will contain the api information and other optional settings for adding extensions to the MD +my $conf = Config::File::read_config_file($uc); + +##setup REST::Client +my $unpw = encode_base64($conf->{api_user} . ':' . $conf->{api_pass}); +my $cookies = HTTP::Cookies->new( {} ); +my $client = REST::Client->new(); +$client->getUseragent()->cookie_jar($cookies); + +if ($conf->{api_selfsigned} =~ m/true/) { + $client->getUseragent()->ssl_opts(verify_hostname => 0); + $client->getUseragent()->ssl_opts(SSL_verify_mode => 0); +} + +$client->addHeader('Accept', 'application/json'); +$client->addHeader('Authorization', "Basic $unpw"); +$client->setHost($conf->{api_host}); + +#create auth token +$client->HEAD('/'); +my $token = &get_cookie_value($cookies, 'XSRF-TOKEN'); +$client->addHeader('X-XSRF-TOKEN', $token); +## + +#for stats +my $i = 0; +my $j = 0; + +##load the MD +#check whether we are reading a dir or file +if (-d $md) { + opendir(my $DH, $md) or die "Can't open $md: $!"; + + while (readdir $DH) { + next if ($_ =~ m/^\.|\.\./); + my $file = $_; + + my $xpc = &load_xml("$md/$file"); + + #check if file is aggregate, or individual entity + my $root = $xpc->findnodes("/*[local-name()='EntitiesDescriptor']"); + + if ($root) { + print "\nprocessing aggregate file: $file ....\n"; + + my $entity = $xpc->findnodes("//*[local-name()='EntityDescriptor']"); + + foreach my $var ($entity->get_nodelist) { + my ($name,$entid,$xml) = &get_entity($var); + print "\nimporting entity $entid\n"; + + #check if config file indicates entity attributes are to be added and add them to the parsed xml as needed + my $attr = get_attr_xml($xpc,$xml); + $xml = $attr if ($attr); + + my $code = &call_api($name,$entid,$xml,$enable); + $i++ if ($code == 201); + $j++ if ($code == 409); + } + + } else { + print "\nprocessing MD file: $file ....\n"; + + open(my $fh,"$md/$file"); + read $fh, my $xml, -s $fh; + + my ($name,$entid) = &get_names($xpc); + + #check if config file indicates entity attributes are to be added and add them to the parsed xml as needed + my $attr = get_attr_xml($xpc,$xml); + $xml = $attr if ($attr); + + my $code = &call_api($name,$entid,$xml,$enable); + $i++ if ($code == 201); + $j++ if ($code == 409); + } + } + closedir $DH; + +#single file +} elsif (-f $md) { + my $xpc = &load_xml("$md"); + + #check if file is aggregate, or individual entity + my $root = $xpc->findnodes("/*[local-name()='EntitiesDescriptor']"); + + if ($root) { + print "\nprocessing aggregate file: $md ....\n"; + + my $entity = $xpc->findnodes("//*[local-name()='EntityDescriptor']"); + + foreach my $var ($entity->get_nodelist) { + my ($name,$entid,$xml) = &get_entity($var); + print "\nimporting entity $entid\n"; + + #check if config file indicates entity attributes are to be added and add them to the parsed xml as needed + my $attr = get_attr_xml($xpc,$xml); + $xml = $attr if ($attr); + + my $code = &call_api($name,$entid,$xml,$enable); + $i++ if ($code == 201); + $j++ if ($code == 409); + } + + } else { + print "\nprocessing MD file: $md ....\n"; + + open(my $fh,$md); + read $fh, my $xml, -s $fh; + + my ($name,$entid) = &get_names($xpc); + + #check if config file indicates entity attributes are to be added and add them to the parsed xml as needed + my $attr = get_attr_xml($xpc,$xml); + $xml = $attr if ($attr); + + my $code = &call_api($name,$entid,$xml,$enable); + $i++ if ($code == 201); + $j++ if ($code == 409); + } + +} else { + print "$md can not be found\n"; + exit 1; +} + +print "\nmetadata uploaded: $i\nduplicate: $j\n"; + +sub load_xml { + my $file = shift; + + my $dom = XML::LibXML->load_xml(location => "$file"); + my $xpc = XML::LibXML::XPathContext->new(); + $xpc->registerNs('md', 'urn:oasis:names:tc:SAML:2.0:metadata'); + $xpc->registerNs('mdui', 'urn:oasis:names:tc:SAML:metadata:ui'); + $xpc->setContextNode($dom); + return $xpc; +} + +sub get_cookie_value { + my $cookies = $_[0]; + my $name = $_[1]; + my $result = 0; + + $cookies->scan(sub + { + if ($_[1] eq $name) + { + $result = $_[2]; + }; + }); + + return $result; +} + +sub get_names { + my $node = shift; + my $name; + + my $entid = $node->findnodes("//*[local-name()='EntityDescriptor']/\@entityID"); + my $orgname = $node->findnodes("//*[local-name()='Organization']/*[local-name()='OrganizationDisplayName']/text()"); + my $uiname = $node->findnodes("//*[local-name()='UIInfo']/*[local-name()='DisplayName']/text()"); + $name = ($orgname) ? $orgname : $entid; + $name = ($uiname) ? $uiname : $name; + + return ($name,$entid); +} + + +sub call_api { + my $name = shift; + my $entid = shift; + my $xml = shift; + my $enable = shift; + my ($params,$code,$result); + + my $utf8 = encode_utf8($xml); + + $params = "?spName=$name"; + $params .= "&enableService=true" if ($enable); + + $client->addHeader('Content-Type', "application/xml; charset='utf8'"); + $client->POST("/api/EntityDescriptor$params",$utf8); + + $code = $client->responseCode(); + $result = $client->responseContent(); + + if ($code == 201) { + + if ($enable =~ m/true/) { + + my $res = JSON->new->decode($result); + my $id = $res->{id}; + + $client->PATCH("/api/activate/entityDescriptor/$id/enable"); + + my $ecode = $client->responseCode(); + my $eresult = $client->responseContent(); + + if ($ecode == 200 || $ecode == 201) { + print "$ecode: entity $name uploaded sucessfully and enabled\n"; + } else { + print "$ecode: entity $name uploaded sucessfully but enabling failed:\n"; + open(my $pipe, '|-', "jq ."); + print $pipe $eresult; + } + + } else { + print "$code: entity $name uploaded sucessfully\n"; + } + } elsif ($code == 409) { + print "$code: entity $name already exists\n"; + } elsif ($code == 500) { + print "$code: $result\n"; + } else { + open(my $pipe, '|-', "jq ."); + print $pipe $result; + } + + return $code; +} + +sub get_entity { + my $node = shift; + + my $entid = $node->findnodes('./@entityID'); + my $orgname = $node->findnodes("./*[local-name()='Organization']/*[local-name()='OrganizationDisplayName']/text()"); + my $uiname = $node->findnodes("./*[local-name()='SPSSODescriptor']/*[local-name()='Extensions']/*[local-name()='UIInfo']/*[local-name()='DisplayName']/text()"); + my $name = ($orgname) ? $orgname : $entid; + $name = ($uiname) ? $uiname : $name; + + #have to add the NS from EntityDescriptor so each parsed xml fragment is valid + my $ns = qq(xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:alg="urn:oasis:names:tc:SAML:metadata:algsupport" xmlns:mdrpi="urn:oasis:names:tc:SAML:metadata:rpi" xmlns:mdattr="urn:oasis:names:tc:SAML:metadata:attribute" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui" xmlns:remd="http://refeds.org/metadata" xmlns:idpdisc="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0"); + + $node =~ s/\\n{attr}; + my ($nxml,$vxml); + + if ($attr) { + my $n = keys %$attr; + + #if md:Extensions + my $ext = $xpc->findnodes("//*[local-name()='Extensions']"); + if ($ext) { + my $ea = $xpc->findnodes("//*[local-name()='EntityAttributes']"); + if ($ea) { + $nxml .= &create_attrs($attr,$n); + $xml =~ s/\<\/mdattr\:EntityAttributes\>/$nxml<\/mdattr:EntityAttributes>/; + } else { + $nxml = qq(); + $nxml .= &create_attrs($attr,$n); + $nxml .= qq(); + + $xml =~ s/\<\/md\:Extensions\>/$nxml<\/md:Extensions>/; + } + } else { + $nxml = qq(); + $nxml .= qq(); + $nxml .= &create_attrs($attr,$n); + $nxml .= qq(); + $nxml .= qq(); + + $xml =~ s/\<\/md\:EntityDescriptor\>/$nxml<\/md:EntityDescriptor>/; + } + + return $xml; + } +return 0; +} + +sub create_attrs { + my $attr = shift; + my $n = shift; + my ($nxml,$vxml); + + for(my $i = 0; $i < $n; $i++){ + my @val; + my $afname = $attr->{$i}{FriendlyName}; + my $aname = $attr->{$i}{Name}; + my $atype = $attr->{$i}{type}; + my $avalue = $attr->{$i}{Value}; + + if (ref $avalue eq ref {}) { + my $n = keys %$avalue; + for(my $j = 0; $j < $n; $j++){ + push(@val,$attr->{$i}{Value}{$j}); + } + } else { + push(@val,$avalue); + } + + undef $vxml; + foreach my $var (@val) { + $vxml .= qq($var\n); + } + $vxml =~ s/\n$//; + + $nxml .= qq( + + $vxml + ); + + } + $nxml =~ s/\<\/saml2\:Attribute\>$/<\/saml2:Attribute>\n/; + + return $nxml; +} diff --git a/bulk-upload/run.sh b/bulk-upload/run.sh new file mode 100755 index 000000000..86c128c6f --- /dev/null +++ b/bulk-upload/run.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +MD=$1 +LAST=$(basename "$MD") + +if [ -z "$1" ];then +echo "usage: ./run.sh or -e (to enable metadata as it is uploaded)"; +exit 1; +fi + +if [ -z "${1%%/*}" ];then + docker run --network=host --mount type=bind,source=$MD,target=/opt/$LAST --mount type=bind,source=$PWD/upload.conf,target=/opt/conf/upload.conf -t unicon/shibui-bulk-upload -m /opt/$LAST $2 +else + docker run --network=host --mount type=bind,source=$PWD/$MD,target=/opt/$LAST --mount type=bind,source=$PWD/upload.conf,target=/opt/conf/upload.conf -t unicon/shibui-bulk-upload -m /opt/$LAST $2 +fi diff --git a/bulk-upload/upload.conf b/bulk-upload/upload.conf new file mode 100644 index 000000000..b0a82d6e5 --- /dev/null +++ b/bulk-upload/upload.conf @@ -0,0 +1,35 @@ + +##shibui API info +#required + +api_user=root +api_pass=letmein7 +api_host=https://shibui.unicon.local + +#if the API is running with self signed certs +api_selfsigned=true + +## + +##EntityAttributes +#optional +#this configuration will transform these entity attribute values into xml and add them to the parsed xml as it us uploaded +#to add more attributes copy the first block and increment the index + +#single value example + +#attr[0][FriendlyName] = signAssertions +#attr[0][Name] = http://shibboleth.net/ns/profiles/saml2/sso/browser/signAssertions +#attr[0][type] = xsd:boolean +#attr[0][Value] = false + +#multi value example + +#attr[1][FriendlyName] = nameIDFormatPrecedence +#attr[1][Name] = http://shibboleth.net/ns/profiles/nameIDFormatPrecedence +#attr[1][type] = xsd:string +#attr[1][Value][0] = urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress +#attr[1][Value][1] = urn:oasis:names:tc:SAML:2.0:nameid-format:transient +#attr[1][Value][2] = urn:oasis:names:tc:SAML:2.0:nameid-format:persistent + +## \ No newline at end of file From ad3c18b1e2fcfca7e635c41e0233aa575f73fefc Mon Sep 17 00:00:00 2001 From: chasegawa Date: Thu, 8 Sep 2022 10:01:30 -0700 Subject: [PATCH 50/71] SHIBUI-2270 Code clean up from Dima's code review comments --- ...rsEntityDescriptorVersionServiceTests.groovy | 4 ++-- .../JPAMetadataResolverServiceImpl.groovy | 6 +++--- .../MigrationTasksContextLoadedListener.java | 4 ---- .../admin/ui/controller/ActivateController.java | 13 +++++++------ .../ui/controller/ActivateExceptionHandler.java | 8 ++++---- .../controller/AttributeBundleController.java | 11 ++++------- .../AttributeBundleExceptionHandler.java | 6 +++--- .../controller/EntityDescriptorController.java | 17 ++++++++--------- ...ityDescriptorControllerExceptionHandler.java | 6 +++--- .../ui/controller/ShibPropertiesController.java | 17 +++++++++-------- ...hibPropertiesControllerExceptionHandler.java | 8 ++++---- ...ption.java => PersistentEntityNotFound.java} | 4 ++-- .../ui/security/controller/GroupController.java | 10 +++++----- .../GroupControllerExceptionHandler.java | 6 +++--- .../ui/security/controller/RolesController.java | 9 +++++---- .../controller/RolesExceptionHandler.java | 8 ++++---- .../ui/security/controller/UsersController.java | 4 ++-- .../ui/security/service/GroupServiceImpl.java | 8 ++++---- .../ui/security/service/IGroupService.java | 7 +++---- .../ui/security/service/IRolesService.java | 8 ++++---- .../ui/security/service/RolesServiceImpl.java | 12 ++++++------ .../admin/ui/security/service/UserService.java | 6 +++--- .../ui/service/AttributeBundleService.java | 14 +++++++------- ...omEntityAttributesDefinitionServiceImpl.java | 5 +---- .../ui/service/EntityDescriptorService.java | 17 +++++++++-------- .../service/EntityDescriptorVersionService.java | 9 +++++---- .../EnversEntityDescriptorVersionService.java | 13 +++++++------ .../admin/ui/service/FilterService.java | 7 ++++--- .../service/JPAEntityDescriptorServiceImpl.java | 17 +++++++++-------- .../admin/ui/service/JPAFilterServiceImpl.java | 8 +++----- .../ui/service/MetadataResolverService.java | 5 ++--- .../ui/service/ShibConfigurationService.java | 8 ++++---- .../service/ShibConfigurationServiceImpl.java | 14 +++++++------- .../ui/configuration/TestConfiguration.groovy | 1 - .../AttributeBundleControllerTests.groovy | 8 ++++---- .../EntityDescriptorControllerTests.groovy | 4 ++-- .../MetadataFiltersControllerTests.groovy | 4 ++-- .../ShibPropertiesControllerTests.groovy | 12 ++++-------- .../EntityDescriptorRepositoryTest.groovy | 3 +-- .../GroupsControllerIntegrationTests.groovy | 7 +++---- 40 files changed, 162 insertions(+), 176 deletions(-) rename backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/exception/{EntityNotFoundException.java => PersistentEntityNotFound.java} (58%) diff --git a/backend/src/enversTest/groovy/edu/internet2/tier/shibboleth/admin/ui/service/envers/EnversEntityDescriptorVersionServiceTests.groovy b/backend/src/enversTest/groovy/edu/internet2/tier/shibboleth/admin/ui/service/envers/EnversEntityDescriptorVersionServiceTests.groovy index f996c534d..76ca684e8 100644 --- a/backend/src/enversTest/groovy/edu/internet2/tier/shibboleth/admin/ui/service/envers/EnversEntityDescriptorVersionServiceTests.groovy +++ b/backend/src/enversTest/groovy/edu/internet2/tier/shibboleth/admin/ui/service/envers/EnversEntityDescriptorVersionServiceTests.groovy @@ -6,7 +6,7 @@ import edu.internet2.tier.shibboleth.admin.ui.configuration.Internationalization import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration import edu.internet2.tier.shibboleth.admin.ui.configuration.TestConfiguration import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound import edu.internet2.tier.shibboleth.admin.ui.repository.EntityDescriptorRepository import edu.internet2.tier.shibboleth.admin.ui.repository.envers.EnversTestsSupport import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorService @@ -121,7 +121,7 @@ class EnversEntityDescriptorVersionServiceTests extends Specification { def edRepresentation = entityDescriptorVersionService.findSpecificVersionOfEntityDescriptor(ed.resourceId, '1000') false } - catch (EntityNotFoundException expected) { + catch (PersistentEntityNotFound expected) { true } } 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 bb86a1915..f207512ae 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 @@ -26,7 +26,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ResourceBackedMet 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.domain.resolvers.opensaml.Refilterable -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound import edu.internet2.tier.shibboleth.admin.ui.exception.ForbiddenException import edu.internet2.tier.shibboleth.admin.ui.exception.InitializationException import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects @@ -498,10 +498,10 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { } } - public edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver findByResourceId(String resourceId) throws EntityNotFoundException { + public edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver findByResourceId(String resourceId) throws PersistentEntityNotFound { edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver result = metadataResolverRepository.findByResourceId(resourceId) if (result == null ) { - throw new EntityNotFoundException("No Provider with resourceId[" + resourceId + "] was found") + throw new PersistentEntityNotFound("No Provider with resourceId[" + resourceId + "] was found") } return result } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/MigrationTasksContextLoadedListener.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/MigrationTasksContextLoadedListener.java index 4dbe3656d..d9dc38c1e 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/MigrationTasksContextLoadedListener.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/MigrationTasksContextLoadedListener.java @@ -1,7 +1,5 @@ package edu.internet2.tier.shibboleth.admin.ui.configuration.auto; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; -import edu.internet2.tier.shibboleth.admin.ui.security.exception.InvalidGroupRegexException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; @@ -16,8 +14,6 @@ import edu.internet2.tier.shibboleth.admin.ui.security.service.IGroupService; import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService; -import java.util.List; - /** * After the context loads, do any needed migration tasks */ diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ActivateController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ActivateController.java index c9e0f20f5..487bd56c2 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ActivateController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ActivateController.java @@ -5,12 +5,10 @@ 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.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -18,7 +16,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter; import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation; import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.exception.ForbiddenException; import edu.internet2.tier.shibboleth.admin.ui.exception.InitializationException; import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorService; @@ -41,7 +39,8 @@ public class ActivateController { @PatchMapping(path = "/entityDescriptor/{resourceId}/{mode}") @Transactional - public ResponseEntity enableEntityDescriptor(@PathVariable String resourceId, @PathVariable String mode) throws EntityNotFoundException, ForbiddenException { + public ResponseEntity enableEntityDescriptor(@PathVariable String resourceId, @PathVariable String mode) throws + PersistentEntityNotFound, ForbiddenException { boolean status = "enable".equalsIgnoreCase(mode); EntityDescriptorRepresentation edr = entityDescriptorService.updateEntityDescriptorEnabledStatus(resourceId, status); return ResponseEntity.ok(edr); @@ -49,7 +48,8 @@ public ResponseEntity enableEntityDescriptor(@PathVariable String resourceId, @PatchMapping(path = "/MetadataResolvers/{metadataResolverId}/Filter/{resourceId}/{mode}") @Transactional - public ResponseEntity enableFilter(@PathVariable String metadataResolverId, @PathVariable String resourceId, @PathVariable String mode) throws EntityNotFoundException, ForbiddenException, ScriptException { + public ResponseEntity enableFilter(@PathVariable String metadataResolverId, @PathVariable String resourceId, @PathVariable String mode) throws + PersistentEntityNotFound, ForbiddenException, ScriptException { boolean status = "enable".equalsIgnoreCase(mode); MetadataFilter persistedFilter = filterService.updateFilterEnabledStatus(metadataResolverId, resourceId, status); return ResponseEntity.ok(persistedFilter); @@ -57,7 +57,8 @@ public ResponseEntity enableFilter(@PathVariable String metadataResolverId, @ @PatchMapping("/MetadataResolvers/{resourceId}/{mode}") @Transactional - public ResponseEntity enableProvider(@PathVariable String resourceId, @PathVariable String mode) throws EntityNotFoundException, ForbiddenException, MetadataFileNotFoundException, InitializationException { + public ResponseEntity enableProvider(@PathVariable String resourceId, @PathVariable String mode) throws + PersistentEntityNotFound, ForbiddenException, MetadataFileNotFoundException, InitializationException { boolean status = "enable".equalsIgnoreCase(mode); MetadataResolver existingResolver = metadataResolverService.findByResourceId(resourceId); existingResolver.setEnabled(status); diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ActivateExceptionHandler.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ActivateExceptionHandler.java index 0c766c53c..fe6f7c0f2 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ActivateExceptionHandler.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ActivateExceptionHandler.java @@ -12,15 +12,15 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; import edu.internet2.tier.shibboleth.admin.ui.domain.exceptions.MetadataFileNotFoundException; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.exception.ForbiddenException; import edu.internet2.tier.shibboleth.admin.ui.exception.InitializationException; @ControllerAdvice(assignableTypes = {ActivateController.class}) public class ActivateExceptionHandler extends ResponseEntityExceptionHandler { - @ExceptionHandler({ EntityNotFoundException.class }) - public ResponseEntity handleEntityNotFoundException(EntityNotFoundException e, WebRequest request) { + @ExceptionHandler({ PersistentEntityNotFound.class }) + public ResponseEntity handleEntityNotFoundException(PersistentEntityNotFound e, WebRequest request) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ErrorResponse(HttpStatus.NOT_FOUND, e.getMessage())); } @@ -45,4 +45,4 @@ public ResponseEntity handleScriptException(ScriptException e, WebRequest req } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/AttributeBundleController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/AttributeBundleController.java index 92c498781..53335d340 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/AttributeBundleController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/AttributeBundleController.java @@ -1,11 +1,8 @@ package edu.internet2.tier.shibboleth.admin.ui.controller; import edu.internet2.tier.shibboleth.admin.ui.domain.AttributeBundle; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.exception.ObjectIdExistsException; -import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupDeleteException; -import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupExistsConflictException; -import edu.internet2.tier.shibboleth.admin.ui.security.model.Group; import edu.internet2.tier.shibboleth.admin.ui.service.AttributeBundleService; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tags; @@ -42,7 +39,7 @@ public ResponseEntity create(@RequestBody AttributeBundle bundle) throws Obje @Secured("ROLE_ADMIN") @DeleteMapping("/{resourceId}") @Transactional - public ResponseEntity delete(@PathVariable String resourceId) throws EntityNotFoundException { + public ResponseEntity delete(@PathVariable String resourceId) throws PersistentEntityNotFound { attributeBundleService.deleteDefinition(resourceId); return ResponseEntity.noContent().build(); } @@ -55,14 +52,14 @@ public ResponseEntity getAll() { @GetMapping("/{resourceId}") @Transactional(readOnly = true) - public ResponseEntity getOne(@PathVariable String resourceId) throws EntityNotFoundException { + public ResponseEntity getOne(@PathVariable String resourceId) throws PersistentEntityNotFound { return ResponseEntity.ok(attributeBundleService.findByResourceId(resourceId)); } @Secured("ROLE_ADMIN") @PutMapping @Transactional - public ResponseEntity update(@RequestBody AttributeBundle bundle) throws EntityNotFoundException { + public ResponseEntity update(@RequestBody AttributeBundle bundle) throws PersistentEntityNotFound { AttributeBundle result = attributeBundleService.updateBundle(bundle); return ResponseEntity.ok(result); } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/AttributeBundleExceptionHandler.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/AttributeBundleExceptionHandler.java index 9f5266c3c..44f32f6ea 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/AttributeBundleExceptionHandler.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/AttributeBundleExceptionHandler.java @@ -1,6 +1,6 @@ package edu.internet2.tier.shibboleth.admin.ui.controller; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.exception.ObjectIdExistsException; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -12,8 +12,8 @@ @ControllerAdvice(assignableTypes = {AttributeBundleController.class}) public class AttributeBundleExceptionHandler extends ResponseEntityExceptionHandler { - @ExceptionHandler({ EntityNotFoundException.class }) - public ResponseEntity handleEntityNotFoundException(EntityNotFoundException e, WebRequest request) { + @ExceptionHandler({ PersistentEntityNotFound.class }) + public ResponseEntity handleEntityNotFoundException(PersistentEntityNotFound e, WebRequest request) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ErrorResponse(HttpStatus.NOT_FOUND, e.getMessage())); } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java index 81d62a1ad..f7cfb019a 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java @@ -2,14 +2,13 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor; import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.exception.ForbiddenException; import edu.internet2.tier.shibboleth.admin.ui.exception.InvalidPatternMatchException; import edu.internet2.tier.shibboleth.admin.ui.exception.ObjectIdExistsException; import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects; import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorService; import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorVersionService; -import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tags; import lombok.extern.slf4j.Slf4j; @@ -34,7 +33,6 @@ import javax.annotation.PostConstruct; import java.net.URI; import java.util.ConcurrentModificationException; -import java.util.Optional; @RestController @RequestMapping("/api") @@ -77,7 +75,7 @@ public ResponseEntity create(@RequestBody EntityDescriptorRepresentation edRe @Secured("ROLE_ADMIN") @DeleteMapping(value = "/EntityDescriptor/{resourceId}") @Transactional - public ResponseEntity deleteOne(@PathVariable String resourceId) throws ForbiddenException, EntityNotFoundException { + public ResponseEntity deleteOne(@PathVariable String resourceId) throws ForbiddenException, PersistentEntityNotFound { entityDescriptorService.delete(resourceId); return ResponseEntity.noContent().build(); } @@ -90,7 +88,7 @@ public ResponseEntity getAll() throws ForbiddenException { @GetMapping("/EntityDescriptor/{resourceId}/Versions") @Transactional - public ResponseEntity getAllVersions(@PathVariable String resourceId) throws EntityNotFoundException, ForbiddenException { + public ResponseEntity getAllVersions(@PathVariable String resourceId) throws PersistentEntityNotFound, ForbiddenException { // this "get by resource id" verifies that both the ED exists and the user has proper access, so needs to remain EntityDescriptor ed = entityDescriptorService.getEntityDescriptorByResourceId(resourceId); return ResponseEntity.ok(versionService.findVersionsForEntityDescriptor(ed.getResourceId())); @@ -105,21 +103,22 @@ public Iterable getDisabledAndNotOwnedByAdmin() @GetMapping("/EntityDescriptor/{resourceId}") @Transactional - public ResponseEntity getOne(@PathVariable String resourceId) throws EntityNotFoundException, ForbiddenException { + public ResponseEntity getOne(@PathVariable String resourceId) throws PersistentEntityNotFound, ForbiddenException { return ResponseEntity.ok(entityDescriptorService .createRepresentationFromDescriptor(entityDescriptorService.getEntityDescriptorByResourceId(resourceId))); } @GetMapping(value = "/EntityDescriptor/{resourceId}", produces = "application/xml") @Transactional - public ResponseEntity getOneXml(@PathVariable String resourceId) throws MarshallingException, EntityNotFoundException, ForbiddenException { + public ResponseEntity getOneXml(@PathVariable String resourceId) throws MarshallingException, PersistentEntityNotFound, ForbiddenException { EntityDescriptor ed = entityDescriptorService.getEntityDescriptorByResourceId(resourceId); final String xml = this.openSamlObjects.marshalToXmlString(ed); return ResponseEntity.ok(xml); } @GetMapping("/EntityDescriptor/{resourceId}/Versions/{versionId}") - public ResponseEntity getSpecificVersion(@PathVariable String resourceId, @PathVariable String versionId) throws EntityNotFoundException, ForbiddenException { + public ResponseEntity getSpecificVersion(@PathVariable String resourceId, @PathVariable String versionId) throws + PersistentEntityNotFound, ForbiddenException { // this "get by resource id" verifies that both the ED exists and the user has proper access, so needs to remain EntityDescriptor ed = entityDescriptorService.getEntityDescriptorByResourceId(resourceId); EntityDescriptorRepresentation result = versionService.findSpecificVersionOfEntityDescriptor(ed.getResourceId(), versionId); @@ -146,7 +145,7 @@ public void initRestTemplate() { @PutMapping("/EntityDescriptor/{resourceId}") @Transactional public ResponseEntity update(@RequestBody EntityDescriptorRepresentation edRepresentation, @PathVariable String resourceId) - throws ForbiddenException, ConcurrentModificationException, EntityNotFoundException, + throws ForbiddenException, ConcurrentModificationException, PersistentEntityNotFound, InvalidPatternMatchException { edRepresentation.setId(resourceId); // This should be the same already, but just to be safe... EntityDescriptorRepresentation result = entityDescriptorService.update(edRepresentation); diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerExceptionHandler.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerExceptionHandler.java index 32d3cd4be..e1afe9413 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerExceptionHandler.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerExceptionHandler.java @@ -1,6 +1,6 @@ package edu.internet2.tier.shibboleth.admin.ui.controller; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.exception.ForbiddenException; import edu.internet2.tier.shibboleth.admin.ui.exception.InvalidPatternMatchException; import edu.internet2.tier.shibboleth.admin.ui.exception.ObjectIdExistsException; @@ -22,8 +22,8 @@ public ResponseEntity handleConcurrentModificationException(ConcurrentModific return ResponseEntity.status(HttpStatus.CONFLICT).body(new ErrorResponse(HttpStatus.CONFLICT, e.getMessage())); } - @ExceptionHandler({ EntityNotFoundException.class }) - public ResponseEntity handleEntityNotFoundException(EntityNotFoundException e, WebRequest request) { + @ExceptionHandler({ PersistentEntityNotFound.class }) + public ResponseEntity handleEntityNotFoundException(PersistentEntityNotFound e, WebRequest request) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ErrorResponse(HttpStatus.NOT_FOUND, e.getMessage())); } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesController.java index b613c2b4f..b9936633a 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesController.java @@ -2,7 +2,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.shib.properties.ShibPropertySet; import edu.internet2.tier.shibboleth.admin.ui.domain.shib.properties.ShibPropertySetting; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.exception.ObjectIdExistsException; import edu.internet2.tier.shibboleth.admin.ui.service.ShibConfigurationService; import io.swagger.v3.oas.annotations.Operation; @@ -41,8 +41,8 @@ public class ShibPropertiesController { @GetMapping("/properties") @Transactional(readOnly = true) - @Operation(description = "Return all the configuration properties - used to populate the UI with the know configuration properties", - summary = "Return all the configuration properties - used to populate the UI with the know configuration properties", method = "GET") + @Operation(description = "Return all the configuration properties - used to populate the UI with the known configuration properties", + summary = "Return all the configuration properties - used to populate the UI with the known configuration properties", method = "GET") public ResponseEntity getAllConfigurationProperties() { return ResponseEntity.ok(service.getAllConfigurationProperties()); } @@ -62,7 +62,7 @@ public ResponseEntity getAllPropertySets() { @Transactional(readOnly = true) @Operation(description = "Return the property set with the given resourceId", summary = "Return the property set with the given resourceId", method = "GET") - public ResponseEntity getPropertySet(@PathVariable Integer resourceId) throws EntityNotFoundException { + public ResponseEntity getPropertySet(@PathVariable Integer resourceId) throws PersistentEntityNotFound { return ResponseEntity.ok(service.getSet(resourceId)); } @@ -70,7 +70,7 @@ public ResponseEntity getPropertySet(@PathVariable Integer resourceId) throws @Transactional(readOnly = true) @Operation(description = "Return the property set with the given resourceId as a zip file of the properties files", summary = "Return the property set with the given resourceId as a zip file of the properties files", method = "GET") - public ResponseEntity getPropertySetAsZip(@PathVariable Integer resourceId) throws EntityNotFoundException, IOException { + public ResponseEntity getPropertySetAsZip(@PathVariable Integer resourceId) throws PersistentEntityNotFound, IOException { ShibPropertySet set = service.getSet(resourceId); StringBuilder sb = new StringBuilder("attachment; filename=\"").append(set.getName()).append(".zip\""); return ResponseEntity.ok().header("Content-Disposition", sb.toString()).body(prepDownloadAsZip(convertPropertiesToMaps(set.getProperties()))); @@ -80,7 +80,7 @@ public ResponseEntity getPropertySetAsZip(@PathVariable Integer resourceId) t @Transactional(readOnly = true) @Operation(description = "Return the property set with the given resourceId as a zip file of a single properties files", summary = "Return the property set with the given resourceId as a zip file of a single properties files", method = "GET") - public ResponseEntity getPropertySetOneFileAsZip(@PathVariable Integer resourceId) throws EntityNotFoundException, IOException { + public ResponseEntity getPropertySetOneFileAsZip(@PathVariable Integer resourceId) throws PersistentEntityNotFound, IOException { ShibPropertySet set = service.getSet(resourceId); StringBuilder sb = new StringBuilder("attachment; filename=\"").append(set.getName()).append(".zip\""); return ResponseEntity.ok().header("Content-Disposition", sb.toString()).body(prepDownloadAsZipWithSingleFile(convertPropertiesToMaps(set.getProperties()))); @@ -141,7 +141,7 @@ private byte[] prepDownloadAsZip(Map> propertiesFiles @DeleteMapping("/property/set/{resourceId}") @Secured("ROLE_ADMIN") @Transactional - public ResponseEntity deletePropertySet(@PathVariable Integer resourceId) throws EntityNotFoundException { + public ResponseEntity deletePropertySet(@PathVariable Integer resourceId) throws PersistentEntityNotFound { service.delete(resourceId); return ResponseEntity.noContent().build(); } @@ -161,7 +161,8 @@ public ResponseEntity createPropertySet(@RequestBody ShibPropertySet newSet) @Transactional @Operation(description = "Update a property set with with the matching resourceId - must exist", summary = "Update an existing property set with the matching resourceId - must exist", method = "PUT") - public ResponseEntity updatePropertySet(@RequestBody ShibPropertySet setToUpdate, @PathVariable int resourceId) throws EntityNotFoundException { + public ResponseEntity updatePropertySet(@RequestBody ShibPropertySet setToUpdate, @PathVariable int resourceId) throws + PersistentEntityNotFound { ShibPropertySet result = service.update(setToUpdate); return ResponseEntity.status(HttpStatus.OK).body(result); } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesControllerExceptionHandler.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesControllerExceptionHandler.java index cbc9cb133..c75005a39 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesControllerExceptionHandler.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesControllerExceptionHandler.java @@ -1,7 +1,7 @@ package edu.internet2.tier.shibboleth.admin.ui.controller; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; import edu.internet2.tier.shibboleth.admin.ui.exception.ObjectIdExistsException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -14,13 +14,13 @@ @ControllerAdvice(assignableTypes = {ShibPropertiesController.class}) public class ShibPropertiesControllerExceptionHandler extends ResponseEntityExceptionHandler { - @ExceptionHandler({ EntityNotFoundException.class }) - public ResponseEntity handleEntityNotFoundException(EntityNotFoundException e, WebRequest request) { + @ExceptionHandler({ PersistentEntityNotFound.class }) + public ResponseEntity handleEntityNotFoundException(PersistentEntityNotFound e, WebRequest request) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ErrorResponse(HttpStatus.NOT_FOUND, e.getMessage())); } @ExceptionHandler({ IOException.class }) - public ResponseEntity handleIOException(EntityNotFoundException e, WebRequest request) { + public ResponseEntity handleIOException(IOException e, WebRequest request) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error creating file"); } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/exception/EntityNotFoundException.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/exception/PersistentEntityNotFound.java similarity index 58% rename from backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/exception/EntityNotFoundException.java rename to backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/exception/PersistentEntityNotFound.java index 212c9f990..b7dc72f33 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/exception/EntityNotFoundException.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/exception/PersistentEntityNotFound.java @@ -3,8 +3,8 @@ /** * Generically meaning - hibernate entity, not SAML entity */ -public class EntityNotFoundException extends Exception { - public EntityNotFoundException(String message) { +public class PersistentEntityNotFound extends Exception { + public PersistentEntityNotFound(String message) { super(message); } } \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupController.java index c287a14a7..8293c9b04 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupController.java @@ -1,6 +1,6 @@ package edu.internet2.tier.shibboleth.admin.ui.security.controller; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupDeleteException; import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupExistsConflictException; import edu.internet2.tier.shibboleth.admin.ui.security.exception.InvalidGroupRegexException; @@ -40,7 +40,7 @@ public ResponseEntity create(@RequestBody Group group) throws GroupExistsConf @Secured("ROLE_ADMIN") @DeleteMapping("/{resourceId}") @Transactional - public ResponseEntity delete(@PathVariable String resourceId) throws EntityNotFoundException, GroupDeleteException { + public ResponseEntity delete(@PathVariable String resourceId) throws PersistentEntityNotFound, GroupDeleteException { groupService.deleteDefinition(resourceId); return ResponseEntity.noContent().build(); } @@ -53,10 +53,10 @@ public ResponseEntity getAll() { @GetMapping("/{resourceId}") @Transactional(readOnly = true) - public ResponseEntity getOne(@PathVariable String resourceId) throws EntityNotFoundException { + public ResponseEntity getOne(@PathVariable String resourceId) throws PersistentEntityNotFound { Group g = groupService.find(resourceId); if (g == null) { - throw new EntityNotFoundException(String.format("Unable to find group with resource id: [%s]", resourceId)); + throw new PersistentEntityNotFound(String.format("Unable to find group with resource id: [%s]", resourceId)); } return ResponseEntity.ok(g); } @@ -64,7 +64,7 @@ public ResponseEntity getOne(@PathVariable String resourceId) throws EntityNo @Secured("ROLE_ADMIN") @PutMapping @Transactional - public ResponseEntity update(@RequestBody Group group) throws EntityNotFoundException, InvalidGroupRegexException { + public ResponseEntity update(@RequestBody Group group) throws PersistentEntityNotFound, InvalidGroupRegexException { Group result = groupService.updateGroup(group); return ResponseEntity.ok(result); } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupControllerExceptionHandler.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupControllerExceptionHandler.java index 39778e21a..b382f50ca 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupControllerExceptionHandler.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupControllerExceptionHandler.java @@ -11,15 +11,15 @@ import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import edu.internet2.tier.shibboleth.admin.ui.controller.ErrorResponse; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupDeleteException; import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupExistsConflictException; @ControllerAdvice(assignableTypes = {GroupController.class}) public class GroupControllerExceptionHandler extends ResponseEntityExceptionHandler { - @ExceptionHandler({ EntityNotFoundException.class }) - public ResponseEntity handleEntityNotFoundException(EntityNotFoundException e, WebRequest request) { + @ExceptionHandler({ PersistentEntityNotFound.class }) + public ResponseEntity handleEntityNotFoundException(PersistentEntityNotFound e, WebRequest request) { HttpHeaders headers = new HttpHeaders(); headers.setLocation(ServletUriComponentsBuilder.fromCurrentServletMapping().path("/api/admin/groups").build().toUri()); diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/RolesController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/RolesController.java index 539dc3195..9b549efb3 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/RolesController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/RolesController.java @@ -18,7 +18,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.security.exception.RoleDeleteException; import edu.internet2.tier.shibboleth.admin.ui.security.exception.RoleExistsConflictException; import edu.internet2.tier.shibboleth.admin.ui.security.model.Role; @@ -42,7 +42,7 @@ public ResponseEntity create(@RequestBody Role role) throws RoleExistsConflic @Secured("ROLE_ADMIN") @DeleteMapping("/{resourceId}") @Transactional - public ResponseEntity delete(@PathVariable String resourceId) throws EntityNotFoundException, RoleDeleteException { + public ResponseEntity delete(@PathVariable String resourceId) throws PersistentEntityNotFound, RoleDeleteException { rolesService.deleteDefinition(resourceId); return ResponseEntity.noContent().build(); } @@ -55,7 +55,7 @@ public ResponseEntity getAll() { @GetMapping("/{resourceId}") @Transactional(readOnly = true) - public ResponseEntity getOne(@PathVariable String resourceId) throws EntityNotFoundException { + public ResponseEntity getOne(@PathVariable String resourceId) throws PersistentEntityNotFound { Role role = rolesService.findByResourceId(resourceId); return ResponseEntity.ok(role); } @@ -63,7 +63,8 @@ public ResponseEntity getOne(@PathVariable String resourceId) throws EntityNo @Secured("ROLE_ADMIN") @PutMapping(path = {"/", "/{resourceId}" }) @Transactional - public ResponseEntity update(@RequestBody Role incomingRoleDetail, @PathVariable Optional resourceId) throws EntityNotFoundException { + public ResponseEntity update(@RequestBody Role incomingRoleDetail, @PathVariable Optional resourceId) throws + PersistentEntityNotFound { Role updateRole; if (resourceId.isPresent()) { updateRole = rolesService.findByResourceId(resourceId.get()); diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/RolesExceptionHandler.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/RolesExceptionHandler.java index e4b840f1a..494b1a6b1 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/RolesExceptionHandler.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/RolesExceptionHandler.java @@ -10,15 +10,15 @@ import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import edu.internet2.tier.shibboleth.admin.ui.controller.ErrorResponse; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.security.exception.RoleDeleteException; import edu.internet2.tier.shibboleth.admin.ui.security.exception.RoleExistsConflictException; @ControllerAdvice(assignableTypes = {RolesController.class}) public class RolesExceptionHandler extends ResponseEntityExceptionHandler { - @ExceptionHandler({ EntityNotFoundException.class }) - public ResponseEntity handleEntityNotFoundException(EntityNotFoundException e, WebRequest request) { + @ExceptionHandler({ PersistentEntityNotFound.class }) + public ResponseEntity handleEntityNotFoundException(PersistentEntityNotFound e, WebRequest request) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ErrorResponse(HttpStatus.NOT_FOUND, e.getMessage())); } @@ -35,4 +35,4 @@ public ResponseEntity handleForbiddenAccess(RoleDeleteException e, WebRequest public ResponseEntity handleRoleExistsConflictException(RoleExistsConflictException e, WebRequest request) { return ResponseEntity.status(HttpStatus.CONFLICT).body(new ErrorResponse(HttpStatus.CONFLICT, e.getMessage())); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersController.java index a281adc10..ed39250b4 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersController.java @@ -26,7 +26,7 @@ import org.springframework.web.client.HttpClientErrorException; import edu.internet2.tier.shibboleth.admin.ui.controller.ErrorResponse; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.security.exception.OwnershipConflictException; import edu.internet2.tier.shibboleth.admin.ui.security.model.User; import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; @@ -56,7 +56,7 @@ public ResponseEntity deleteOne(@PathVariable String username) { try { userService.delete(username); } - catch (EntityNotFoundException e) { + catch (PersistentEntityNotFound e) { throw new HttpClientErrorException(NOT_FOUND, String.format("User with username [%s] not found", username)); } catch (OwnershipConflictException e) { diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/GroupServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/GroupServiceImpl.java index 65ee10764..f329a5be2 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/GroupServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/GroupServiceImpl.java @@ -1,6 +1,6 @@ package edu.internet2.tier.shibboleth.admin.ui.security.service; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupDeleteException; import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupExistsConflictException; import edu.internet2.tier.shibboleth.admin.ui.security.exception.InvalidGroupRegexException; @@ -52,7 +52,7 @@ public Group createGroup(Group group) throws GroupExistsConflictException, Inval @Override @Transactional - public void deleteDefinition(String resourceId) throws EntityNotFoundException, GroupDeleteException { + public void deleteDefinition(String resourceId) throws PersistentEntityNotFound, GroupDeleteException { Group group = find(resourceId); if (!ownershipRepository.findAllByOwner(group).isEmpty()) { throw new GroupDeleteException(String.format( @@ -116,10 +116,10 @@ public List findAll() { } @Override - public Group updateGroup(Group group) throws EntityNotFoundException, InvalidGroupRegexException { + public Group updateGroup(Group group) throws PersistentEntityNotFound, InvalidGroupRegexException { Group g = find(group.getResourceId()); if (g == null) { - throw new EntityNotFoundException(String.format("Unable to find group with resource id: [%s] and name: [%s]", + throw new PersistentEntityNotFound(String.format("Unable to find group with resource id: [%s] and name: [%s]", group.getResourceId(), group.getName())); } validateGroupRegex(group); diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/IGroupService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/IGroupService.java index d6e44e5ec..66fd089a9 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/IGroupService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/IGroupService.java @@ -2,8 +2,7 @@ import java.util.List; -import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupDeleteException; import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupExistsConflictException; import edu.internet2.tier.shibboleth.admin.ui.security.exception.InvalidGroupRegexException; @@ -13,7 +12,7 @@ public interface IGroupService { Group createGroup(Group group) throws GroupExistsConflictException, InvalidGroupRegexException; - void deleteDefinition(String resourceId) throws EntityNotFoundException, GroupDeleteException; + void deleteDefinition(String resourceId) throws PersistentEntityNotFound, GroupDeleteException; void ensureAdminGroupExists(); @@ -21,7 +20,7 @@ public interface IGroupService { List findAll(); - Group updateGroup(Group g) throws EntityNotFoundException, InvalidGroupRegexException; + Group updateGroup(Group g) throws PersistentEntityNotFound, InvalidGroupRegexException; boolean doesStringMatchGroupPattern(String groupId, String uri); } \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/IRolesService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/IRolesService.java index ac30d986a..46d3f81f5 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/IRolesService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/IRolesService.java @@ -4,7 +4,7 @@ import java.util.Optional; import java.util.Set; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.security.exception.RoleDeleteException; import edu.internet2.tier.shibboleth.admin.ui.security.exception.RoleExistsConflictException; import edu.internet2.tier.shibboleth.admin.ui.security.model.Role; @@ -17,13 +17,13 @@ public interface IRolesService { Optional findByName(String roleNone); - Role findByResourceId(String resourceId) throws EntityNotFoundException; + Role findByResourceId(String resourceId) throws PersistentEntityNotFound; Set getAndCreateAllRoles(Set roles); - void deleteDefinition(String resourceId) throws EntityNotFoundException, RoleDeleteException; + void deleteDefinition(String resourceId) throws PersistentEntityNotFound, RoleDeleteException; - Role updateRole(Role role) throws EntityNotFoundException; + Role updateRole(Role role) throws PersistentEntityNotFound; void save(Role newUserRole); } \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/RolesServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/RolesServiceImpl.java index 939be59d8..18385084b 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/RolesServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/RolesServiceImpl.java @@ -8,7 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.security.exception.RoleDeleteException; import edu.internet2.tier.shibboleth.admin.ui.security.exception.RoleExistsConflictException; import edu.internet2.tier.shibboleth.admin.ui.security.model.Role; @@ -31,7 +31,7 @@ public Role createRole(Role role) throws RoleExistsConflictException { } @Override - public void deleteDefinition(String resourceId) throws EntityNotFoundException, RoleDeleteException { + public void deleteDefinition(String resourceId) throws PersistentEntityNotFound, RoleDeleteException { Optional found = roleRepository.findByResourceId(resourceId); if (found.isPresent() && !found.get().getUsers().isEmpty()) { throw new RoleDeleteException(String.format("Unable to delete role with resource id: [%s] - remove role from all users first", resourceId)); @@ -50,10 +50,10 @@ public Optional findByName(String roleName) { } @Override - public Role findByResourceId(String resourceId) throws EntityNotFoundException { + public Role findByResourceId(String resourceId) throws PersistentEntityNotFound { Optional found = roleRepository.findByResourceId(resourceId); if (found.isEmpty()) { - throw new EntityNotFoundException(String.format("Unable to find role with resource id: [%s]", resourceId)); + throw new PersistentEntityNotFound(String.format("Unable to find role with resource id: [%s]", resourceId)); } return found.get(); } @@ -83,10 +83,10 @@ private Role getRoleNone() { } @Override - public Role updateRole(Role role) throws EntityNotFoundException { + public Role updateRole(Role role) throws PersistentEntityNotFound { Optional found = roleRepository.findByName(role.getName()); if (found.isEmpty()) { - throw new EntityNotFoundException(String.format("Unable to find role with name: [%s]", role.getName())); + throw new PersistentEntityNotFound(String.format("Unable to find role with name: [%s]", role.getName())); } return roleRepository.save(role); } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/UserService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/UserService.java index df200f482..dfe21708a 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/UserService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/UserService.java @@ -2,7 +2,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor; import edu.internet2.tier.shibboleth.admin.ui.domain.IActivatable; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupExistsConflictException; import edu.internet2.tier.shibboleth.admin.ui.security.exception.InvalidGroupRegexException; import edu.internet2.tier.shibboleth.admin.ui.security.exception.OwnershipConflictException; @@ -82,9 +82,9 @@ public boolean currentUserIsAdmin() { } @Transactional - public void delete(String username) throws EntityNotFoundException, OwnershipConflictException { + public void delete(String username) throws PersistentEntityNotFound, OwnershipConflictException { Optional userToRemove = userRepository.findByUsername(username); - if (userToRemove.isEmpty()) throw new EntityNotFoundException("User does not exist"); + if (userToRemove.isEmpty()) throw new PersistentEntityNotFound("User does not exist"); if (!ownershipRepository.findOwnedByUser(username).isEmpty()) throw new OwnershipConflictException("User ["+username+"] has ownership of entities in the system. Please remove all items before attempting to delete the user."); // ok, user exists and doesn't own anything in the system, so delete them diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/AttributeBundleService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/AttributeBundleService.java index 916ea99b2..52b869693 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/AttributeBundleService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/AttributeBundleService.java @@ -1,7 +1,7 @@ package edu.internet2.tier.shibboleth.admin.ui.service; import edu.internet2.tier.shibboleth.admin.ui.domain.AttributeBundle; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.exception.ObjectIdExistsException; import edu.internet2.tier.shibboleth.admin.ui.repository.AttributeBundleRepository; import org.springframework.beans.factory.annotation.Autowired; @@ -26,17 +26,17 @@ public List findAll() { return attributeBundleRepository.findAll(); } - public void deleteDefinition(String resourceId) throws EntityNotFoundException { + public void deleteDefinition(String resourceId) throws PersistentEntityNotFound { if (attributeBundleRepository.findByResourceId(resourceId).isEmpty()) { - throw new EntityNotFoundException(String.format("Unable to find attribute bundle with resource id: [%s] for deletion", resourceId)); + throw new PersistentEntityNotFound(String.format("Unable to find attribute bundle with resource id: [%s] for deletion", resourceId)); } attributeBundleRepository.deleteById(resourceId); } - public AttributeBundle updateBundle(AttributeBundle bundle) throws EntityNotFoundException { + public AttributeBundle updateBundle(AttributeBundle bundle) throws PersistentEntityNotFound { Optional dbBundle = attributeBundleRepository.findByResourceId(bundle.getResourceId()); if (dbBundle.isEmpty()) { - throw new EntityNotFoundException(String.format("Unable to find attribute bundle with resource id: [%s] for update", bundle.getResourceId())); + throw new PersistentEntityNotFound(String.format("Unable to find attribute bundle with resource id: [%s] for update", bundle.getResourceId())); } AttributeBundle bundleToUpdate = dbBundle.get(); bundleToUpdate.setName(bundle.getName()); @@ -44,10 +44,10 @@ public AttributeBundle updateBundle(AttributeBundle bundle) throws EntityNotFoun return attributeBundleRepository.save(bundleToUpdate); } - public AttributeBundle findByResourceId(String resourceId) throws EntityNotFoundException { + public AttributeBundle findByResourceId(String resourceId) throws PersistentEntityNotFound { Optional result = attributeBundleRepository.findByResourceId(resourceId); if (result.isEmpty()) { - throw new EntityNotFoundException(String.format("Unable to find attribute bundle with resource id: [%s] for deletion", resourceId)); + throw new PersistentEntityNotFound(String.format("Unable to find attribute bundle with resource id: [%s] for deletion", resourceId)); } return result.get(); } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java index cd5893c42..98454c058 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/CustomEntityAttributesDefinitionServiceImpl.java @@ -17,10 +17,7 @@ public class CustomEntityAttributesDefinitionServiceImpl implements CustomEntityAttributesDefinitionService { @Autowired private ApplicationEventPublisher applicationEventPublisher; - - @Autowired - EntityManager entityManager; // Why is this here - it isn't used - + @Autowired private CustomEntityAttributeDefinitionRepository repository; diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java index 6ecf9073e..6d66732b0 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java @@ -3,7 +3,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.Attribute; import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor; import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.exception.ForbiddenException; import edu.internet2.tier.shibboleth.admin.ui.exception.InvalidPatternMatchException; import edu.internet2.tier.shibboleth.admin.ui.exception.ObjectIdExistsException; @@ -55,9 +55,9 @@ EntityDescriptorRepresentation createNew(EntityDescriptorRepresentation edRepres /** * @param resourceId - id of the JPA EntityDescriptor * @throws ForbiddenException If user is unauthorized to perform this operation - * @throws EntityNotFoundException If the db entity is not found + * @throws PersistentEntityNotFound If the db entity is not found */ - void delete(String resourceId) throws ForbiddenException, EntityNotFoundException; + void delete(String resourceId) throws ForbiddenException, PersistentEntityNotFound; /** * @return - Iterable set of EntityDescriptorRepresentations of those items which are NOT enabled and not owned by @@ -83,9 +83,9 @@ EntityDescriptorRepresentation createNew(EntityDescriptorRepresentation edRepres * @param resourceId - id of the JPA EntityDescriptor * @return JPA EntityDescriptor * @throws ForbiddenException If user is unauthorized to perform this operation - * @throws EntityNotFoundException If the db entity is not found + * @throws PersistentEntityNotFound If the db entity is not found */ - EntityDescriptor getEntityDescriptorByResourceId(String resourceId) throws EntityNotFoundException, ForbiddenException; + EntityDescriptor getEntityDescriptorByResourceId(String resourceId) throws PersistentEntityNotFound, ForbiddenException; /** * Given a list of attributes, generate a map of relying party overrides @@ -97,12 +97,12 @@ EntityDescriptorRepresentation createNew(EntityDescriptorRepresentation edRepres /** * @throws ForbiddenException If the user is not permitted to perform the action - * @throws EntityNotFoundException If the entity doesn't already exist in the database + * @throws PersistentEntityNotFound If the entity doesn't already exist in the database * @throws ConcurrentModificationException IF the entity is being modified in another session * @throws InvalidPatternMatchException If the entity id or the ACS location urls don't match the supplied regex */ EntityDescriptorRepresentation update(EntityDescriptorRepresentation edRepresentation) - throws ForbiddenException, EntityNotFoundException, ConcurrentModificationException, + throws ForbiddenException, PersistentEntityNotFound, ConcurrentModificationException, InvalidPatternMatchException; /** @@ -113,7 +113,8 @@ EntityDescriptorRepresentation update(EntityDescriptorRepresentation edRepresent */ void updateDescriptorFromRepresentation(final org.opensaml.saml.saml2.metadata.EntityDescriptor entityDescriptor, final EntityDescriptorRepresentation representation); - EntityDescriptorRepresentation updateEntityDescriptorEnabledStatus(String resourceId, boolean status) throws EntityNotFoundException, ForbiddenException; + EntityDescriptorRepresentation updateEntityDescriptorEnabledStatus(String resourceId, boolean status) throws + PersistentEntityNotFound, ForbiddenException; EntityDescriptorRepresentation createNewEntityDescriptorFromXMLOrigin(EntityDescriptor ed); diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorVersionService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorVersionService.java index c8c67fbc8..365fccb80 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorVersionService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorVersionService.java @@ -3,7 +3,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor; import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation; import edu.internet2.tier.shibboleth.admin.ui.domain.versioning.Version; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import java.util.List; @@ -12,7 +12,8 @@ */ public interface EntityDescriptorVersionService { - List findVersionsForEntityDescriptor(String resourceId) throws EntityNotFoundException; + List findVersionsForEntityDescriptor(String resourceId) throws PersistentEntityNotFound; - EntityDescriptorRepresentation findSpecificVersionOfEntityDescriptor(String resourceId, String versionId) throws EntityNotFoundException; -} + EntityDescriptorRepresentation findSpecificVersionOfEntityDescriptor(String resourceId, String versionId) throws + PersistentEntityNotFound; +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EnversEntityDescriptorVersionService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EnversEntityDescriptorVersionService.java index 99906882b..5857ac283 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EnversEntityDescriptorVersionService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EnversEntityDescriptorVersionService.java @@ -4,7 +4,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation; import edu.internet2.tier.shibboleth.admin.ui.domain.versioning.Version; import edu.internet2.tier.shibboleth.admin.ui.envers.EnversVersionServiceSupport; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import java.util.List; @@ -23,20 +23,21 @@ public EnversEntityDescriptorVersionService(EnversVersionServiceSupport enversVe } @Override - public List findVersionsForEntityDescriptor(String resourceId) throws EntityNotFoundException { + public List findVersionsForEntityDescriptor(String resourceId) throws PersistentEntityNotFound { List results = enversVersionServiceSupport.findVersionsForPersistentEntity(resourceId, EntityDescriptor.class); if (results.isEmpty()) { - throw new EntityNotFoundException(String.format("No versions found for entity descriptor with resource id [%s].", resourceId)); + throw new PersistentEntityNotFound(String.format("No versions found for entity descriptor with resource id [%s].", resourceId)); } return results; } @Override - public EntityDescriptorRepresentation findSpecificVersionOfEntityDescriptor(String resourceId, String versionId) throws EntityNotFoundException { + public EntityDescriptorRepresentation findSpecificVersionOfEntityDescriptor(String resourceId, String versionId) throws + PersistentEntityNotFound { Object edObject = enversVersionServiceSupport.findSpecificVersionOfPersistentEntity(resourceId, versionId, EntityDescriptor.class); if (edObject == null) { - throw new EntityNotFoundException("Unable to find specific version requested - version: " + versionId); + throw new PersistentEntityNotFound("Unable to find specific version requested - version: " + versionId); } return entityDescriptorService.createRepresentationFromDescriptor((EntityDescriptor) edObject); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/FilterService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/FilterService.java index 6d752928b..d5823ef9f 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/FilterService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/FilterService.java @@ -5,7 +5,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter; import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter; import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.FilterRepresentation; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.exception.ForbiddenException; /** @@ -31,5 +31,6 @@ public interface FilterService { */ FilterRepresentation createRepresentationFromFilter(final EntityAttributesFilter entityAttributesFilter); - MetadataFilter updateFilterEnabledStatus(String metadataResolverId, String resourceId, boolean status) throws EntityNotFoundException, ForbiddenException, ScriptException; -} + MetadataFilter updateFilterEnabledStatus(String metadataResolverId, String resourceId, boolean status) throws + PersistentEntityNotFound, ForbiddenException, ScriptException; +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java index ec5c28048..6269020e8 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java @@ -16,7 +16,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.OrganizationRepresentation; import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.SecurityInfoRepresentation; import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.ServiceProviderSsoDescriptorRepresentation; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.exception.ForbiddenException; import edu.internet2.tier.shibboleth.admin.ui.exception.InvalidPatternMatchException; import edu.internet2.tier.shibboleth.admin.ui.exception.ObjectIdExistsException; @@ -354,7 +354,7 @@ public EntityDescriptorRepresentation createRepresentationFromDescriptor(org.ope } @Override - public void delete(String resourceId) throws ForbiddenException, EntityNotFoundException { + public void delete(String resourceId) throws ForbiddenException, PersistentEntityNotFound { EntityDescriptor ed = getEntityDescriptorByResourceId(resourceId); if (ed.isServiceEnabled()) { throw new ForbiddenException("Deleting an enabled Metadata Source is not allowed. Disable the source and try again."); @@ -398,10 +398,10 @@ public List getAttributeReleaseListFromAttributeList(List att } @Override - public EntityDescriptor getEntityDescriptorByResourceId(String resourceId) throws EntityNotFoundException, ForbiddenException { + public EntityDescriptor getEntityDescriptorByResourceId(String resourceId) throws PersistentEntityNotFound, ForbiddenException { EntityDescriptor ed = entityDescriptorRepository.findByResourceId(resourceId); if (ed == null) { - throw new EntityNotFoundException(String.format("The entity descriptor with entity id [%s] was not found.", resourceId)); + throw new PersistentEntityNotFound(String.format("The entity descriptor with entity id [%s] was not found.", resourceId)); } if (!userService.isAuthorizedFor(ed)) { throw new ForbiddenException(); @@ -416,10 +416,10 @@ public Map getRelyingPartyOverridesRepresentationFromAttributeLi @Override public EntityDescriptorRepresentation update(EntityDescriptorRepresentation edRep) - throws ForbiddenException, EntityNotFoundException, InvalidPatternMatchException { + throws ForbiddenException, PersistentEntityNotFound, InvalidPatternMatchException { EntityDescriptor existingEd = entityDescriptorRepository.findByResourceId(edRep.getId()); if (existingEd == null) { - throw new EntityNotFoundException(String.format("The entity descriptor with entity id [%s] was not found for update.", edRep.getId())); + throw new PersistentEntityNotFound(String.format("The entity descriptor with entity id [%s] was not found for update.", edRep.getId())); } if (edRep.isServiceEnabled() && !userService.currentUserCanEnable(existingEd)) { throw new ForbiddenException("You do not have the permissions necessary to enable this service."); @@ -456,10 +456,11 @@ public void updateDescriptorFromRepresentation(org.opensaml.saml.saml2.metadata. } @Override - public EntityDescriptorRepresentation updateEntityDescriptorEnabledStatus(String resourceId, boolean status) throws EntityNotFoundException, ForbiddenException { + public EntityDescriptorRepresentation updateEntityDescriptorEnabledStatus(String resourceId, boolean status) throws + PersistentEntityNotFound, ForbiddenException { EntityDescriptor ed = entityDescriptorRepository.findByResourceId(resourceId); if (ed == null) { - throw new EntityNotFoundException("Entity with resourceid[" + resourceId + "] was not found for update"); + throw new PersistentEntityNotFound("Entity with resourceid[" + resourceId + "] was not found for update"); } if (!userService.currentUserCanEnable(ed)) { throw new ForbiddenException("You do not have the permissions necessary to change the enable status of this entity descriptor."); diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAFilterServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAFilterServiceImpl.java index c42bd7cad..aeab05669 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAFilterServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAFilterServiceImpl.java @@ -1,11 +1,10 @@ package edu.internet2.tier.shibboleth.admin.ui.service; -import edu.internet2.tier.shibboleth.admin.ui.domain.IActivatable; import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter; import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter; import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.FilterRepresentation; import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.exception.ForbiddenException; import edu.internet2.tier.shibboleth.admin.ui.repository.FilterRepository; import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository; @@ -16,7 +15,6 @@ import org.springframework.transaction.interceptor.TransactionAspectSupport; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Optional; @@ -108,7 +106,7 @@ private void reloadFiltersAndHandleScriptException(String resolverResourceId) th */ @Override public MetadataFilter updateFilterEnabledStatus(String metadataResolverId, String resourceId, boolean status) - throws EntityNotFoundException, ForbiddenException, ScriptException { + throws PersistentEntityNotFound, ForbiddenException, ScriptException { MetadataResolver metadataResolver = metadataResolverRepository.findByResourceId(metadataResolverId); // Now we operate directly on the filter attached to MetadataResolver, @@ -116,7 +114,7 @@ public MetadataFilter updateFilterEnabledStatus(String metadataResolverId, Strin Optional filterTobeUpdatedOptional = metadataResolver.getMetadataFilters().stream() .filter(it -> it.getResourceId().equals(resourceId)).findFirst(); if (filterTobeUpdatedOptional.isEmpty()) { - throw new EntityNotFoundException("Filter with resource id[" + resourceId + "] not found"); + throw new PersistentEntityNotFound("Filter with resource id[" + resourceId + "] not found"); } MetadataFilter filterTobeUpdated = filterTobeUpdatedOptional.get(); diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolverService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolverService.java index 6c921509e..b32e0d9f9 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolverService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolverService.java @@ -4,13 +4,12 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.exceptions.MetadataFileNotFoundException; import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.exception.ForbiddenException; import edu.internet2.tier.shibboleth.admin.ui.exception.InitializationException; -import org.w3c.dom.Node; public interface MetadataResolverService { - public MetadataResolver findByResourceId(String resourceId) throws EntityNotFoundException; + public MetadataResolver findByResourceId(String resourceId) throws PersistentEntityNotFound; public Document generateConfiguration(); diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ShibConfigurationService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ShibConfigurationService.java index 64c029d96..8c1533a6d 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ShibConfigurationService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ShibConfigurationService.java @@ -2,7 +2,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.shib.properties.ShibConfigurationProperty; import edu.internet2.tier.shibboleth.admin.ui.domain.shib.properties.ShibPropertySet; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.exception.ObjectIdExistsException; import edu.internet2.tier.shibboleth.admin.ui.repository.ProjectionIdAndName; @@ -14,7 +14,7 @@ public interface ShibConfigurationService { ShibPropertySet create(ShibPropertySet set) throws ObjectIdExistsException; - void delete(int resourceId) throws EntityNotFoundException; + void delete(int resourceId) throws PersistentEntityNotFound; List getAllConfigurationProperties(); @@ -22,9 +22,9 @@ public interface ShibConfigurationService { List getExistingPropertyNames(); - ShibPropertySet getSet(int resourceId) throws EntityNotFoundException; + ShibPropertySet getSet(int resourceId) throws PersistentEntityNotFound; ShibConfigurationProperty save(ShibConfigurationProperty prop); - ShibPropertySet update(ShibPropertySet setToUpdate) throws EntityNotFoundException; + ShibPropertySet update(ShibPropertySet setToUpdate) throws PersistentEntityNotFound; } \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ShibConfigurationServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ShibConfigurationServiceImpl.java index 1c3c2a513..21a5605e9 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ShibConfigurationServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ShibConfigurationServiceImpl.java @@ -3,7 +3,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.shib.properties.ShibConfigurationProperty; import edu.internet2.tier.shibboleth.admin.ui.domain.shib.properties.ShibPropertySet; import edu.internet2.tier.shibboleth.admin.ui.domain.shib.properties.ShibPropertySetting; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.exception.ObjectIdExistsException; import edu.internet2.tier.shibboleth.admin.ui.repository.ProjectionIdAndName; import edu.internet2.tier.shibboleth.admin.ui.repository.ShibConfigurationRepository; @@ -39,17 +39,17 @@ public ShibPropertySet create(ShibPropertySet set) throws ObjectIdExistsExceptio getSet(set.getResourceId()); throw new ObjectIdExistsException(Integer.toString(set.getResourceId())); } - catch (EntityNotFoundException e) { + catch (PersistentEntityNotFound e) { // we don't want to find the object } return save(set); } @Override - public void delete(int resourceId) throws EntityNotFoundException { + public void delete(int resourceId) throws PersistentEntityNotFound { ShibPropertySet set = shibPropertySetRepository.findByResourceId(resourceId); if (set == null) { - throw new EntityNotFoundException(String.format("The property set with id [%s] was not found for update.", resourceId)); + throw new PersistentEntityNotFound(String.format("The property set with id [%s] was not found for update.", resourceId)); } shibPropertySettingRepository.deleteAll(set.getProperties()); shibPropertySetRepository.delete(set); @@ -71,10 +71,10 @@ public List getExistingPropertyNames() { } @Override - public ShibPropertySet getSet(int resourceId) throws EntityNotFoundException { + public ShibPropertySet getSet(int resourceId) throws PersistentEntityNotFound { ShibPropertySet result = shibPropertySetRepository.findByResourceId(resourceId); if (result == null) { - throw new EntityNotFoundException((String.format("The property set with id [%s] was not found.", resourceId))); + throw new PersistentEntityNotFound((String.format("The property set with id [%s] was not found.", resourceId))); } return result; } @@ -85,7 +85,7 @@ public ShibConfigurationProperty save(ShibConfigurationProperty prop) { } @Override - public ShibPropertySet update(ShibPropertySet setToUpdate) throws EntityNotFoundException { + public ShibPropertySet update(ShibPropertySet setToUpdate) throws PersistentEntityNotFound { getSet(setToUpdate.getResourceId()); // check that it exists, if not it'll throw an exception return save(setToUpdate); } diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy index f46eb33d8..1a044baf2 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestConfiguration.groovy @@ -61,7 +61,6 @@ class TestConfiguration { @Bean CustomEntityAttributesDefinitionServiceImpl customEntityAttributesDefinitionServiceImpl() { new CustomEntityAttributesDefinitionServiceImpl().with { - it.entityManager = entityManager it.repository = repository return it } diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/AttributeBundleControllerTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/AttributeBundleControllerTests.groovy index 00e624b7e..567639f36 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/AttributeBundleControllerTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/AttributeBundleControllerTests.groovy @@ -1,10 +1,10 @@ package edu.internet2.tier.shibboleth.admin.ui.controller -import com.fasterxml.jackson.databind.MapperFeature + import com.fasterxml.jackson.databind.ObjectMapper import edu.internet2.tier.shibboleth.admin.ui.configuration.ShibUIConfiguration import edu.internet2.tier.shibboleth.admin.ui.domain.AttributeBundle -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound import edu.internet2.tier.shibboleth.admin.ui.exception.ObjectIdExistsException import edu.internet2.tier.shibboleth.admin.ui.repository.AttributeBundleRepository import edu.internet2.tier.shibboleth.admin.ui.service.AttributeBundleService @@ -148,7 +148,7 @@ class AttributeBundleControllerTests extends Specification { mockMvc.perform(delete("/api/custom/entity/bundles/randomIDValdoesntexist")) false } catch (NestedServletException expected) { - expected instanceof EntityNotFoundException + expected instanceof PersistentEntityNotFound } when: "Delete what does exist" @@ -180,7 +180,7 @@ class AttributeBundleControllerTests extends Specification { mockMvc.perform(put('/api/custom/entity/bundles').contentType(APPLICATION_JSON).content(objectMapper.writeValueAsString(bundle))) false } catch (NestedServletException expected) { - expected.getCause() instanceof EntityNotFoundException + expected.getCause() instanceof PersistentEntityNotFound } when: "update bundle" diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy index 35bd77ea2..3ffbe12e0 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy @@ -5,7 +5,7 @@ import edu.internet2.tier.shibboleth.admin.ui.AbstractBaseDataJpaTest import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.AssertionConsumerServiceRepresentation import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound import edu.internet2.tier.shibboleth.admin.ui.exception.ForbiddenException import edu.internet2.tier.shibboleth.admin.ui.exception.InvalidPatternMatchException import edu.internet2.tier.shibboleth.admin.ui.exception.ObjectIdExistsException @@ -376,7 +376,7 @@ class EntityDescriptorControllerTests extends AbstractBaseDataJpaTest { mockMvc.perform(get("/api/EntityDescriptor/uuid-1")) } catch (Exception e) { - e instanceof EntityNotFoundException + e instanceof PersistentEntityNotFound } } diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersControllerTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersControllerTests.groovy index 2820533e9..6b54c7a0d 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersControllerTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersControllerTests.groovy @@ -8,7 +8,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.exceptions.MetadataFileNotF import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlChainingMetadataResolver -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound import edu.internet2.tier.shibboleth.admin.ui.exception.ForbiddenException import edu.internet2.tier.shibboleth.admin.ui.exception.InitializationException import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects @@ -107,7 +107,7 @@ class MetadataFiltersControllerTests extends AbstractBaseDataJpaTest { } @Override - MetadataResolver findByResourceId(String resourceId) throws EntityNotFoundException { + MetadataResolver findByResourceId(String resourceId) throws PersistentEntityNotFound { // This won't get called return null } diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesControllerTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesControllerTests.groovy index c5ab4a003..8545362c4 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesControllerTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/ShibPropertiesControllerTests.groovy @@ -4,7 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper import edu.internet2.tier.shibboleth.admin.ui.AbstractBaseDataJpaTest import edu.internet2.tier.shibboleth.admin.ui.domain.shib.properties.ShibPropertySet import edu.internet2.tier.shibboleth.admin.ui.domain.shib.properties.ShibPropertySetting -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound import edu.internet2.tier.shibboleth.admin.ui.exception.ObjectIdExistsException import edu.internet2.tier.shibboleth.admin.ui.repository.ShibPropertySetRepository import edu.internet2.tier.shibboleth.admin.ui.repository.ShibPropertySettingRepository @@ -18,15 +18,11 @@ import spock.lang.Subject import javax.persistence.EntityManager import javax.transaction.Transactional -import static org.hamcrest.CoreMatchers.containsString import static org.springframework.http.MediaType.APPLICATION_JSON import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status @@ -107,7 +103,7 @@ class ShibPropertiesControllerTests extends AbstractBaseDataJpaTest { mockMvc.perform(delete("/api/shib/property/set/010")) } catch (Exception e) { - e instanceof EntityNotFoundException + e instanceof PersistentEntityNotFound } when: @@ -128,7 +124,7 @@ class ShibPropertiesControllerTests extends AbstractBaseDataJpaTest { mockMvc.perform(get("/api/shib/property/set/0101")) } catch (Exception e) { - e instanceof EntityNotFoundException + e instanceof PersistentEntityNotFound } } @@ -194,7 +190,7 @@ class ShibPropertiesControllerTests extends AbstractBaseDataJpaTest { mockMvc.perform(put('/api/shib/property/set/1234').contentType(APPLICATION_JSON).content(jsonBody)) } catch (Exception e) { - e instanceof EntityNotFoundException + e instanceof PersistentEntityNotFound } } diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy index 1635ed35f..1615a81ee 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy @@ -122,10 +122,9 @@ class EntityDescriptorRepositoryTest extends AbstractBaseDataJpaTest { @Bean CustomEntityAttributesDefinitionServiceImpl customEntityAttributesDefinitionServiceImpl(EntityManager entityManager, CustomEntityAttributeDefinitionRepository customEntityAttributeDefinitionRepository) { new CustomEntityAttributesDefinitionServiceImpl().with { - it.entityManager = entityManager it.repository = customEntityAttributeDefinitionRepository return it } } } -} +} \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupsControllerIntegrationTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupsControllerIntegrationTests.groovy index c4a76e832..bb4613f6b 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupsControllerIntegrationTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupsControllerIntegrationTests.groovy @@ -1,14 +1,13 @@ package edu.internet2.tier.shibboleth.admin.ui.security.controller import edu.internet2.tier.shibboleth.admin.ui.AbstractBaseDataJpaTest -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupDeleteException import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupExistsConflictException import edu.internet2.tier.shibboleth.admin.ui.security.model.Group import edu.internet2.tier.shibboleth.admin.ui.security.model.Role import edu.internet2.tier.shibboleth.admin.ui.security.model.User import edu.internet2.tier.shibboleth.admin.ui.security.repository.GroupsRepository -import edu.internet2.tier.shibboleth.admin.ui.security.service.IGroupService import edu.internet2.tier.shibboleth.admin.ui.util.WithMockAdmin import groovy.json.JsonOutput import org.springframework.beans.factory.annotation.Autowired @@ -117,7 +116,7 @@ class GroupsControllerIntegrationTests extends AbstractBaseDataJpaTest { .accept(MediaType.APPLICATION_JSON)) false } catch (Throwable expected) { - expected instanceof EntityNotFoundException + expected instanceof PersistentEntityNotFound } } @@ -158,7 +157,7 @@ class GroupsControllerIntegrationTests extends AbstractBaseDataJpaTest { mockMvc.perform(get("$RESOURCE_URI/CCC")) false } catch (Throwable expected) { - expected instanceof EntityNotFoundException + expected instanceof PersistentEntityNotFound } } From 378749f9af90e75b4ad2880a99e42c894384bcb1 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 8 Sep 2022 10:57:51 -0700 Subject: [PATCH 51/71] Added validation for number --- ui/src/app/admin/component/ConfigurationForm.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ui/src/app/admin/component/ConfigurationForm.js b/ui/src/app/admin/component/ConfigurationForm.js index 747a70452..d6029481b 100644 --- a/ui/src/app/admin/component/ConfigurationForm.js +++ b/ui/src/app/admin/component/ConfigurationForm.js @@ -159,7 +159,9 @@ export function ConfigurationForm({ configurations, configuration = {}, loading, + {...register(`properties.${idx}.propertyValue`, { + valueAsNumber: p.displayType === 'number' + })} /> : Date: Thu, 8 Sep 2022 11:08:36 -0700 Subject: [PATCH 52/71] Updated validation to only allow integers for numbers --- ui/src/app/admin/component/ConfigurationForm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/app/admin/component/ConfigurationForm.js b/ui/src/app/admin/component/ConfigurationForm.js index d6029481b..a1560ce42 100644 --- a/ui/src/app/admin/component/ConfigurationForm.js +++ b/ui/src/app/admin/component/ConfigurationForm.js @@ -160,7 +160,7 @@ export function ConfigurationForm({ configurations, configuration = {}, loading, type={p.displayType === 'number' ? 'number' : 'text'} placeholder="value" {...register(`properties.${idx}.propertyValue`, { - valueAsNumber: p.displayType === 'number' + setValueAs: v => (p.displayType === 'number' ? parseInt(v) : v), })} /> : From 71b0a04b49704fe370195e41f676288b23a6efe0 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 8 Sep 2022 11:12:34 -0700 Subject: [PATCH 53/71] Added text displaytype change --- ui/src/app/admin/component/ConfigurationForm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/app/admin/component/ConfigurationForm.js b/ui/src/app/admin/component/ConfigurationForm.js index a1560ce42..bceac7a42 100644 --- a/ui/src/app/admin/component/ConfigurationForm.js +++ b/ui/src/app/admin/component/ConfigurationForm.js @@ -150,7 +150,7 @@ export function ConfigurationForm({ configurations, configuration = {}, loading, { p.propertyName } { p.category } - { p.displayType } + { p.displayType === 'number' ? 'integer' : p.displayType } {p.displayType !== 'boolean' ? Date: Thu, 8 Sep 2022 12:40:29 -0700 Subject: [PATCH 54/71] SHIBUI-2270 Bug fix for ints when no value present --- .../properties/ShibPropertySettingJacksonSerializer.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/shib/properties/ShibPropertySettingJacksonSerializer.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/shib/properties/ShibPropertySettingJacksonSerializer.java index 6bd5b926c..c625c9acb 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/shib/properties/ShibPropertySettingJacksonSerializer.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/shib/properties/ShibPropertySettingJacksonSerializer.java @@ -31,7 +31,11 @@ public void serialize(ShibPropertySetting sps, JsonGenerator generator, Serializ generator.writeBooleanField("propertyValue", Boolean.valueOf(sps.getPropertyValue())); break; case "number": - generator.writeNumberField("propertyValue", Long.parseLong(sps.getPropertyValue())); + try { + generator.writeNumberField("propertyValue", Long.parseLong(sps.getPropertyValue())); + } catch (NumberFormatException notANumber) { + generator.writeStringField("propertyValue", sps.getPropertyValue()); + } break; default: generator.writeStringField("propertyValue", sps.getPropertyValue()); From b5fba267abc86751bbc16c3259db113fa5c60790 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Thu, 8 Sep 2022 13:43:19 -0700 Subject: [PATCH 55/71] SHIBUI-2364 GET ALL for multiple EntityDescriptors doesn't fetch EVERYTHING --- .../EntityDescriptorController.java | 2 +- .../EntityDescriptorProjection.java | 19 +++++++++++++++++++ .../EntityDescriptorRepository.java | 5 ++++- .../ui/repository/ProjectionIdAndName.java | 3 ++- .../ui/service/EntityDescriptorService.java | 7 ++++--- .../JPAEntityDescriptorServiceImpl.java | 11 ++++++----- 6 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorProjection.java diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java index f7cfb019a..065e4d9e3 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java @@ -83,7 +83,7 @@ public ResponseEntity deleteOne(@PathVariable String resourceId) throws Forbi @GetMapping("/EntityDescriptors") @Transactional public ResponseEntity getAll() throws ForbiddenException { - return ResponseEntity.ok(entityDescriptorService.getAllRepresentationsBasedOnUserAccess()); + return ResponseEntity.ok(entityDescriptorService.getAllEntityDescriptorProjectionsBasedOnUserAccess()); } @GetMapping("/EntityDescriptor/{resourceId}/Versions") diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorProjection.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorProjection.java new file mode 100644 index 000000000..57cf02ab9 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorProjection.java @@ -0,0 +1,19 @@ +package edu.internet2.tier.shibboleth.admin.ui.repository; + +import java.time.LocalDateTime; + +public interface EntityDescriptorProjection { + default String getId() { + return getResourceId(); + } + String getEntityID(); + default String getEntityId() { + return getEntityID(); + } + String getResourceId(); + String getServiceProviderName(); + String getCreatedBy(); + LocalDateTime getCreatedDate(); + boolean getServiceEnabled(); + String getIdOfOwner(); +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepository.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepository.java index 5e28e7d75..bb2b275d6 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepository.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepository.java @@ -12,6 +12,9 @@ * Repository to manage {@link EntityDescriptor} instances. */ public interface EntityDescriptorRepository extends JpaRepository { + List findAllBy(); + + List findAllByIdOfOwner(String ownerId); EntityDescriptor findByEntityID(String entityId); @@ -34,4 +37,4 @@ public interface EntityDescriptorRepository extends JpaRepository findAllByIdOfOwnerIsNull(); -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/ProjectionIdAndName.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/ProjectionIdAndName.java index 6731aea86..fca5ae8cd 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/ProjectionIdAndName.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/ProjectionIdAndName.java @@ -1,6 +1,7 @@ package edu.internet2.tier.shibboleth.admin.ui.repository; -public interface ProjectionIdAndName{ +public interface ProjectionIdAndName { String getResourceId(); + String getName(); } \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java index 6d66732b0..a5440b7fa 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java @@ -3,10 +3,11 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.Attribute; import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor; import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation; -import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.exception.ForbiddenException; import edu.internet2.tier.shibboleth.admin.ui.exception.InvalidPatternMatchException; import edu.internet2.tier.shibboleth.admin.ui.exception.ObjectIdExistsException; +import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; +import edu.internet2.tier.shibboleth.admin.ui.repository.EntityDescriptorProjection; import java.util.ConcurrentModificationException; import java.util.List; @@ -67,9 +68,9 @@ EntityDescriptorRepresentation createNew(EntityDescriptorRepresentation edRepres Iterable getAllDisabledAndNotOwnedByAdmin() throws ForbiddenException; /** - * @return a list of EntityDescriptorRepresentations that a user has the rights to access + * @return a list of EntityDescriptorProjections that a user has the rights to access */ - List getAllRepresentationsBasedOnUserAccess() throws ForbiddenException; + List getAllEntityDescriptorProjectionsBasedOnUserAccess() throws ForbiddenException; /** * Given a list of attributes, generate an AttributeReleaseList diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java index 6269020e8..441fa52af 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java @@ -21,6 +21,7 @@ import edu.internet2.tier.shibboleth.admin.ui.exception.InvalidPatternMatchException; import edu.internet2.tier.shibboleth.admin.ui.exception.ObjectIdExistsException; import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects; +import edu.internet2.tier.shibboleth.admin.ui.repository.EntityDescriptorProjection; import edu.internet2.tier.shibboleth.admin.ui.repository.EntityDescriptorRepository; import edu.internet2.tier.shibboleth.admin.ui.security.model.Group; import edu.internet2.tier.shibboleth.admin.ui.security.model.Owner; @@ -373,16 +374,16 @@ public Iterable getAllDisabledAndNotOwnedByAdmin } @Override - public List getAllRepresentationsBasedOnUserAccess() throws ForbiddenException { + public List getAllEntityDescriptorProjectionsBasedOnUserAccess() throws ForbiddenException { switch (userService.getCurrentUserAccess()) { case ADMIN: - return entityDescriptorRepository.findAllStreamByCustomQuery().map(ed -> createRepresentationFromDescriptor(ed)) - .collect(Collectors.toList()); + List o = entityDescriptorRepository.findAllBy();//.map(edProjection -> createRepresentationFromDescriptor(edProjection)).collect(Collectors.toList()); + return o; case GROUP: User user = userService.getCurrentUser(); Group group = user.getGroup(); - return entityDescriptorRepository.findAllStreamByIdOfOwner(group.getOwnerId()) - .map(ed -> createRepresentationFromDescriptor(ed)).collect(Collectors.toList()); + List ed = entityDescriptorRepository.findAllByIdOfOwner(group.getOwnerId());//.map(ed -> createRepresentationFromDescriptor(ed)).collect(Collectors.toList()); + return ed; default: throw new ForbiddenException(); } From f443fd962bb503b547403eca9a53c931838965d7 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Thu, 8 Sep 2022 13:49:05 -0700 Subject: [PATCH 56/71] SHIBUI-2364 code cleanup --- .../admin/ui/service/JPAEntityDescriptorServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java index 441fa52af..55cf3e016 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java @@ -377,12 +377,12 @@ public Iterable getAllDisabledAndNotOwnedByAdmin public List getAllEntityDescriptorProjectionsBasedOnUserAccess() throws ForbiddenException { switch (userService.getCurrentUserAccess()) { case ADMIN: - List o = entityDescriptorRepository.findAllBy();//.map(edProjection -> createRepresentationFromDescriptor(edProjection)).collect(Collectors.toList()); + List o = entityDescriptorRepository.findAllBy(); return o; case GROUP: User user = userService.getCurrentUser(); Group group = user.getGroup(); - List ed = entityDescriptorRepository.findAllByIdOfOwner(group.getOwnerId());//.map(ed -> createRepresentationFromDescriptor(ed)).collect(Collectors.toList()); + List ed = entityDescriptorRepository.findAllByIdOfOwner(group.getOwnerId()); return ed; default: throw new ForbiddenException(); From 1218e33407fc778d0a042e8315a7c9455b78a324 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 8 Sep 2022 15:24:34 -0700 Subject: [PATCH 57/71] Added spinner --- ui/src/app/core/components/Spinner.js | 4 +-- ui/src/app/metadata/hoc/MetadataSelector.js | 28 +++++++++++++++------ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/ui/src/app/core/components/Spinner.js b/ui/src/app/core/components/Spinner.js index 880f53d2a..c137bb9ac 100644 --- a/ui/src/app/core/components/Spinner.js +++ b/ui/src/app/core/components/Spinner.js @@ -2,8 +2,8 @@ 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 function Spinner (props) { + return () } export default Spinner; \ No newline at end of file diff --git a/ui/src/app/metadata/hoc/MetadataSelector.js b/ui/src/app/metadata/hoc/MetadataSelector.js index b81db74b2..54a49d4df 100644 --- a/ui/src/app/metadata/hoc/MetadataSelector.js +++ b/ui/src/app/metadata/hoc/MetadataSelector.js @@ -1,5 +1,6 @@ import React from 'react'; import { useLocation, useParams } from 'react-router'; +import Spinner from '../../core/components/Spinner'; import { useMetadataEntity } from '../hooks/api'; export const MetadataTypeContext = React.createContext(); @@ -10,6 +11,7 @@ export const MetadataLoaderContext = React.createContext(); export function MetadataSelector({ children, ...props }) { let { type, id } = useParams(); + const [loading, setLoading] = React.useState(false); const location = useLocation(); if (!type) { @@ -30,25 +32,35 @@ export function MetadataSelector({ children, ...props }) { const source = await get(`/${id}`); if (response.ok) { setMetadata(source); + setLoading(false); } } function reload() { + setLoading(true); loadMetadata(id); + } React.useEffect(() => reload(), [id]); return ( - - {type && - - {metadata && metadata.version && - {children(metadata, reload)} + + {loading &&
+ +
} + + {type && + + {metadata && metadata.version && + + {children(metadata, reload)} + + } + } -
- } -
+ + ); } From f6c033119e468148ab2bf71417b5bc76da9202e8 Mon Sep 17 00:00:00 2001 From: Charles Hasegawa Date: Thu, 8 Sep 2022 22:57:13 +0000 Subject: [PATCH 58/71] README.md edited online with Bitbucket --- bulk-upload/README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/bulk-upload/README.md b/bulk-upload/README.md index c436394e8..23462d5ca 100644 --- a/bulk-upload/README.md +++ b/bulk-upload/README.md @@ -1,8 +1,12 @@ This script can be used to bulk upload metadata files into the Shibboleth IdP UI ### requirements ### -The shibui must be configured without SAML authentication enabled. The API is currently only accessible using Basic auth. -If shibui is using SAML auth, you can temporarily disable it by setting pac4j-enabled: false in application.yml and restarting shibui. +Docker engine - the run script will launch a Docker container which will handle the process. +OR +Bash shell with Perl (and additional Perl libraries - see below). + +The Shib-UI must be configured *without* SAML authentication enabled. The needed API is currently only accessible using Basic auth. If you are using SAML auth, you can return to using it after the bulk upload process is run. +If Shib-UI is using SAML auth, you can temporarily disable it by setting pac4j-enabled: false in application.yml and restarting shibui. After uploading you can re-enable SAML auth by setting pac4j-enabled: true in application.yml and restarting shibui. ### usage ### @@ -34,7 +38,7 @@ attr[0][Value] = false ### docker image ### run.sh will pull the shibui-bulk-upload image from dockerhub and run the script within -If you need to build the image yourself, `cd docker-build;docker build -t unicon/shibui-bulk-upload .` +If you prefer to build the image yourself, `cd docker-build;docker build -t unicon/shibui-bulk-upload .` ### running without docker ### The docker-build/shibui-md-upload.pl script can be run manually. From c5e69500e6e810d0e563f869e5ac174bf229d85a Mon Sep 17 00:00:00 2001 From: Sean Porth Date: Fri, 9 Sep 2022 11:56:09 -0400 Subject: [PATCH 59/71] shibui-2341 fix SQL --- backend/src/main/resources/db/changelog/changelog.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/main/resources/db/changelog/changelog.sql b/backend/src/main/resources/db/changelog/changelog.sql index f1494b2ca..af15ca6b8 100644 --- a/backend/src/main/resources/db/changelog/changelog.sql +++ b/backend/src/main/resources/db/changelog/changelog.sql @@ -184,7 +184,7 @@ update resource_backed_metadata_resolver_aud set max_refresh_delay ='PT4H'; ALTER TABLE description ALTER COLUMN descriptionValue LONGTEXT; GO -ALTER TABLE description)aud ALTER COLUMN descriptionValue LONGTEXT; +ALTER TABLE description_aud ALTER COLUMN descriptionValue LONGTEXT; GO -- changeset liquibase:1.13.0.2 dbms:postgresql,mssql @@ -192,7 +192,7 @@ GO -- 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 description ALTER COLUMN descriptionValue TEXT; +ALTER TABLE description ALTER COLUMN descriptionValue TYPE TEXT; GO -ALTER TABLE description_aud ALTER COLUMN descriptionValue TEXT; +ALTER TABLE description_aud ALTER COLUMN descriptionValue TYPE TEXT; GO \ No newline at end of file From df26265f48e871ec4cb410c266b05e4dc537fb15 Mon Sep 17 00:00:00 2001 From: Sean Porth Date: Fri, 9 Sep 2022 12:16:51 -0400 Subject: [PATCH 60/71] shibui-2341 exit upload if api is inaccessible --- bulk-upload/docker-build/shibui-md-upload.pl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bulk-upload/docker-build/shibui-md-upload.pl b/bulk-upload/docker-build/shibui-md-upload.pl index 3aae45aa8..160559c6d 100755 --- a/bulk-upload/docker-build/shibui-md-upload.pl +++ b/bulk-upload/docker-build/shibui-md-upload.pl @@ -41,6 +41,11 @@ #create auth token $client->HEAD('/'); + +my $code = $client->responseCode(); +my $res = $client->responseContent(); +die "$res\n" if ($code != 302 && $code != 200); + my $token = &get_cookie_value($cookies, 'XSRF-TOKEN'); $client->addHeader('X-XSRF-TOKEN', $token); ## From 132562d6e79262577cb34b682c3c2c7788ae961f Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 9 Sep 2022 13:49:34 -0700 Subject: [PATCH 61/71] SHIBUI-2364 code cleanup --- .../ui/controller/EntityDescriptorController.java | 11 +++++++++-- .../admin/ui/service/EntityDescriptorService.java | 2 ++ .../ui/service/JPAEntityDescriptorServiceImpl.java | 8 ++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java index 065e4d9e3..9952e8842 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java @@ -145,13 +145,20 @@ public void initRestTemplate() { @PutMapping("/EntityDescriptor/{resourceId}") @Transactional public ResponseEntity update(@RequestBody EntityDescriptorRepresentation edRepresentation, @PathVariable String resourceId) - throws ForbiddenException, ConcurrentModificationException, PersistentEntityNotFound, - InvalidPatternMatchException { + throws ForbiddenException, ConcurrentModificationException, PersistentEntityNotFound, InvalidPatternMatchException { edRepresentation.setId(resourceId); // This should be the same already, but just to be safe... EntityDescriptorRepresentation result = entityDescriptorService.update(edRepresentation); return ResponseEntity.ok().body(result); } + @PutMapping("/EntityDescriptor/{resourceId}/changeGroup/{groupId}") + @Transactional + public ResponseEntity updateGroupForEntityDescriptor(@PathVariable String resourceId, String groupId) + throws ForbiddenException, ConcurrentModificationException, PersistentEntityNotFound, InvalidPatternMatchException { + EntityDescriptorRepresentation result = entityDescriptorService.updateGroupForEntityDescriptor(resourceId, groupId); + return ResponseEntity.ok().body(result); + } + @PostMapping(value = "/EntityDescriptor", consumes = "application/xml") @Transactional public ResponseEntity upload(@RequestBody byte[] entityDescriptorXml, @RequestParam String spName) throws Exception { diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java index a5440b7fa..fa8fc62f8 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java @@ -120,4 +120,6 @@ EntityDescriptorRepresentation updateEntityDescriptorEnabledStatus(String resour EntityDescriptorRepresentation createNewEntityDescriptorFromXMLOrigin(EntityDescriptor ed); boolean entityExists(String entityID); + + EntityDescriptorRepresentation updateGroupForEntityDescriptor(String resourceId, String groupId); } \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java index 55cf3e016..291f659f8 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java @@ -119,6 +119,14 @@ public boolean entityExists(String entityID) { return entityDescriptorRepository.findByEntityID(entityID) != null ; } + @Override + public EntityDescriptorRepresentation updateGroupForEntityDescriptor(String resourceId, String groupId) { + EntityDescriptor ed = entityDescriptorRepository.findByResourceId(resourceId); + ed.setIdOfOwner(groupId); + EntityDescriptor savedEntity = entityDescriptorRepository.save(ed); + return createRepresentationFromDescriptor(savedEntity); + } + @Override public EntityDescriptorRepresentation createNew(EntityDescriptorRepresentation edRep) throws ForbiddenException, ObjectIdExistsException, InvalidPatternMatchException { From 4638b29f18523f2d6e209418aad649d6b52a3d27 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Fri, 9 Sep 2022 14:32:14 -0700 Subject: [PATCH 62/71] Implemented fix for group change and copy change --- ui/src/app/dashboard/view/SourcesTab.js | 2 +- ui/src/app/metadata/copy/CopySource.js | 30 +++++++++------ ui/src/app/metadata/copy/EntityTypeahead.js | 42 ++++++++++++++++----- 3 files changed, 52 insertions(+), 22 deletions(-) diff --git a/ui/src/app/dashboard/view/SourcesTab.js b/ui/src/app/dashboard/view/SourcesTab.js index 40ff4dd4f..b0d1352d3 100644 --- a/ui/src/app/dashboard/view/SourcesTab.js +++ b/ui/src/app/dashboard/view/SourcesTab.js @@ -37,7 +37,7 @@ export function SourcesTab () { React.useEffect(() => { loadSources() }, []); async function changeSourceGroup(source, group) { - await updater.put(`/${source.id}`, { + await updater.put(`/${source.id}/changeGroup/${group}`, { ...source, idOfOwner: group }); diff --git a/ui/src/app/metadata/copy/CopySource.js b/ui/src/app/metadata/copy/CopySource.js index f3ae6b142..d7d0be54a 100644 --- a/ui/src/app/metadata/copy/CopySource.js +++ b/ui/src/app/metadata/copy/CopySource.js @@ -34,7 +34,7 @@ export function CopySource({ copy, onNext }) { setSelected([]); }; - const { register, handleSubmit, control, formState, setValue, getValues } = useForm({ + const { register, handleSubmit, control, formState, setValue, getValues, watch } = useForm({ mode: 'onChange', reValidateMode: 'onBlur', defaultValues: { @@ -47,6 +47,8 @@ export function CopySource({ copy, onNext }) { shouldUnregister: false, }); + const target = watch('target'); + const { errors, isValid } = formState; React.useEffect(() => { @@ -92,25 +94,28 @@ export function CopySource({ copy, onNext }) {
- - - Select the Entity ID to copy - - - + + + + Select the Entity ID to copy + + + Entity ID to copy is Required - + + Metadata Source Name (Dashboard Display Only) - + + + aria-describedby="serviceProviderName-help" disabled={!target} /> Service Resolver Name is required @@ -118,12 +123,15 @@ export function CopySource({ copy, onNext }) { + New Entity ID - + + !(sourceIds.indexOf(v) > -1) diff --git a/ui/src/app/metadata/copy/EntityTypeahead.js b/ui/src/app/metadata/copy/EntityTypeahead.js index ed8b9a14e..716089039 100644 --- a/ui/src/app/metadata/copy/EntityTypeahead.js +++ b/ui/src/app/metadata/copy/EntityTypeahead.js @@ -1,10 +1,16 @@ +import { faSpinner } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import React from 'react'; import { Typeahead } from 'react-bootstrap-typeahead'; import { useController } from 'react-hook-form'; -import { useMetadataSources } from '../hooks/api'; +import { useMetadataEntity, useMetadataSources } from '../hooks/api'; +import Form from 'react-bootstrap/Form'; -export function EntityTypeahead ({id, control, name}) { +export function EntityTypeahead ({id, control, name, children}) { const { data = [] } = useMetadataSources({}, []); + + const { get, response, loading } = useMetadataEntity(); + const entities = React.useMemo(() => data.map(d => d.entityId), [data]); const { @@ -18,14 +24,30 @@ export function EntityTypeahead ({id, control, name}) { defaultValue: "", }); + const loadSelected = async (selected) => { + const toCopy = data.find(e => e.entityId === selected); + + const source = await get(`/${toCopy.id}`); + if (response.ok) { + onChange(source); + } + // + } + return ( - onChange(selected ? data.find(e => e.entityId === selected[0]) : '')} - defaultInputValue={value ? value.entityId : ''} - options={entities} - required={true} - id={id} - /> + + + {children} + {loading && } + + selected && selected.length > 0 ? loadSelected(selected[0]) : null} + defaultInputValue={value ? value.entityId : ''} + options={entities} + required={true} + id={id} + /> + ) } \ No newline at end of file From c326dbe8bcff8db39dccd0a47c1258e37f94e2b1 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 9 Sep 2022 16:03:36 -0700 Subject: [PATCH 63/71] SHIBUI-2364 fixes to group --- .../admin/ui/controller/EntityDescriptorController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java index 9952e8842..e57870cb9 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java @@ -153,7 +153,7 @@ public ResponseEntity update(@RequestBody EntityDescriptorRepresentation edRe @PutMapping("/EntityDescriptor/{resourceId}/changeGroup/{groupId}") @Transactional - public ResponseEntity updateGroupForEntityDescriptor(@PathVariable String resourceId, String groupId) + public ResponseEntity updateGroupForEntityDescriptor(@PathVariable String resourceId, @PathVariable String groupId) throws ForbiddenException, ConcurrentModificationException, PersistentEntityNotFound, InvalidPatternMatchException { EntityDescriptorRepresentation result = entityDescriptorService.updateGroupForEntityDescriptor(resourceId, groupId); return ResponseEntity.ok().body(result); From 1e0b19a807e1540d2afb5bc3c1d5aea8acdad3cd Mon Sep 17 00:00:00 2001 From: Sean Porth Date: Mon, 12 Sep 2022 13:38:40 -0400 Subject: [PATCH 64/71] shibui-2341 better url encoding, utf8 encoding of names --- bulk-upload/README.md | 2 +- bulk-upload/docker-build/Dockerfile | 2 +- bulk-upload/docker-build/shibui-md-upload.pl | 14 +++++++++----- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/bulk-upload/README.md b/bulk-upload/README.md index 23462d5ca..02196fba9 100644 --- a/bulk-upload/README.md +++ b/bulk-upload/README.md @@ -42,6 +42,6 @@ If you prefer to build the image yourself, `cd docker-build;docker build -t unic ### running without docker ### The docker-build/shibui-md-upload.pl script can be run manually. -Depending on OS you may need to install some additional non dist Perl modules. REST::Client , XML::LibXML , JSON , Config::File +Depending on OS you may need to install some additional non dist Perl modules. REST::Client , XML::LibXML , JSON , Config::File , URI::Encode `perl shibui-md-upload.pl -c -m -e (enable metadata source after upload)` diff --git a/bulk-upload/docker-build/Dockerfile b/bulk-upload/docker-build/Dockerfile index dd7384667..8c1efcba9 100644 --- a/bulk-upload/docker-build/Dockerfile +++ b/bulk-upload/docker-build/Dockerfile @@ -3,7 +3,7 @@ MAINTAINER sporth@unicon.net RUN apt-get clean \ && apt-get -y update \ - && apt-get install -y librest-client-perl libconfig-file-perl jq libxml-libxml-perl libjson-perl + && apt-get install -y librest-client-perl libconfig-file-perl jq libxml-libxml-perl libjson-perl liburi-encode-perl WORKDIR /opt COPY shibui-md-upload.pl /opt/shibui-md-upload.pl diff --git a/bulk-upload/docker-build/shibui-md-upload.pl b/bulk-upload/docker-build/shibui-md-upload.pl index 160559c6d..4f24334e3 100755 --- a/bulk-upload/docker-build/shibui-md-upload.pl +++ b/bulk-upload/docker-build/shibui-md-upload.pl @@ -12,6 +12,7 @@ use XML::LibXML::XPathContext; use Encode; use JSON; +use URI::Encode; ##process arguments our ($opt_e,$opt_m,$opt_c); @@ -201,10 +202,13 @@ sub call_api { my $xml = shift; my $enable = shift; my ($params,$code,$result); + my $encoder = URI::Encode->new({encode_reserved => 1}); my $utf8 = encode_utf8($xml); + my $utf8_name = encode_utf8($name); + my $ename = $encoder->encode($name); - $params = "?spName=$name"; + $params = "?spName=$ename"; $params .= "&enableService=true" if ($enable); $client->addHeader('Content-Type', "application/xml; charset='utf8'"); @@ -226,18 +230,18 @@ sub call_api { my $eresult = $client->responseContent(); if ($ecode == 200 || $ecode == 201) { - print "$ecode: entity $name uploaded sucessfully and enabled\n"; + print "$ecode: entity $utf8_name uploaded sucessfully and enabled\n"; } else { - print "$ecode: entity $name uploaded sucessfully but enabling failed:\n"; + print "$ecode: entity $utf8_name uploaded sucessfully but enabling failed:\n"; open(my $pipe, '|-', "jq ."); print $pipe $eresult; } } else { - print "$code: entity $name uploaded sucessfully\n"; + print "$code: entity $utf8_name uploaded sucessfully\n"; } } elsif ($code == 409) { - print "$code: entity $name already exists\n"; + print "$code: entity $utf8_name already exists\n"; } elsif ($code == 500) { print "$code: $result\n"; } else { From fbbbeaacfb77ef807382a3c1556e90d79dd2bf80 Mon Sep 17 00:00:00 2001 From: Charles Hasegawa Date: Mon, 12 Sep 2022 18:43:01 +0000 Subject: [PATCH 65/71] README.md edited online with Bitbucket --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3afd1b078..9f31bc7e4 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,11 @@ ## Running -There are currently 2 ways to run the application: +There are currently 3 ways to run the application: 1. As an executable WAR using Java -1. deployed in a Java Servlet 3.0 container such as Tomcat or Jetty +1. Deployed in a Java Servlet 3.0 container such as Tomcat or Jetty +1. Via Docker container - see instructions at https://spaces.at.internet2.edu/display/SMMU/Shibboleth+IdP+UI+Deployment+Instructions Note that some features require encoded slashes in the URL. In tomcat (which is embedded in the war), this can be allowed with: From f55bf87d9e79b565af073c2a59e64c3b3fe6fc55 Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Tue, 13 Sep 2022 12:23:43 -0400 Subject: [PATCH 66/71] NOJIRA Fixed a text compare and what looked to be a race condition --- .../integration/resources/SHIBUI-2268.side | 22 +++++++------------ .../integration/resources/SHIBUI-2270-2.side | 7 ++++++ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/backend/src/integration/resources/SHIBUI-2268.side b/backend/src/integration/resources/SHIBUI-2268.side index a9533b8c8..0dc9a83dd 100644 --- a/backend/src/integration/resources/SHIBUI-2268.side +++ b/backend/src/integration/resources/SHIBUI-2268.side @@ -948,24 +948,18 @@ ["xpath=//div[4]/div/div/div[3]/button", "xpath:position"] ], "value": "" - }, { - "id": "6cd2789b-4ec1-4153-8d4e-fb896a1b0e5e", - "comment": "", - "command": "click", - "target": "css=.align-items-end", - "targets": [ - ["css=.align-items-end", "css:finder"], - ["xpath=//div[@id='root']/div/footer/div/div[2]/div", "xpath:idRelative"], - ["xpath=//footer/div/div[2]/div", "xpath:position"] - ], - "value": "" }, { "id": "b9432398-233d-4872-8b56-9aa8fd48ca85", "comment": "", "command": "assertText", - "target": "css=.alert", - "targets": [], - "value": "No FiltersNo filters have been added to this Metadata Provider" + "target": "css=.alert > p", + "targets": [ + ["css=.alert > p", "css:finder"], + ["xpath=//div[@id='filters']/div[2]/p", "xpath:idRelative"], + ["xpath=//section/div/div/div[3]/div[2]/p", "xpath:position"], + ["xpath=//p[contains(.,'No filters have been added to this Metadata Provider')]", "xpath:innerText"] + ], + "value": "No filters have been added to this Metadata Provider" }, { "id": "3543733a-3e14-4f07-9aaa-e29a26fe36b1", "comment": "", diff --git a/backend/src/integration/resources/SHIBUI-2270-2.side b/backend/src/integration/resources/SHIBUI-2270-2.side index 2872ad331..9f1c37d7a 100644 --- a/backend/src/integration/resources/SHIBUI-2270-2.side +++ b/backend/src/integration/resources/SHIBUI-2270-2.side @@ -2114,6 +2114,13 @@ ["xpath=//div[4]/div/div/div[3]/button", "xpath:position"] ], "value": "" + }, { + "id": "d7643f3c-f387-4404-8f8b-e73ebfeb0754", + "comment": "", + "command": "pause", + "target": "5000", + "targets": [], + "value": "" }, { "id": "efc6da0e-490c-4c8b-b4d2-07b71059d0ef", "comment": "", From c8e821db9457713c30918dc16a35c34cfc5b9da4 Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Tue, 13 Sep 2022 13:15:29 -0400 Subject: [PATCH 67/71] NOJIRA Small change to attempt to add test stability. --- backend/src/integration/resources/SHIBUI-1732-1.side | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/backend/src/integration/resources/SHIBUI-1732-1.side b/backend/src/integration/resources/SHIBUI-1732-1.side index 5c1d1daec..5ed256172 100644 --- a/backend/src/integration/resources/SHIBUI-1732-1.side +++ b/backend/src/integration/resources/SHIBUI-1732-1.side @@ -630,6 +630,13 @@ ["xpath=//li[3]/button", "xpath:position"] ], "value": "" + }, { + "id": "97d81369-bb35-4f59-b838-ef69e253fc21", + "comment": "", + "command": "waitForElementEditable", + "target": "id=root_xmlId", + "targets": [], + "value": "30000" }, { "id": "14f9bdcf-a54a-4f3b-9c4a-e4e9e94647ba", "comment": "", From 2b5f052dea49ec4781927b020fe872cc3518d9bf Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Tue, 13 Sep 2022 14:29:43 -0400 Subject: [PATCH 68/71] NOJIRA Further attempts at stabilizing tests. --- .../integration/resources/SHIBUI-1407-1.side | 7 ++ .../integration/resources/SHIBUI-2270-2.side | 119 ++---------------- 2 files changed, 16 insertions(+), 110 deletions(-) diff --git a/backend/src/integration/resources/SHIBUI-1407-1.side b/backend/src/integration/resources/SHIBUI-1407-1.side index 46d1c6fa1..dea518e4a 100644 --- a/backend/src/integration/resources/SHIBUI-1407-1.side +++ b/backend/src/integration/resources/SHIBUI-1407-1.side @@ -2415,6 +2415,13 @@ ["xpath=//button[contains(.,'Compare Selected(2)')]", "xpath:innerText"] ], "value": "" + }, { + "id": "4dbf4b6f-7de9-49e1-a23f-ff748f5a986b", + "comment": "", + "command": "pause", + "target": "3000", + "targets": [], + "value": "" }, { "id": "978829e9-fa70-4548-9a55-0e2ffa0df9a4", "comment": "", diff --git a/backend/src/integration/resources/SHIBUI-2270-2.side b/backend/src/integration/resources/SHIBUI-2270-2.side index 9f1c37d7a..9a645405f 100644 --- a/backend/src/integration/resources/SHIBUI-2270-2.side +++ b/backend/src/integration/resources/SHIBUI-2270-2.side @@ -674,7 +674,7 @@ "id": "3aedee37-3445-4679-afe8-62e53b348e52", "comment": "", "command": "click", - "target": "css=.fa-caret-down > path", + "target": "css=.fa-caret-down", "targets": [ ["css=.fa-caret-down > path", "css:finder"] ], @@ -1185,30 +1185,6 @@ ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] ], "value": "" - }, { - "id": "185cd9b2-0f1b-4f64-a4a5-b62f5a881d45", - "comment": "", - "command": "click", - "target": "css=.p-3", - "targets": [ - ["css=.p-3", "css:finder"], - ["xpath=//div[@id='root']/div/main/div", "xpath:idRelative"], - ["xpath=//main/div", "xpath:position"] - ], - "value": "" - }, { - "id": "2a295dc3-422a-436e-8450-03dbcc88a1b0", - "comment": "", - "command": "click", - "target": "css=.toggle-button", - "targets": [ - ["css=.toggle-button", "css:finder"], - ["xpath=(//button[@type='button'])[44]", "xpath:attributes"], - ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], - ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], - ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] - ], - "value": "" }, { "id": "6fdf6ef4-52e8-44a9-8dc5-8126e2ba11b0", "comment": "", @@ -1665,7 +1641,7 @@ "id": "5bf0b70b-e413-49eb-bfcb-f97a4265c70b", "comment": "", "command": "click", - "target": "css=.fa-caret-down > path", + "target": "css=.fa-caret-down", "targets": [ ["css=.fa-caret-down > path", "css:finder"] ], @@ -1699,26 +1675,6 @@ ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] ], "value": "" - }, { - "id": "cd98777e-1800-417f-af35-9f6d531decfa", - "comment": "", - "command": "click", - "target": "css=form", - "targets": [ - ["css=form", "css:finder"], - ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form", "xpath:idRelative"], - ["xpath=//form", "xpath:position"] - ], - "value": "" - }, { - "id": "2ac41455-f406-4e71-88c0-8c30b7c23eab", - "comment": "", - "command": "click", - "target": "css=.fa-caret-down", - "targets": [ - ["css=.fa-caret-down", "css:finder"] - ], - "value": "" }, { "id": "a729126e-0c39-4db6-882c-b506db087119", "comment": "", @@ -1735,18 +1691,6 @@ ["xpath=//a[contains(.,'Status - Add all')]", "xpath:innerText"] ], "value": "" - }, { - "id": "602156fa-9fed-4a42-9182-4aa66338dd24", - "comment": "", - "command": "click", - "target": "css=td", - "targets": [ - ["css=td", "css:finder"], - ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[4]/div/table/tbody/tr/td", "xpath:idRelative"], - ["xpath=//td", "xpath:position"], - ["xpath=//td[contains(.,'At least one property is required.')]", "xpath:innerText"] - ], - "value": "" }, { "id": "878447bd-6424-440f-8dcf-461f994a6478", "comment": "", @@ -1884,30 +1828,6 @@ ["xpath=//a[contains(.,'X509InternalAuthnConfiguration - Add all')]", "xpath:innerText"] ], "value": "" - }, { - "id": "2a8c3086-a40d-4e9c-857a-7fda2bd2e8f5", - "comment": "", - "command": "click", - "target": "css=.toggle-button", - "targets": [ - ["css=.toggle-button", "css:finder"], - ["xpath=(//button[@type='button'])[68]", "xpath:attributes"], - ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], - ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], - ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] - ], - "value": "" - }, { - "id": "93a9c033-0fcc-4af9-85b5-7e18d882bf68", - "comment": "", - "command": "click", - "target": "css=.col-12 > .d-flex", - "targets": [ - ["css=.col-12 > .d-flex", "css:finder"], - ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div", "xpath:idRelative"], - ["xpath=//form/div[2]/div/div", "xpath:position"] - ], - "value": "" }, { "id": "d06a3e9a-849f-4b8d-83a1-797f8abf6794", "comment": "", @@ -1920,6 +1840,13 @@ ["xpath=//form/div[2]/div/div/button", "xpath:position"] ], "value": "" + }, { + "id": "546b2382-08c5-4360-baaa-1adb84522a76", + "comment": "", + "command": "waitForElementVisible", + "target": "css=tr:nth-child(653) > td:nth-child(1)", + "targets": [], + "value": "30000" }, { "id": "1e726b4f-8ae7-40eb-ba52-747c88ae2e89", "comment": "", @@ -1960,20 +1887,6 @@ ["xpath=//a[contains(.,'  Edit')]", "xpath:innerText"] ], "value": "" - }, { - "id": "caeb6c0b-c99d-4e4f-87b1-874ac54f30a8", - "comment": "", - "command": "click", - "target": "id=valueInput-idp.resolvertest.accessPolicy", - "targets": [ - ["id=valueInput-idp.resolvertest.accessPolicy", "id"], - ["name=properties.0.propertyValue", "name"], - ["css=#valueInput-idp\\.resolvertest\\.accessPolicy", "css:finder"], - ["xpath=//input[@id='valueInput-idp.resolvertest.accessPolicy']", "xpath:attributes"], - ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[4]/div/table/tbody/tr/td[4]/div/input", "xpath:idRelative"], - ["xpath=//td[4]/div/input", "xpath:position"] - ], - "value": "" }, { "id": "812d8a90-f462-470a-9a4d-efd2cca679c2", "comment": "", @@ -1988,20 +1901,6 @@ ["xpath=//td[4]/div/input", "xpath:position"] ], "value": "foo" - }, { - "id": "8c98218b-9d71-42ac-8682-36d2aeb0f39e", - "comment": "", - "command": "click", - "target": "id=valueInput-idp.resolvertest.logging", - "targets": [ - ["id=valueInput-idp.resolvertest.logging", "id"], - ["name=properties.1.propertyValue", "name"], - ["css=#valueInput-idp\\.resolvertest\\.logging", "css:finder"], - ["xpath=//input[@id='valueInput-idp.resolvertest.logging']", "xpath:attributes"], - ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[4]/div/table/tbody/tr[2]/td[4]/div/input", "xpath:idRelative"], - ["xpath=//tr[2]/td[4]/div/input", "xpath:position"] - ], - "value": "" }, { "id": "948ac5c1-aa09-44af-a024-c0dc898616d1", "comment": "", From 71718462447c7bf3ad7b687419bb8c1f96f71872 Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Tue, 13 Sep 2022 14:47:10 -0400 Subject: [PATCH 69/71] NOJIRA Yet another attempt at getting 2270-2 to exhibit consistent passing behavior. --- .../integration/resources/SHIBUI-2270-2.side | 68 +++++++++++++------ 1 file changed, 46 insertions(+), 22 deletions(-) diff --git a/backend/src/integration/resources/SHIBUI-2270-2.side b/backend/src/integration/resources/SHIBUI-2270-2.side index 9a645405f..f8941b4b4 100644 --- a/backend/src/integration/resources/SHIBUI-2270-2.side +++ b/backend/src/integration/resources/SHIBUI-2270-2.side @@ -140,7 +140,7 @@ "id": "3fae037d-0e59-4b9d-adf2-dbd624b72613", "comment": "", "command": "click", - "target": "css=.rbt-input-main", + "target": "css=.toggle-button", "targets": [ ["css=.rbt-input-main", "css:finder"], ["xpath=//input[@value='']", "xpath:attributes"], @@ -168,7 +168,7 @@ "id": "be761931-fb77-4030-bc2c-2577d3a99580", "comment": "", "command": "click", - "target": "css=.rbt-input-main", + "target": "css=.toggle-button", "targets": [ ["css=.rbt-input-main", "css:finder"], ["xpath=//input[@value='']", "xpath:attributes"], @@ -225,7 +225,7 @@ "id": "b1cb5ac9-027c-45f2-b7c2-d1a661378928", "comment": "", "command": "click", - "target": "css=.rbt-input-main", + "target": "css=.toggle-button", "targets": [ ["css=.rbt-input-main", "css:finder"], ["xpath=//input[@value='']", "xpath:attributes"], @@ -253,7 +253,7 @@ "id": "ff91bfaf-f6ce-42c2-9dd4-1c52268d140d", "comment": "", "command": "click", - "target": "css=.fa-caret-down", + "target": "css=.toggle-button", "targets": [ ["css=.fa-caret-down", "css:finder"] ], @@ -307,7 +307,7 @@ "id": "384ea0fc-0bc1-4f63-b736-7e1d67277662", "comment": "", "command": "click", - "target": "css=.rbt-input-main", + "target": "css=.toggle-button", "targets": [ ["css=.rbt-input-main", "css:finder"], ["xpath=//input[@value='']", "xpath:attributes"], @@ -451,7 +451,7 @@ "id": "9f2f0c50-7465-4879-bb68-822bca1f0fa3", "comment": "", "command": "click", - "target": "css=.rbt-input-main", + "target": "css=.toggle-button", "targets": [ ["css=.rbt-input-main", "css:finder"], ["xpath=//input[@value='']", "xpath:attributes"], @@ -479,7 +479,7 @@ "id": "3b326c6f-96d3-4f6c-ba82-e9ffd95517f1", "comment": "", "command": "click", - "target": "css=.fa-caret-down", + "target": "css=.toggle-button", "targets": [ ["css=.fa-caret-down", "css:finder"] ], @@ -562,7 +562,7 @@ "id": "c6bfe838-9027-4c25-990e-e451e9d04a4d", "comment": "", "command": "click", - "target": "css=.fa-caret-down", + "target": "css=.toggle-button", "targets": [ ["css=.fa-caret-down", "css:finder"] ], @@ -674,7 +674,7 @@ "id": "3aedee37-3445-4679-afe8-62e53b348e52", "comment": "", "command": "click", - "target": "css=.fa-caret-down", + "target": "css=.toggle-button", "targets": [ ["css=.fa-caret-down > path", "css:finder"] ], @@ -815,7 +815,7 @@ "id": "6d5dcd3a-0d08-4140-9634-196e2e2fdb90", "comment": "", "command": "click", - "target": "css=.fa-caret-down", + "target": "css=.toggle-button", "targets": [ ["css=.fa-caret-down", "css:finder"] ], @@ -898,7 +898,7 @@ "id": "c06b4caf-e093-49b4-8cac-f71bda476995", "comment": "", "command": "click", - "target": "css=.fa-caret-down", + "target": "css=.toggle-button", "targets": [ ["css=.fa-caret-down", "css:finder"] ], @@ -1097,7 +1097,7 @@ "id": "e8d736c8-be22-4411-87d4-0a1eefcc821e", "comment": "", "command": "click", - "target": "css=.fa-caret-down", + "target": "css=.toggle-button", "targets": [ ["css=.fa-caret-down", "css:finder"] ], @@ -1122,7 +1122,7 @@ "id": "ed236cf8-e185-4b41-a47f-2a9219eab773", "comment": "", "command": "click", - "target": "css=.fa-caret-down", + "target": "css=.toggle-button", "targets": [ ["css=.fa-caret-down", "css:finder"] ], @@ -1205,7 +1205,7 @@ "id": "614f715d-8fcc-4e84-8d0d-dd947fc7c99f", "comment": "", "command": "click", - "target": "css=.fa-caret-down", + "target": "css=.toggle-button", "targets": [ ["css=.fa-caret-down", "css:finder"] ], @@ -1259,7 +1259,7 @@ "id": "b93aed8b-bd95-496a-ad07-b9bfe23f8522", "comment": "", "command": "click", - "target": "css=.fa-caret-down > path", + "target": "css=.toggle-button", "targets": [ ["css=.fa-caret-down > path", "css:finder"] ], @@ -1400,7 +1400,7 @@ "id": "f7c7f42d-b4cb-4f92-997f-d9677a00758f", "comment": "", "command": "click", - "target": "css=.fa-caret-down", + "target": "css=.toggle-button", "targets": [ ["css=.fa-caret-down", "css:finder"] ], @@ -1425,7 +1425,7 @@ "id": "5a3ad5c4-37e2-4060-88bd-ed96b94d037e", "comment": "", "command": "click", - "target": "css=.fa-caret-down", + "target": "css=.toggle-button", "targets": [ ["css=.fa-caret-down", "css:finder"] ], @@ -1533,7 +1533,7 @@ "id": "10926b24-5952-4685-be81-802f5fc7ca4a", "comment": "", "command": "click", - "target": "css=.fa-caret-down", + "target": "css=.toggle-button", "targets": [ ["css=.fa-caret-down", "css:finder"] ], @@ -1558,7 +1558,7 @@ "id": "5558c433-213a-49de-b68d-e6d9ac396b86", "comment": "", "command": "click", - "target": "css=.fa-caret-down", + "target": "css=.toggle-button", "targets": [ ["css=.fa-caret-down", "css:finder"] ], @@ -1641,7 +1641,7 @@ "id": "5bf0b70b-e413-49eb-bfcb-f97a4265c70b", "comment": "", "command": "click", - "target": "css=.fa-caret-down", + "target": "css=.toggle-button", "targets": [ ["css=.fa-caret-down > path", "css:finder"] ], @@ -1724,7 +1724,7 @@ "id": "eca7bf2d-db81-4cad-873b-eba9440bd0e5", "comment": "", "command": "click", - "target": "css=.fa-caret-down", + "target": "css=.toggle-button", "targets": [ ["css=.fa-caret-down", "css:finder"] ], @@ -1807,7 +1807,7 @@ "id": "a11e93fd-5a1b-4456-a875-f0b8a8582058", "comment": "", "command": "click", - "target": "css=.fa-caret-down > path", + "target": "css=.toggle-button", "targets": [ ["css=.fa-caret-down > path", "css:finder"] ], @@ -2013,6 +2013,30 @@ ["xpath=//div[4]/div/div/div[3]/button", "xpath:position"] ], "value": "" + }, { + "id": "f92982ba-8145-490b-999c-ff52ae1ce146", + "comment": "", + "command": "waitForElementVisible", + "target": "css=td", + "targets": [ + ["css=td", "css:finder"], + ["xpath=//div[@id='root']/div/main/div/section/div/div[2]/div[2]/table/tbody/tr/td", "xpath:idRelative"], + ["xpath=//td", "xpath:position"], + ["xpath=//td[contains(.,'No configurations defined.')]", "xpath:innerText"] + ], + "value": "30000" + }, { + "id": "9bc43f09-b4e4-4f98-94d3-d7a9f3fa05c1", + "comment": "", + "command": "assertText", + "target": "css=td", + "targets": [ + ["css=td", "css:finder"], + ["xpath=//div[@id='root']/div/main/div/section/div/div[2]/div[2]/table/tbody/tr/td", "xpath:idRelative"], + ["xpath=//td", "xpath:position"], + ["xpath=//td[contains(.,'No configurations defined.')]", "xpath:innerText"] + ], + "value": "No configurations defined." }, { "id": "d7643f3c-f387-4404-8f8b-e73ebfeb0754", "comment": "", From 1bbf7310a40e5f66f6180432a598be641a8c33ef Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Tue, 13 Sep 2022 14:58:31 -0400 Subject: [PATCH 70/71] NOJIRA More 2270 stability. Maybe. --- .../integration/resources/SHIBUI-2270-2.side | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/backend/src/integration/resources/SHIBUI-2270-2.side b/backend/src/integration/resources/SHIBUI-2270-2.side index f8941b4b4..96995251c 100644 --- a/backend/src/integration/resources/SHIBUI-2270-2.side +++ b/backend/src/integration/resources/SHIBUI-2270-2.side @@ -1887,6 +1887,13 @@ ["xpath=//a[contains(.,'  Edit')]", "xpath:innerText"] ], "value": "" + }, { + "id": "10357b31-6f98-4d85-8d42-1ec5fc4906ca", + "comment": "", + "command": "click", + "target": "id=valueInput-idp.resolvertest.accessPolicy", + "targets": [], + "value": "" }, { "id": "812d8a90-f462-470a-9a4d-efd2cca679c2", "comment": "", @@ -1902,7 +1909,7 @@ ], "value": "foo" }, { - "id": "948ac5c1-aa09-44af-a024-c0dc898616d1", + "id": "2b3f457c-5eb6-4df4-a7f5-3f4856a71cc2", "comment": "", "command": "type", "target": "id=valueInput-idp.resolvertest.logging", @@ -1915,6 +1922,13 @@ ["xpath=//tr[2]/td[4]/div/input", "xpath:position"] ], "value": "bar" + }, { + "id": "948ac5c1-aa09-44af-a024-c0dc898616d1", + "comment": "", + "command": "click", + "target": "id=valueInput-idp.resolvertest.logging", + "targets": [], + "value": "" }, { "id": "46d0e1ac-4706-47cf-9336-683b7b6519f2", "comment": "", @@ -2013,6 +2027,13 @@ ["xpath=//div[4]/div/div/div[3]/button", "xpath:position"] ], "value": "" + }, { + "id": "129a0a85-e23e-447c-b1f0-12587ccd7978", + "comment": "", + "command": "pause", + "target": "5000", + "targets": [], + "value": "" }, { "id": "f92982ba-8145-490b-999c-ff52ae1ce146", "comment": "", From 4f4d21c87c63f6afafe78123441c35239fc8393e Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Tue, 13 Sep 2022 16:30:09 -0400 Subject: [PATCH 71/71] NOJIRA Last attept at stabilizing a lengthy 2270 test. --- .../integration/resources/SHIBUI-2270-2.side | 904 ++++++++++++++++-- 1 file changed, 812 insertions(+), 92 deletions(-) diff --git a/backend/src/integration/resources/SHIBUI-2270-2.side b/backend/src/integration/resources/SHIBUI-2270-2.side index 96995251c..11400b4db 100644 --- a/backend/src/integration/resources/SHIBUI-2270-2.side +++ b/backend/src/integration/resources/SHIBUI-2270-2.side @@ -164,6 +164,18 @@ ["xpath=//a[contains(.,'AACLI - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "161ef892-c85c-43f3-9356-e93a559a44a0", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "be761931-fb77-4030-bc2c-2577d3a99580", "comment": "", @@ -180,7 +192,7 @@ "id": "eb50041f-bf6e-4ef4-92ee-9319f79b8336", "comment": "", "command": "click", - "target": "id=property-selector-item-9", + "target": "id=property-selector-item-2", "targets": [ ["id=property-selector-item-9", "id"], ["linkText=AccountLockoutManagement - Add all", "linkText"], @@ -192,6 +204,18 @@ ["xpath=//a[contains(.,'AccountLockoutManagement - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "32bf713f-ecd2-4b8c-a0bb-e23c397bbd54", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "de63d0c0-9504-4339-b76f-ce21b7c9f5f8", "comment": "", @@ -209,7 +233,7 @@ "id": "9f0ee002-e494-4409-9461-35d70ec30bf3", "comment": "", "command": "click", - "target": "id=property-selector-item-17", + "target": "id=property-selector-item-3", "targets": [ ["id=property-selector-item-17", "id"], ["linkText=AttendedRestartConfiguration - Add all", "linkText"], @@ -221,6 +245,18 @@ ["xpath=//a[contains(.,'AttendedRestartConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "9026ce67-e4e7-4023-943a-13c40955c7c6", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "b1cb5ac9-027c-45f2-b7c2-d1a661378928", "comment": "", @@ -237,7 +273,7 @@ "id": "53354967-a636-428a-8dea-c771e2ee3add", "comment": "", "command": "click", - "target": "id=property-selector-item-25", + "target": "id=property-selector-item-4", "targets": [ ["id=property-selector-item-25", "id"], ["linkText=AttributePostLoginC14NConfiguration - Add all", "linkText"], @@ -249,6 +285,18 @@ ["xpath=//a[contains(.,'AttributePostLoginC14NConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "3a12a054-f507-4e10-b7fb-988fe56a4879", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "ff91bfaf-f6ce-42c2-9dd4-1c52268d140d", "comment": "", @@ -262,7 +310,7 @@ "id": "825680dd-0180-4b92-a2df-40d041c24831", "comment": "", "command": "click", - "target": "id=property-selector-item-33", + "target": "id=property-selector-item-5", "targets": [ ["id=property-selector-item-33", "id"], ["linkText=AuditLoggingConfiguration - Add all", "linkText"], @@ -274,6 +322,18 @@ ["xpath=//a[contains(.,'AuditLoggingConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "a629072e-6d4b-45a9-bcfc-49b7f5ec610e", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "1c671949-1992-4cbd-930c-0153e1fea983", "comment": "", @@ -291,7 +351,7 @@ "id": "7e6f1147-95fa-4f2e-b71c-bdc2265c8537", "comment": "", "command": "click", - "target": "id=property-selector-item-49", + "target": "id=property-selector-item-6", "targets": [ ["id=property-selector-item-49", "id"], ["linkText=AuthenticationConfiguration - Add all", "linkText"], @@ -303,6 +363,18 @@ ["xpath=//a[contains(.,'AuthenticationConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "635ddc4a-f916-4bcd-b7a3-cec6e1a267ca", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "384ea0fc-0bc1-4f63-b736-7e1d67277662", "comment": "", @@ -319,7 +391,7 @@ "id": "2158cbdc-85be-4082-938c-00a14e0d6d63", "comment": "", "command": "click", - "target": "id=property-selector-item-59", + "target": "id=property-selector-item-7", "targets": [ ["id=property-selector-item-59", "id"], ["linkText=CSRF - Add all", "linkText"], @@ -331,6 +403,18 @@ ["xpath=//a[contains(.,'CSRF - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "84e6519a-960d-4c27-a405-395355969ea4", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "a861c6d1-277e-438f-a49c-d47521f67dcc", "comment": "", @@ -348,7 +432,7 @@ "id": "f71b15c0-ff1b-4f26-8630-b755e1af00aa", "comment": "", "command": "click", - "target": "id=property-selector-item-62", + "target": "id=property-selector-item-8", "targets": [ ["id=property-selector-item-62", "id"], ["linkText=CasProtocolConfiguration - Add all", "linkText"], @@ -360,6 +444,18 @@ ["xpath=//a[contains(.,'CasProtocolConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "d6d64aa2-c565-4204-8390-35fb0c2217a9", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "50f0c334-c0ca-43dc-8464-6d5d5b64de3e", "comment": "", @@ -377,7 +473,7 @@ "id": "ab25fbad-3959-4b65-ae5b-cd8cf81679d3", "comment": "", "command": "click", - "target": "id=property-selector-item-66", + "target": "id=property-selector-item-9", "targets": [ ["id=property-selector-item-66", "id"], ["linkText=ConsentConfiguration - Add all", "linkText"], @@ -389,6 +485,18 @@ ["xpath=//a[contains(.,'ConsentConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "1b348c87-d54a-4323-9bb9-9ce5bde493aa", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "5b5e0325-1735-4b9a-9920-5dac993cbb13", "comment": "", @@ -406,7 +514,7 @@ "id": "d06957b0-f5fa-4960-ac87-750566eb8484", "comment": "", "command": "click", - "target": "id=property-selector-item-84", + "target": "id=property-selector-item-10", "targets": [ ["id=property-selector-item-84", "id"], ["linkText=Core - Add all", "linkText"], @@ -418,6 +526,18 @@ ["xpath=//a[contains(.,'Core - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "f37bb161-c2fe-458d-b2f1-4c84f17ae1af", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "cf7d85ba-7edc-4bf1-938a-a88fd04c7252", "comment": "", @@ -435,7 +555,7 @@ "id": "630e9dc2-89d6-435e-bd3d-040814109f16", "comment": "", "command": "click", - "target": "id=property-selector-item-100", + "target": "id=property-selector-item-11", "targets": [ ["id=property-selector-item-100", "id"], ["linkText=DuoAuthnConfiguration - Add all", "linkText"], @@ -447,6 +567,18 @@ ["xpath=//a[contains(.,'DuoAuthnConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "565f7538-ceb5-46b0-8f95-d67ff41d24e2", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "9f2f0c50-7465-4879-bb68-822bca1f0fa3", "comment": "", @@ -463,7 +595,7 @@ "id": "6f28c9cc-1006-456b-ae72-b70006636829", "comment": "", "command": "click", - "target": "id=property-selector-item-127", + "target": "id=property-selector-item-12", "targets": [ ["id=property-selector-item-127", "id"], ["linkText=DuoOIDCAuthnConfiguration - Add all", "linkText"], @@ -475,6 +607,18 @@ ["xpath=//a[contains(.,'DuoOIDCAuthnConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "d6491bae-0111-4831-9a5d-bdd59fd499fd", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "3b326c6f-96d3-4f6c-ba82-e9ffd95517f1", "comment": "", @@ -488,7 +632,7 @@ "id": "ec3ac03f-c46b-4e1c-a89d-e2dc9826ca98", "comment": "", "command": "click", - "target": "id=property-selector-item-169", + "target": "id=property-selector-item-13", "targets": [ ["id=property-selector-item-169", "id"], ["linkText=ErrorHandlingConfiguration - Add all", "linkText"], @@ -500,6 +644,18 @@ ["xpath=//a[contains(.,'ErrorHandlingConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "d111643c-b2f9-43d2-9421-d48e008c6acd", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "ce43ffb1-3979-4381-a155-9a2a59d1ac95", "comment": "", @@ -517,7 +673,7 @@ "id": "62d42fb7-00e2-400d-a1be-adcbf826ce3a", "comment": "", "command": "click", - "target": "id=property-selector-item-175", + "target": "id=property-selector-item-14", "targets": [ ["id=property-selector-item-175", "id"], ["linkText=ExternalAuthnConfiguration - Add all", "linkText"], @@ -529,6 +685,18 @@ ["xpath=//a[contains(.,'ExternalAuthnConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "32940f9c-1028-48de-86f5-31b49e098b1c", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "b1c01f80-778c-4ea3-b952-dd84c18e5904", "comment": "", @@ -546,7 +714,7 @@ "id": "8a3757ee-2564-436e-abc5-e0584a59a82e", "comment": "", "command": "click", - "target": "id=property-selector-item-192", + "target": "id=property-selector-item-15", "targets": [ ["id=property-selector-item-192", "id"], ["linkText=FTICKSLoggingConfiguration - Add all", "linkText"], @@ -558,6 +726,18 @@ ["xpath=//a[contains(.,'FTICKSLoggingConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "e5a60d2e-60b2-464e-be45-c73b8717ba2e", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "c6bfe838-9027-4c25-990e-e451e9d04a4d", "comment": "", @@ -571,7 +751,7 @@ "id": "0c462504-cb92-421d-aeb0-8afecac90aec", "comment": "", "command": "click", - "target": "id=property-selector-item-199", + "target": "id=property-selector-item-16", "targets": [ ["id=property-selector-item-199", "id"], ["linkText=FunctionAuthnConfiguration - Add all", "linkText"], @@ -583,6 +763,18 @@ ["xpath=//a[contains(.,'FunctionAuthnConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "e44eac9f-47ab-48ec-a821-17c74a00d17b", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "892d14a0-9ab0-4c05-945b-bd96d461eba8", "comment": "", @@ -600,7 +792,7 @@ "id": "9a809145-1f01-4a6b-8eaf-836f91a9bd5a", "comment": "", "command": "click", - "target": "id=property-selector-item-214", + "target": "id=property-selector-item-17", "targets": [ ["id=property-selector-item-214", "id"], ["linkText=HelloWorldConfiguration - Add all", "linkText"], @@ -612,6 +804,18 @@ ["xpath=//a[contains(.,'HelloWorldConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "a2647ee4-f9df-4698-ab1f-02d7b488b835", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "8e3dc610-99f9-4a85-a0c0-cd572ccf0a84", "comment": "", @@ -629,7 +833,7 @@ "id": "fa182a6d-bba7-4f50-a6d8-a5391b592004", "comment": "", "command": "click", - "target": "id=property-selector-item-222", + "target": "id=property-selector-item-18", "targets": [ ["id=property-selector-item-222", "id"], ["linkText=IPAddressAuthnConfiguration - Add all", "linkText"], @@ -641,6 +845,18 @@ ["xpath=//a[contains(.,'IPAddressAuthnConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "43df662a-1205-40ca-967e-2473b36eb829", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "17e45a4b-9d00-478f-9add-c1a7138a7959", "comment": "", @@ -658,7 +874,7 @@ "id": "2a3578cb-56d5-4805-8e82-2058e17c3ad5", "comment": "", "command": "click", - "target": "id=property-selector-item-237", + "target": "id=property-selector-item-19", "targets": [ ["id=property-selector-item-237", "id"], ["linkText=JAASAuthnConfiguration - Add all", "linkText"], @@ -670,6 +886,18 @@ ["xpath=//a[contains(.,'JAASAuthnConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "f24149b6-8c1e-4ffa-b08a-262f7bc270b0", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "3aedee37-3445-4679-afe8-62e53b348e52", "comment": "", @@ -683,7 +911,7 @@ "id": "fce00a94-ffe3-4771-b33d-e6c8cde6c690", "comment": "", "command": "click", - "target": "id=property-selector-item-240", + "target": "id=property-selector-item-20", "targets": [ ["id=property-selector-item-240", "id"], ["linkText=KerberosAuthnConfiguration - Add all", "linkText"], @@ -695,6 +923,18 @@ ["xpath=//a[contains(.,'KerberosAuthnConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "f3fb5c6b-ddcf-4dd5-83c2-4b3f6960e5fc", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "37642e97-2b2a-4cfd-9b71-d150c13b1b2d", "comment": "", @@ -712,7 +952,7 @@ "id": "fdae4c41-909b-44b1-b245-469c430a09a0", "comment": "", "command": "click", - "target": "id=property-selector-item-245", + "target": "id=property-selector-item-21", "targets": [ ["id=property-selector-item-245", "id"], ["linkText=LDAPAuthnConfiguration - Add all", "linkText"], @@ -724,6 +964,18 @@ ["xpath=//a[contains(.,'LDAPAuthnConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "fa39c178-50a4-4761-ba14-86c9bb7e146d", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "f34f0217-ff82-441b-a73b-b25f791bc546", "comment": "", @@ -741,7 +993,7 @@ "id": "d30d9da8-65e0-41a1-b27f-c4cc998c97fd", "comment": "", "command": "click", - "target": "id=property-selector-item-281", + "target": "id=property-selector-item-22", "targets": [ ["id=property-selector-item-281", "id"], ["linkText=LogoutConfiguration - Add all", "linkText"], @@ -753,6 +1005,18 @@ ["xpath=//a[contains(.,'LogoutConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "4313bd45-a1f1-43ca-87be-9d173ac965fb", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "cb442dbe-c609-4b8b-ac55-2d32362be80b", "comment": "", @@ -770,7 +1034,7 @@ "id": "19b1de66-7601-4e41-a345-657c5417f23f", "comment": "", "command": "click", - "target": "id=property-selector-item-288", + "target": "id=property-selector-item-23", "targets": [ ["id=property-selector-item-288", "id"], ["linkText=MetadataQuery - Add all", "linkText"], @@ -782,6 +1046,18 @@ ["xpath=//a[contains(.,'MetadataQuery - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "5a58e55d-3351-4ecd-addc-c0d1a74b7c80", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "513c8bd3-cbb4-443f-9a90-8a2ae9d5c0ce", "comment": "", @@ -799,7 +1075,7 @@ "id": "515cc435-61ee-430a-8cdc-ac41e3926fbc", "comment": "", "command": "click", - "target": "id=property-selector-item-296", + "target": "id=property-selector-item-24", "targets": [ ["id=property-selector-item-296", "id"], ["linkText=MetadataReload - Add all", "linkText"], @@ -811,6 +1087,18 @@ ["xpath=//a[contains(.,'MetadataReload - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "4252877a-5ba4-4a08-93a3-865463f8e8ab", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "6d5dcd3a-0d08-4140-9634-196e2e2fdb90", "comment": "", @@ -824,7 +1112,7 @@ "id": "2b2a05d9-4e8b-45cf-882f-08328cb0b6e5", "comment": "", "command": "click", - "target": "id=property-selector-item-304", + "target": "id=property-selector-item-25", "targets": [ ["id=property-selector-item-304", "id"], ["linkText=Metadatagen - Add all", "linkText"], @@ -836,6 +1124,18 @@ ["xpath=//a[contains(.,'Metadatagen - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "1d9b32f7-e71c-414d-a138-d7238ff2cd90", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "f1709162-b102-48da-81b0-5862158fd74d", "comment": "", @@ -853,7 +1153,7 @@ "id": "643c1db8-10f8-4146-94fb-bf920b007c00", "comment": "", "command": "click", - "target": "id=property-selector-item-313", + "target": "id=property-selector-item-26", "targets": [ ["id=property-selector-item-313", "id"], ["linkText=MetricsConfiguration - Add all", "linkText"], @@ -865,6 +1165,18 @@ ["xpath=//a[contains(.,'MetricsConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "5eefe563-90b6-482e-bc3a-a1f001d2f403", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "206468ff-7786-4e32-96dd-4c0e9a2194b7", "comment": "", @@ -882,7 +1194,7 @@ "id": "00f2e151-13aa-4ac0-bb0c-d7e531f422a5", "comment": "", "command": "click", - "target": "id=property-selector-item-320", + "target": "id=property-selector-item-27", "targets": [ ["id=property-selector-item-320", "id"], ["linkText=Misc - Add all", "linkText"], @@ -894,6 +1206,18 @@ ["xpath=//a[contains(.,'Misc - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "419ef781-8332-44e9-9c20-1ac1f680f1cb", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "c06b4caf-e093-49b4-8cac-f71bda476995", "comment": "", @@ -907,7 +1231,7 @@ "id": "031e88e8-bde7-4d25-8aab-919bc8882901", "comment": "", "command": "click", - "target": "id=property-selector-item-326", + "target": "id=property-selector-item-28", "targets": [ ["id=property-selector-item-326", "id"], ["linkText=MultiFactorAuthnConfiguration - Add all", "linkText"], @@ -919,6 +1243,18 @@ ["xpath=//a[contains(.,'MultiFactorAuthnConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "7e1bd75f-13e1-4129-8c0b-230abad99d05", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "7ab63a23-e0ab-4a07-8ef8-9fdb6af9f59b", "comment": "", @@ -936,7 +1272,7 @@ "id": "34cbdae8-4b4c-4faa-a38c-f3a9c5475e45", "comment": "", "command": "click", - "target": "id=property-selector-item-342", + "target": "id=property-selector-item-29", "targets": [ ["id=property-selector-item-342", "id"], ["linkText=NameIDConsumptionConfiguration - Add all", "linkText"], @@ -948,6 +1284,18 @@ ["xpath=//a[contains(.,'NameIDConsumptionConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "c7d69437-7bf5-4fb9-8450-47c0aecdae0b", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "15c61405-c967-475f-b494-6bdb461b5283", "comment": "", @@ -965,7 +1313,7 @@ "id": "6e13ab35-510b-4e7b-976c-457d59f65606", "comment": "", "command": "click", - "target": "id=property-selector-item-345", + "target": "id=property-selector-item-30", "targets": [ ["id=property-selector-item-345", "id"], ["linkText=NameIDGenerationConfiguration - Add all", "linkText"], @@ -977,6 +1325,18 @@ ["xpath=//a[contains(.,'NameIDGenerationConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "c2d86012-0b07-4f31-a0a7-47afcd6d5697", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "74505e9c-1a4b-441d-9e21-fce8077576b4", "comment": "", @@ -994,7 +1354,7 @@ "id": "ec03564e-9ff9-4c53-914e-e33e8efec3b8", "comment": "", "command": "click", - "target": "id=property-selector-item-349", + "target": "id=property-selector-item-31", "targets": [ ["id=property-selector-item-349", "id"], ["linkText=OAuth2ClientAuthnConfiguration - Add all", "linkText"], @@ -1006,6 +1366,18 @@ ["xpath=//a[contains(.,'OAuth2ClientAuthnConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "f89312e5-6a9c-4bcc-bd98-bade2d380829", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "9bc758f1-8c06-429e-abf4-78fadd181d56", "comment": "", @@ -1023,7 +1395,7 @@ "id": "a81e8d28-41b8-47d1-901b-6d36fb90398d", "comment": "", "command": "click", - "target": "id=property-selector-item-358", + "target": "id=property-selector-item-32", "targets": [ ["id=property-selector-item-358", "id"], ["linkText=OIDC OP - Add all", "linkText"], @@ -1035,6 +1407,18 @@ ["xpath=//a[contains(.,'OIDC OP - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "fee01919-c451-487c-b329-12e715df8d23", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "5e1646f3-7841-4b97-96c9-639c6f7ef3ca", "comment": "", @@ -1052,7 +1436,7 @@ "id": "f3865e29-6b36-49ab-99a4-44370b5ed974", "comment": "", "command": "click", - "target": "id=property-selector-item-371", + "target": "id=property-selector-item-33", "targets": [ ["id=property-selector-item-371", "id"], ["linkText=OPAuthorization - Add all", "linkText"], @@ -1064,6 +1448,18 @@ ["xpath=//a[contains(.,'OPAuthorization - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "7dd7a6e4-4b73-4d81-968f-bff6f5688fd4", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "821c3a6d-b9a6-45bf-bda3-46c2f1e87303", "comment": "", @@ -1081,7 +1477,7 @@ "id": "72620249-22a8-436b-b506-670fad77fefa", "comment": "", "command": "click", - "target": "id=property-selector-item-378", + "target": "id=property-selector-item-34", "targets": [ ["id=property-selector-item-378", "id"], ["linkText=OPClientAuthentication - Add all", "linkText"], @@ -1093,6 +1489,18 @@ ["xpath=//a[contains(.,'OPClientAuthentication - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "dc272d77-865b-4dae-bfc4-c64298eece48", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "e8d736c8-be22-4411-87d4-0a1eefcc821e", "comment": "", @@ -1106,7 +1514,7 @@ "id": "d8ef3cf9-1398-4bcd-b976-92a2a471ce1c", "comment": "", "command": "click", - "target": "id=property-selector-item-380", + "target": "id=property-selector-item-35", "targets": [ ["id=property-selector-item-380", "id"], ["linkText=OPClientCredentialsGrant - Add all", "linkText"], @@ -1118,6 +1526,18 @@ ["xpath=//a[contains(.,'OPClientCredentialsGrant - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "7db3f06c-ff54-4312-8f21-8beaec2e64b6", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "ed236cf8-e185-4b41-a47f-2a9219eab773", "comment": "", @@ -1131,7 +1551,7 @@ "id": "d4965727-9cc9-465a-9d4d-9e3a16c9507a", "comment": "", "command": "click", - "target": "id=property-selector-item-383", + "target": "id=property-selector-item-36", "targets": [ ["id=property-selector-item-383", "id"], ["linkText=OPClientResolution - Add all", "linkText"], @@ -1143,6 +1563,18 @@ ["xpath=//a[contains(.,'OPClientResolution - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "942a8de5-3f66-400a-8652-9e77d56cc41e", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "899a5897-0786-4f40-8d1f-2c3cc64f4666", "comment": "", @@ -1150,17 +1582,58 @@ "target": "css=.toggle-button", "targets": [ ["css=.toggle-button", "css:finder"], - ["xpath=(//button[@type='button'])[43]", "xpath:attributes"], + ["xpath=(//button[@type='button'])[43]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "a08f536a-166d-45e0-a477-b7aece98a6bc", + "comment": "", + "command": "click", + "target": "id=property-selector-item-37", + "targets": [ + ["id=property-selector-item-387", "id"], + ["linkText=OPCustomFilterRegistration - Add all", "linkText"], + ["css=#property-selector-item-387", "css:finder"], + ["xpath=//a[@id='property-selector-item-387']", "xpath:attributes"], + ["xpath=//div[@id='property-selector']/div[74]/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '#')])[387]", "xpath:href"], + ["xpath=//div[74]/a", "xpath:position"], + ["xpath=//a[contains(.,'OPCustomFilterRegistration - Add all')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "743cfb54-8a45-485f-b99a-69f9ebac1e4c", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" + }, { + "id": "90ec186d-d13c-49a1-9912-744f62873feb", + "comment": "", + "command": "click", + "target": "css=.toggle-button", + "targets": [ + ["css=.toggle-button", "css:finder"], + ["xpath=(//button[@type='button'])[44]", "xpath:attributes"], ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] ], "value": "" }, { - "id": "a08f536a-166d-45e0-a477-b7aece98a6bc", + "id": "5d32be07-b83d-4b24-bfd0-f6c58c3e2228", "comment": "", "command": "click", - "target": "id=property-selector-item-387", + "target": "id=property-selector-item-38", "targets": [ ["id=property-selector-item-387", "id"], ["linkText=OPCustomFilterRegistration - Add all", "linkText"], @@ -1173,32 +1646,15 @@ ], "value": "" }, { - "id": "90ec186d-d13c-49a1-9912-744f62873feb", - "comment": "", - "command": "click", - "target": "css=.toggle-button", - "targets": [ - ["css=.toggle-button", "css:finder"], - ["xpath=(//button[@type='button'])[44]", "xpath:attributes"], - ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/div/div/button", "xpath:idRelative"], - ["xpath=//div[2]/div/div/div/div/button", "xpath:position"], - ["xpath=//button[contains(.,'Options')]", "xpath:innerText"] - ], - "value": "" - }, { - "id": "6fdf6ef4-52e8-44a9-8dc5-8126e2ba11b0", + "id": "998d8862-f79e-4ec4-889e-ce046de3c11c", "comment": "", "command": "click", - "target": "id=property-selector-item-389", + "target": "xpath=//form/div[2]/div/div/button", "targets": [ - ["id=property-selector-item-389", "id"], - ["linkText=OPDiscovery - Add all", "linkText"], - ["css=#property-selector-item-389", "css:finder"], - ["xpath=//a[@id='property-selector-item-389']", "xpath:attributes"], - ["xpath=//div[@id='property-selector']/div[76]/a", "xpath:idRelative"], - ["xpath=(//a[contains(@href, '#')])[389]", "xpath:href"], - ["xpath=//div[76]/a", "xpath:position"], - ["xpath=//a[contains(.,'OPDiscovery - Add all')]", "xpath:innerText"] + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] ], "value": "" }, { @@ -1214,7 +1670,7 @@ "id": "a3bbcc78-ce50-4b17-9419-f228664dc9fc", "comment": "", "command": "click", - "target": "id=property-selector-item-392", + "target": "id=property-selector-item-39", "targets": [ ["id=property-selector-item-392", "id"], ["linkText=OPDynamicClientRegistration - Add all", "linkText"], @@ -1226,6 +1682,18 @@ ["xpath=//a[contains(.,'OPDynamicClientRegistration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "fc0a234c-ee59-4af0-93cf-7994b3cef11f", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "ec8f2a2b-b45d-4345-af4b-dd5965f9dc54", "comment": "", @@ -1243,7 +1711,7 @@ "id": "ba6779d8-9a40-4981-a41f-c8c22df7027a", "comment": "", "command": "click", - "target": "id=property-selector-item-407", + "target": "id=property-selector-item-40", "targets": [ ["id=property-selector-item-407", "id"], ["linkText=OPMetadataPolicies - Add all", "linkText"], @@ -1255,6 +1723,18 @@ ["xpath=//a[contains(.,'OPMetadataPolicies - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "7dbff2cb-b2e1-4054-9411-6a823dffa819", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "b93aed8b-bd95-496a-ad07-b9bfe23f8522", "comment": "", @@ -1268,7 +1748,7 @@ "id": "57fc676c-34fc-4220-915e-be3c30821030", "comment": "", "command": "click", - "target": "id=property-selector-item-409", + "target": "id=property-selector-item-41", "targets": [ ["id=property-selector-item-409", "id"], ["linkText=OPRevocation - Add all", "linkText"], @@ -1280,6 +1760,18 @@ ["xpath=//a[contains(.,'OPRevocation - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "24758ea5-317b-4c0e-9919-d79c2de026a8", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "85efb0c2-9a2b-4816-b77d-4c84816f3499", "comment": "", @@ -1297,7 +1789,7 @@ "id": "0c424441-f80c-4f42-9a4a-2df0be1ad937", "comment": "", "command": "click", - "target": "id=property-selector-item-412", + "target": "id=property-selector-item-42", "targets": [ ["id=property-selector-item-412", "id"], ["linkText=OPSecurity - Add all", "linkText"], @@ -1309,6 +1801,18 @@ ["xpath=//a[contains(.,'OPSecurity - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "3adce77e-2dbb-41c6-9637-bc1db9925f43", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "686dc5ad-4686-4364-865e-e8c95210f7e3", "comment": "", @@ -1326,7 +1830,7 @@ "id": "da318a35-6cdf-4346-b357-3aadeaf46640", "comment": "", "command": "click", - "target": "id=property-selector-item-420", + "target": "id=property-selector-item-43", "targets": [ ["id=property-selector-item-420", "id"], ["linkText=OPSubClaim - Add all", "linkText"], @@ -1338,6 +1842,18 @@ ["xpath=//a[contains(.,'OPSubClaim - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "f1365110-924c-4cd5-9a2d-801e668a8594", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "5f8f249d-2052-4b6f-be83-9cdde0f5a06d", "comment": "", @@ -1355,7 +1871,7 @@ "id": "f36fb2c2-bf28-4fb0-8a6e-083b8a7d854e", "comment": "", "command": "click", - "target": "id=property-selector-item-424", + "target": "id=property-selector-item-44", "targets": [ ["id=property-selector-item-424", "id"], ["linkText=OPToken - Add all", "linkText"], @@ -1367,6 +1883,18 @@ ["xpath=//a[contains(.,'OPToken - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "36d15c9b-c948-48d1-b779-6cf5fff7c93a", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "5e7fc6cc-c7e3-4d4b-b682-ec939c8a5db1", "comment": "", @@ -1384,7 +1912,7 @@ "id": "24fa8f94-9a62-4e11-9125-a6c576695e77", "comment": "", "command": "click", - "target": "id=property-selector-item-436", + "target": "id=property-selector-item-45", "targets": [ ["id=property-selector-item-436", "id"], ["linkText=PersistentNameIDGenerationConfiguration - Add all", "linkText"], @@ -1396,6 +1924,18 @@ ["xpath=//a[contains(.,'PersistentNameIDGenerationConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "99b294a6-77f5-4d63-96a8-e4a0724e22bf", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "f7c7f42d-b4cb-4f92-997f-d9677a00758f", "comment": "", @@ -1409,7 +1949,7 @@ "id": "7bfdfde0-3399-4161-9cbc-e67f10ae44b5", "comment": "", "command": "click", - "target": "id=property-selector-item-460", + "target": "id=property-selector-item-46", "targets": [ ["id=property-selector-item-460", "id"], ["linkText=ReloadableServices - Add all", "linkText"], @@ -1421,6 +1961,18 @@ ["xpath=//a[contains(.,'ReloadableServices - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "a9c1d8ea-ae21-43d6-adc2-be6696a9d16e", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "5a3ad5c4-37e2-4060-88bd-ed96b94d037e", "comment": "", @@ -1434,7 +1986,7 @@ "id": "db192d5c-0857-4059-869d-d1ff40fd8844", "comment": "", "command": "click", - "target": "id=property-selector-item-501", + "target": "id=property-selector-item-47", "targets": [ ["id=property-selector-item-501", "id"], ["linkText=RelyingPartyConfiguration - Add all", "linkText"], @@ -1446,6 +1998,18 @@ ["xpath=//a[contains(.,'RelyingPartyConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "019376a3-6cbc-4dce-b948-9655bc765038", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "46e1fd14-ca91-4f92-a919-695dcff58622", "comment": "", @@ -1463,7 +2027,7 @@ "id": "bf5ba1a6-ba55-4397-91fa-7f1c1cd28e0d", "comment": "", "command": "click", - "target": "id=property-selector-item-507", + "target": "id=property-selector-item-48", "targets": [ ["id=property-selector-item-507", "id"], ["linkText=RemoteUserAuthnConfiguration - Add all", "linkText"], @@ -1475,6 +2039,18 @@ ["xpath=//a[contains(.,'RemoteUserAuthnConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "c15a438c-5582-44a0-8d87-70a1034ca0bf", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "fde12162-843c-4425-bc3e-f404f52cd232", "comment": "", @@ -1488,7 +2064,7 @@ "id": "e1313d05-d1ff-4196-8ae7-eb04c1088afd", "comment": "", "command": "click", - "target": "id=property-selector-item-524", + "target": "id=property-selector-item-49", "targets": [ ["id=property-selector-item-524", "id"], ["linkText=RemoteUserInternalAuthnConfiguration - Add all", "linkText"], @@ -1500,6 +2076,18 @@ ["xpath=//a[contains(.,'RemoteUserInternalAuthnConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "1e2a6f80-46e4-42d3-b30e-46bcbb07a7b7", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "1b2b7432-6d03-4b84-922c-59b9cee6ccc5", "comment": "", @@ -1517,7 +2105,7 @@ "id": "31fff123-cc89-4473-9943-a7b5d1206de7", "comment": "", "command": "click", - "target": "id=property-selector-item-549", + "target": "id=property-selector-item-50", "targets": [ ["id=property-selector-item-549", "id"], ["linkText=SAML2ProxyTransformPostLoginC14NConfiguration - Add all", "linkText"], @@ -1529,6 +2117,18 @@ ["xpath=//a[contains(.,'SAML2ProxyTransformPostLoginC14NConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "d583a94e-bb04-4c34-ad36-8154af54a05c", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "10926b24-5952-4685-be81-802f5fc7ca4a", "comment": "", @@ -1542,7 +2142,7 @@ "id": "746398e5-d85c-412c-8a64-45c6d2a669ee", "comment": "", "command": "click", - "target": "id=property-selector-item-552", + "target": "id=property-selector-item-51", "targets": [ ["id=property-selector-item-552", "id"], ["linkText=SAMLAuthnConfiguration - Add all", "linkText"], @@ -1554,6 +2154,18 @@ ["xpath=//a[contains(.,'SAMLAuthnConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "fd0211b1-c372-487c-9110-e870534cf39c", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "5558c433-213a-49de-b68d-e6d9ac396b86", "comment": "", @@ -1567,7 +2179,7 @@ "id": "a85d9957-d3f3-4304-bd85-dd25ae70592b", "comment": "", "command": "click", - "target": "id=property-selector-item-572", + "target": "id=property-selector-item-52", "targets": [ ["id=property-selector-item-572", "id"], ["linkText=SPNEGOAuthnConfiguration - Add all", "linkText"], @@ -1579,6 +2191,18 @@ ["xpath=//a[contains(.,'SPNEGOAuthnConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "cbe5f9bb-b431-4de5-9522-f9a3585839b2", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "62dcb81a-9265-4f8f-ac8e-6ae7027a3601", "comment": "", @@ -1596,7 +2220,7 @@ "id": "18da3cfc-943f-43e5-ab16-6a9070336d5c", "comment": "", "command": "click", - "target": "id=property-selector-item-592", + "target": "id=property-selector-item-53", "targets": [ ["id=property-selector-item-592", "id"], ["linkText=SecurityConfiguration - Add all", "linkText"], @@ -1608,6 +2232,18 @@ ["xpath=//a[contains(.,'SecurityConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "479b0839-b06a-4198-ac33-564b1ed167ad", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "894853a1-2202-4ff4-bc06-f0f7faf32505", "comment": "", @@ -1625,7 +2261,7 @@ "id": "12440bab-1419-4d7d-948c-71811b067df2", "comment": "", "command": "click", - "target": "id=property-selector-item-626", + "target": "id=property-selector-item-54", "targets": [ ["id=property-selector-item-626", "id"], ["linkText=SessionConfiguration - Add all", "linkText"], @@ -1637,6 +2273,18 @@ ["xpath=//a[contains(.,'SessionConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "59eea1df-31ec-424e-a322-788d308372be", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "5bf0b70b-e413-49eb-bfcb-f97a4265c70b", "comment": "", @@ -1650,7 +2298,7 @@ "id": "eb83e85f-6924-44ac-9922-9c5a1fcbcbc5", "comment": "", "command": "click", - "target": "id=property-selector-item-639", + "target": "id=property-selector-item-55", "targets": [ ["id=property-selector-item-639", "id"], ["linkText=SimplePostLoginC14NConfiguration - Add all", "linkText"], @@ -1662,6 +2310,18 @@ ["xpath=//a[contains(.,'SimplePostLoginC14NConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "db50354f-7930-4f07-acae-aabe51699ae0", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "d941d154-a6a3-4684-ad04-ca9d45acf2aa", "comment": "", @@ -1679,7 +2339,7 @@ "id": "a729126e-0c39-4db6-882c-b506db087119", "comment": "", "command": "click", - "target": "id=property-selector-item-643", + "target": "id=property-selector-item-56", "targets": [ ["id=property-selector-item-643", "id"], ["linkText=Status - Add all", "linkText"], @@ -1691,6 +2351,18 @@ ["xpath=//a[contains(.,'Status - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "d57ea24b-ba28-4df9-8bcc-4e2f81fa0a37", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "878447bd-6424-440f-8dcf-461f994a6478", "comment": "", @@ -1708,7 +2380,7 @@ "id": "3b964802-50ee-4a2a-8db6-d24a51a61483", "comment": "", "command": "click", - "target": "id=property-selector-item-651", + "target": "id=property-selector-item-57", "targets": [ ["id=property-selector-item-651", "id"], ["linkText=StorageConfiguration - Add all", "linkText"], @@ -1720,6 +2392,18 @@ ["xpath=//a[contains(.,'StorageConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "74a2c100-4829-443c-8b00-d6e1db73815e", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "eca7bf2d-db81-4cad-873b-eba9440bd0e5", "comment": "", @@ -1733,7 +2417,7 @@ "id": "40ca1af5-e808-4b69-a5dd-3b545c1b233d", "comment": "", "command": "click", - "target": "id=property-selector-item-659", + "target": "id=property-selector-item-58", "targets": [ ["id=property-selector-item-659", "id"], ["linkText=TOTP - Add all", "linkText"], @@ -1745,6 +2429,18 @@ ["xpath=//a[contains(.,'TOTP - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "727b615e-a3e8-4254-b162-970b19aeb2a0", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "d6e986cb-865d-4472-b791-ea9ba459a849", "comment": "", @@ -1762,7 +2458,7 @@ "id": "26be9d61-f3c2-482e-8d0d-759a00c9b28f", "comment": "", "command": "click", - "target": "id=property-selector-item-677", + "target": "id=property-selector-item-59", "targets": [ ["id=property-selector-item-677", "id"], ["linkText=X500PostLoginC14NConfiguration - Add all", "linkText"], @@ -1774,6 +2470,18 @@ ["xpath=//a[contains(.,'X500PostLoginC14NConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "3fd22066-5329-4435-b7ef-ed6f1853e964", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "966c35be-39a4-4fa9-aded-8ba6fa1394a2", "comment": "", @@ -1791,7 +2499,7 @@ "id": "5124a661-4c33-4468-9c08-505268f78ff0", "comment": "", "command": "click", - "target": "id=property-selector-item-683", + "target": "id=property-selector-item-60", "targets": [ ["id=property-selector-item-683", "id"], ["linkText=X509AuthnConfiguration - Add all", "linkText"], @@ -1803,6 +2511,18 @@ ["xpath=//a[contains(.,'X509AuthnConfiguration - Add all')]", "xpath:innerText"] ], "value": "" + }, { + "id": "34c11849-e76a-4169-b63c-4c714912c25f", + "comment": "", + "command": "click", + "target": "xpath=//form/div[2]/div/div/button", + "targets": [ + ["css=.ms-2", "css:finder"], + ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], + ["xpath=//div[@id='root']/div/main/div/section/div[2]/div/form/div[2]/div/div/button", "xpath:idRelative"], + ["xpath=//form/div[2]/div/div/button", "xpath:position"] + ], + "value": "" }, { "id": "a11e93fd-5a1b-4456-a875-f0b8a8582058", "comment": "", @@ -1816,7 +2536,7 @@ "id": "299da229-ce40-43ac-87c6-2bb6c1122d93", "comment": "", "command": "click", - "target": "id=property-selector-item-699", + "target": "id=property-selector-item-61", "targets": [ ["id=property-selector-item-699", "id"], ["linkText=X509InternalAuthnConfiguration - Add all", "linkText"], @@ -1832,7 +2552,7 @@ "id": "d06a3e9a-849f-4b8d-83a1-797f8abf6794", "comment": "", "command": "click", - "target": "css=.ms-2", + "target": "xpath=//form/div[2]/div/div/button", "targets": [ ["css=.ms-2", "css:finder"], ["xpath=(//button[@type='button'])[69]", "xpath:attributes"], @@ -1908,6 +2628,13 @@ ["xpath=//td[4]/div/input", "xpath:position"] ], "value": "foo" + }, { + "id": "948ac5c1-aa09-44af-a024-c0dc898616d1", + "comment": "", + "command": "click", + "target": "id=valueInput-idp.resolvertest.logging", + "targets": [], + "value": "" }, { "id": "2b3f457c-5eb6-4df4-a7f5-3f4856a71cc2", "comment": "", @@ -1922,13 +2649,6 @@ ["xpath=//tr[2]/td[4]/div/input", "xpath:position"] ], "value": "bar" - }, { - "id": "948ac5c1-aa09-44af-a024-c0dc898616d1", - "comment": "", - "command": "click", - "target": "id=valueInput-idp.resolvertest.logging", - "targets": [], - "value": "" }, { "id": "46d0e1ac-4706-47cf-9336-683b7b6519f2", "comment": "",