From 4287880abd0d1a69f86cc79dc6555bb3453a6282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Sat, 5 Apr 2025 17:35:02 +0200 Subject: [PATCH 001/579] Switching version 4.0 to new branch 4_0_X --- .github/workflows/codeql-analysis.yml | 4 ++-- .github/workflows/crosschecks.yml | 4 ++-- .github/workflows/dockerhub.yml | 2 +- .github/workflows/fit_Elasticsearch.yml | 4 ++-- .github/workflows/fit_OpenSearch.yml | 4 ++-- .github/workflows/fit_Payara.yml | 4 ++-- .github/workflows/fit_Tomcat_LiveSync.yml | 4 ++-- .github/workflows/fit_Tomcat_PostgreSQL_JSON.yml | 4 ++-- .github/workflows/fit_Tomcat_PostgreSQL_XML.yml | 4 ++-- .github/workflows/fit_Tomcat_PostgreSQL_YAML.yml | 4 ++-- .github/workflows/fit_WA_OIDCC4UI.yml | 4 ++-- .github/workflows/fit_WA_OpenFGA.yml | 4 ++-- .github/workflows/fit_WA_SAML2SP4UI.yml | 4 ++-- .github/workflows/fit_WA_SRA_CASClient.yml | 4 ++-- .github/workflows/fit_WA_SRA_OAuth2.yml | 4 ++-- .github/workflows/fit_WA_SRA_OIDC.yml | 4 ++-- .github/workflows/fit_WA_SRA_SAML2.yml | 4 ++-- .github/workflows/fit_Wildfly.yml | 4 ++-- .github/workflows/fit_Zookeeper.yml | 4 ++-- .github/workflows/mariadb.yml | 4 ++-- .github/workflows/mysql.yml | 4 ++-- .github/workflows/neo4j.yml | 4 ++-- .github/workflows/oracle.yml | 4 ++-- 23 files changed, 45 insertions(+), 45 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 2addc10811d..dcfe1ea9b90 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -18,10 +18,10 @@ name: "CodeQL" on: push: - branches: [master,pr-*] + branches: [4_0_X,pr-*] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/crosschecks.yml b/.github/workflows/crosschecks.yml index d382b4fbd5a..50fc6c064a6 100644 --- a/.github/workflows/crosschecks.yml +++ b/.github/workflows/crosschecks.yml @@ -18,10 +18,10 @@ name: "Cross Checks" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 5a10de05be0..ddc7ef6ccae 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -19,7 +19,7 @@ name: "Push to DockerHub" on: push: branches: - - master + - 4_0_X tags: - syncope-4.0.* diff --git a/.github/workflows/fit_Elasticsearch.yml b/.github/workflows/fit_Elasticsearch.yml index b2f24b4e4e5..fb736ee97a9 100644 --- a/.github/workflows/fit_Elasticsearch.yml +++ b/.github/workflows/fit_Elasticsearch.yml @@ -18,10 +18,10 @@ name: "FIT Elasticsearch" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/fit_OpenSearch.yml b/.github/workflows/fit_OpenSearch.yml index 25d5851d46e..137423f78e0 100644 --- a/.github/workflows/fit_OpenSearch.yml +++ b/.github/workflows/fit_OpenSearch.yml @@ -18,10 +18,10 @@ name: "FIT OpenSearch" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/fit_Payara.yml b/.github/workflows/fit_Payara.yml index 7b2d697106b..8acb3e13867 100644 --- a/.github/workflows/fit_Payara.yml +++ b/.github/workflows/fit_Payara.yml @@ -18,10 +18,10 @@ name: "FIT Payara" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/fit_Tomcat_LiveSync.yml b/.github/workflows/fit_Tomcat_LiveSync.yml index 7481cae0ddc..dc5ebe602dd 100644 --- a/.github/workflows/fit_Tomcat_LiveSync.yml +++ b/.github/workflows/fit_Tomcat_LiveSync.yml @@ -18,10 +18,10 @@ name: "FIT Tomcat LiveSync" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/fit_Tomcat_PostgreSQL_JSON.yml b/.github/workflows/fit_Tomcat_PostgreSQL_JSON.yml index 2d9a5b8bcbd..78ee0e940da 100644 --- a/.github/workflows/fit_Tomcat_PostgreSQL_JSON.yml +++ b/.github/workflows/fit_Tomcat_PostgreSQL_JSON.yml @@ -18,10 +18,10 @@ name: "FIT Tomcat PostgreSQL JSON" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/fit_Tomcat_PostgreSQL_XML.yml b/.github/workflows/fit_Tomcat_PostgreSQL_XML.yml index b3153d898c4..494baabe57a 100644 --- a/.github/workflows/fit_Tomcat_PostgreSQL_XML.yml +++ b/.github/workflows/fit_Tomcat_PostgreSQL_XML.yml @@ -18,10 +18,10 @@ name: "FIT Tomcat PostgreSQL XML" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/fit_Tomcat_PostgreSQL_YAML.yml b/.github/workflows/fit_Tomcat_PostgreSQL_YAML.yml index ba19bdd2d0c..f81ff8b73d0 100644 --- a/.github/workflows/fit_Tomcat_PostgreSQL_YAML.yml +++ b/.github/workflows/fit_Tomcat_PostgreSQL_YAML.yml @@ -18,10 +18,10 @@ name: "FIT Tomcat PostgreSQL YAML" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/fit_WA_OIDCC4UI.yml b/.github/workflows/fit_WA_OIDCC4UI.yml index fc045e60f44..2479f9630e6 100644 --- a/.github/workflows/fit_WA_OIDCC4UI.yml +++ b/.github/workflows/fit_WA_OIDCC4UI.yml @@ -18,10 +18,10 @@ name: "FIT WA OIDCC4UI" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/fit_WA_OpenFGA.yml b/.github/workflows/fit_WA_OpenFGA.yml index 56680e70c06..e3d02139646 100644 --- a/.github/workflows/fit_WA_OpenFGA.yml +++ b/.github/workflows/fit_WA_OpenFGA.yml @@ -18,10 +18,10 @@ name: "FIT WA OpenFGA" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/fit_WA_SAML2SP4UI.yml b/.github/workflows/fit_WA_SAML2SP4UI.yml index 93881c49d34..de91920decb 100644 --- a/.github/workflows/fit_WA_SAML2SP4UI.yml +++ b/.github/workflows/fit_WA_SAML2SP4UI.yml @@ -18,10 +18,10 @@ name: "FIT WA SAML2SP4UI" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/fit_WA_SRA_CASClient.yml b/.github/workflows/fit_WA_SRA_CASClient.yml index f32f124ff1d..70b0663e08b 100644 --- a/.github/workflows/fit_WA_SRA_CASClient.yml +++ b/.github/workflows/fit_WA_SRA_CASClient.yml @@ -18,10 +18,10 @@ name: "FIT WA SRA CASClient" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/fit_WA_SRA_OAuth2.yml b/.github/workflows/fit_WA_SRA_OAuth2.yml index e016731bf4b..2370f0df88f 100644 --- a/.github/workflows/fit_WA_SRA_OAuth2.yml +++ b/.github/workflows/fit_WA_SRA_OAuth2.yml @@ -18,10 +18,10 @@ name: "FIT WA SRA OAuth2" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/fit_WA_SRA_OIDC.yml b/.github/workflows/fit_WA_SRA_OIDC.yml index 0360b68d726..b29a34fa785 100644 --- a/.github/workflows/fit_WA_SRA_OIDC.yml +++ b/.github/workflows/fit_WA_SRA_OIDC.yml @@ -18,10 +18,10 @@ name: "FIT WA SRA OIDC" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/fit_WA_SRA_SAML2.yml b/.github/workflows/fit_WA_SRA_SAML2.yml index b60f464740f..f3963a0a55e 100644 --- a/.github/workflows/fit_WA_SRA_SAML2.yml +++ b/.github/workflows/fit_WA_SRA_SAML2.yml @@ -18,10 +18,10 @@ name: "FIT WA SRA SAML2" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/fit_Wildfly.yml b/.github/workflows/fit_Wildfly.yml index 5e165174730..5407955dc40 100644 --- a/.github/workflows/fit_Wildfly.yml +++ b/.github/workflows/fit_Wildfly.yml @@ -18,10 +18,10 @@ name: "FIT Wildfly" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/fit_Zookeeper.yml b/.github/workflows/fit_Zookeeper.yml index c2ff40d05e9..dad2d64fb4d 100644 --- a/.github/workflows/fit_Zookeeper.yml +++ b/.github/workflows/fit_Zookeeper.yml @@ -18,10 +18,10 @@ name: "FIT Zookeeper" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/mariadb.yml b/.github/workflows/mariadb.yml index 8c2e2b7b1ea..45dd8232e08 100644 --- a/.github/workflows/mariadb.yml +++ b/.github/workflows/mariadb.yml @@ -18,10 +18,10 @@ name: "MariaDB" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/mysql.yml b/.github/workflows/mysql.yml index 30997151f9b..21fef5ee7bc 100644 --- a/.github/workflows/mysql.yml +++ b/.github/workflows/mysql.yml @@ -18,10 +18,10 @@ name: "MySQL" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/neo4j.yml b/.github/workflows/neo4j.yml index d698236c3fc..e7e9ad70232 100644 --- a/.github/workflows/neo4j.yml +++ b/.github/workflows/neo4j.yml @@ -18,10 +18,10 @@ name: "Neo4j" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' diff --git a/.github/workflows/oracle.yml b/.github/workflows/oracle.yml index 128a47b4d51..961d64fbc79 100644 --- a/.github/workflows/oracle.yml +++ b/.github/workflows/oracle.yml @@ -18,10 +18,10 @@ name: "Oracle" on: push: - branches: ['master', 'pr-*'] + branches: ['4_0_X', 'pr-*'] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [4_0_X] schedule: - cron: '0 13 * * 4' From 8247bdf275b4be529b3b9b5b696841c9fa3b04b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Mon, 7 Apr 2025 08:27:27 +0200 Subject: [PATCH 002/579] Upgrading Swagger UI and docker-maven-plugin --- pom.xml | 4 +- src/main/asciidoc/getting-started/obtain.adoc | 6 +-- .../concepts/attributerepositories.adoc | 4 +- .../reference-guide/concepts/audit.adoc | 2 +- .../concepts/authenticationmodules.adoc | 4 +- .../concepts/entitlements.adoc | 6 +-- .../reference-guide/concepts/extensions.adoc | 12 ++--- .../concepts/externalresources.adoc | 4 +- .../concepts/notifications.adoc | 4 +- .../reference-guide/concepts/policies.adoc | 46 +++++++++---------- .../concepts/provisioning/livesync.adoc | 6 +-- .../concepts/provisioning/propagation.adoc | 18 ++++---- .../concepts/provisioning/provisioning.adoc | 12 ++--- .../concepts/provisioning/pull.adoc | 18 ++++---- .../concepts/provisioning/push.adoc | 6 +-- .../reference-guide/concepts/realms.adoc | 2 +- .../reference-guide/concepts/reports.adoc | 2 +- .../reference-guide/concepts/routes.adoc | 4 +- .../reference-guide/concepts/tasks.adoc | 20 ++++---- .../concepts/typemanagement.adoc | 2 +- .../reference-guide/concepts/workflow.adoc | 24 +++++----- .../asciidoc/reference-guide/usage/core.adoc | 6 +-- .../reference-guide/usage/customization.adoc | 24 +++++----- src/main/asciidoc/syncope-theme.yml | 4 +- src/site/xdoc/integration.xml | 2 +- 25 files changed, 121 insertions(+), 121 deletions(-) diff --git a/pom.xml b/pom.xml index 1c6fb7c35ec..36643f82d69 100644 --- a/pom.xml +++ b/pom.xml @@ -447,7 +447,7 @@ under the License. 4.0.4 2.2.29 - 5.20.3 + 5.20.6 1.3.8 1.4.1-1 @@ -1733,7 +1733,7 @@ under the License. io.fabric8 docker-maven-plugin - 0.45.1 + 0.46.0 diff --git a/src/main/asciidoc/getting-started/obtain.adoc b/src/main/asciidoc/getting-started/obtain.adoc index 4f742f0c8a9..94910e82847 100644 --- a/src/main/asciidoc/getting-started/obtain.adoc +++ b/src/main/asciidoc/getting-started/obtain.adoc @@ -143,7 +143,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/tree/syncope-{docVersion}/docker/src/main/resources/docker-compose[available^]. endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/tree/master/docker/src/main/resources/docker-compose[available^]. +https://github.com/apache/syncope/tree/4_0_X/docker/src/main/resources/docker-compose[available^]. endif::[] .Core, Admin UI and Enduser UI with PostgreSQL, with embedded Keymaster @@ -396,7 +396,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/tree/syncope-{docVersion}/docker/src/main/resources/kubernetes[available^], endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/tree/master/docker/src/main/resources/kubernetes[available^], +https://github.com/apache/syncope/tree/4_0_X/docker/src/main/resources/kubernetes[available^], endif::[] that can be used to install Apache Syncope directly in Kubernetes. @@ -429,7 +429,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/tree/syncope-{docVersion}/docker/src/main/resources/kubernetes[folder^], endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/tree/master/docker/src/main/resources/kubernetes[folder^], +https://github.com/apache/syncope/tree/4_0_X/docker/src/main/resources/kubernetes[folder^], endif::[] wherever you downloaded it diff --git a/src/main/asciidoc/reference-guide/concepts/attributerepositories.adoc b/src/main/asciidoc/reference-guide/concepts/attributerepositories.adoc index 2e6d277a872..384ce4341df 100644 --- a/src/main/asciidoc/reference-guide/concepts/attributerepositories.adoc +++ b/src/main/asciidoc/reference-guide/concepts/attributerepositories.adoc @@ -37,14 +37,14 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/common/am/lib/src/main/java/org/apache/syncope/common/lib/attr/AttrRepoConf.java[AttrRepoConf^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/common/am/lib/src/main/java/org/apache/syncope/common/lib/attr/AttrRepoConf.java[AttrRepoConf^] +https://github.com/apache/syncope/blob/4_0_X/common/am/lib/src/main/java/org/apache/syncope/common/lib/attr/AttrRepoConf.java[AttrRepoConf^] endif::[] interface and extending appropriately the ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/wa/bootstrap/src/main/java/org/apache/syncope/wa/bootstrap/WAPropertySourceLocator.java[WAPropertySourceLocator^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/wa/bootstrap/src/main/java/org/apache/syncope/wa/bootstrap/WAPropertySourceLocator.java[WAPropertySourceLocator^] +https://github.com/apache/syncope/blob/4_0_X/wa/bootstrap/src/main/java/org/apache/syncope/wa/bootstrap/WAPropertySourceLocator.java[WAPropertySourceLocator^] endif::[] class. ==== diff --git a/src/main/asciidoc/reference-guide/concepts/audit.adoc b/src/main/asciidoc/reference-guide/concepts/audit.adoc index 03cb3a61ec4..5d55beafd33 100644 --- a/src/main/asciidoc/reference-guide/concepts/audit.adoc +++ b/src/main/asciidoc/reference-guide/concepts/audit.adoc @@ -40,6 +40,6 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditEventProcessor.java[AuditEventProcessor^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditEventProcessor.java[AuditEventProcessor^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AuditEventProcessor.java[AuditEventProcessor^] endif::[] interface. diff --git a/src/main/asciidoc/reference-guide/concepts/authenticationmodules.adoc b/src/main/asciidoc/reference-guide/concepts/authenticationmodules.adoc index 36ff2a6d5be..1e3f480ad53 100644 --- a/src/main/asciidoc/reference-guide/concepts/authenticationmodules.adoc +++ b/src/main/asciidoc/reference-guide/concepts/authenticationmodules.adoc @@ -50,14 +50,14 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/AuthModuleConf.java[AuthModuleConf^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/AuthModuleConf.java[AuthModuleConf^] +https://github.com/apache/syncope/blob/4_0_X/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/AuthModuleConf.java[AuthModuleConf^] endif::[] interface and extending appropriately the ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/wa/bootstrap/src/main/java/org/apache/syncope/wa/bootstrap/WAPropertySourceLocator.java[WAPropertySourceLocator^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/wa/bootstrap/src/main/java/org/apache/syncope/wa/bootstrap/WAPropertySourceLocator.java[WAPropertySourceLocator^] +https://github.com/apache/syncope/blob/4_0_X/wa/bootstrap/src/main/java/org/apache/syncope/wa/bootstrap/WAPropertySourceLocator.java[WAPropertySourceLocator^] endif::[] class. ==== diff --git a/src/main/asciidoc/reference-guide/concepts/entitlements.adoc b/src/main/asciidoc/reference-guide/concepts/entitlements.adoc index f4863c59b33..72021665536 100644 --- a/src/main/asciidoc/reference-guide/concepts/entitlements.adoc +++ b/src/main/asciidoc/reference-guide/concepts/entitlements.adoc @@ -27,7 +27,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RealmLogic.java[RealmLogic^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RealmLogic.java[RealmLogic^] +https://github.com/apache/syncope/blob/4_0_X/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RealmLogic.java[RealmLogic^] endif::[] , the https://docs.spring.io/spring-security/reference/6.4/servlet/authorization/method-security.html#authorization-expressions[`hasRole` expression^] @@ -50,14 +50,14 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/IdRepoEntitlement.java[statically defined^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/IdRepoEntitlement.java[statically defined^] +https://github.com/apache/syncope/blob/4_0_X/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/IdRepoEntitlement.java[statically defined^] endif::[] - even though <> have the ability to ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/FlowableEntitlement.java[enlarge the initial list^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/FlowableEntitlement.java[enlarge the initial list^] +https://github.com/apache/syncope/blob/4_0_X/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/FlowableEntitlement.java[enlarge the initial list^] endif::[] : this is because entitlements are the pillars of the internal security model and are not meant for external usage. ==== diff --git a/src/main/asciidoc/reference-guide/concepts/extensions.adoc b/src/main/asciidoc/reference-guide/concepts/extensions.adoc index 77c789c34b3..61eaaa6ab8a 100644 --- a/src/main/asciidoc/reference-guide/concepts/extensions.adoc +++ b/src/main/asciidoc/reference-guide/concepts/extensions.adoc @@ -54,7 +54,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/tree/syncope-{docVersion}/ext/saml2sp4ui[source tree^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/tree/master/ext/saml2sp4ui[source tree^] +https://github.com/apache/syncope/tree/4_0_X/ext/saml2sp4ui[source tree^] endif::[] . ==== @@ -88,7 +88,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/tree/syncope-{docVersion}/ext/oidcc4ui[source tree^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/tree/master/ext/oidcc4ui[source tree^] +https://github.com/apache/syncope/tree/4_0_X/ext/oidcc4ui[source tree^] endif::[] . ==== @@ -119,7 +119,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/tree/syncope-{docVersion}/ext/elasticsearch[source tree^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/tree/master/ext/elasticsearch[source tree^] +https://github.com/apache/syncope/tree/4_0_X/ext/elasticsearch[source tree^] endif::[] . ==== @@ -141,7 +141,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/tree/syncope-{docVersion}/ext/opensearch[source tree^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/tree/master/ext/opensearch[source tree^] +https://github.com/apache/syncope/tree/4_0_X/ext/opensearch[source tree^] endif::[] . ==== @@ -166,7 +166,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/tree/syncope-{docVersion}/ext/scimv2[source tree^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/tree/master/ext/scimv2[source tree^] +https://github.com/apache/syncope/tree/4_0_X/ext/scimv2[source tree^] endif::[] . ==== @@ -190,7 +190,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/tree/syncope-{docVersion}/ext/openfga[source tree^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/tree/master/ext/openfga[source tree^] +https://github.com/apache/syncope/tree/4_0_X/ext/openfga[source tree^] endif::[] . ==== diff --git a/src/main/asciidoc/reference-guide/concepts/externalresources.adoc b/src/main/asciidoc/reference-guide/concepts/externalresources.adoc index 182bc2b878e..240ce60ccf5 100644 --- a/src/main/asciidoc/reference-guide/concepts/externalresources.adoc +++ b/src/main/asciidoc/reference-guide/concepts/externalresources.adoc @@ -56,7 +56,7 @@ When defining a connector instance, the following information must be provided: * administration realm - the <> under which administrators need to own <> in order to be allowed to manage this connector and all related external resources * connector bundle - one of the several -https://github.com/Tirasa/ConnId/blob/master/README.md#available-connectors[already available^], or some to be +https://github.com/Tirasa/ConnId/blob/4_0_X/README.md#available-connectors[already available^], or some to be https://connid.atlassian.net/wiki/display/BASE/Create+new+connector[made from scratch^], in order to fulfill specific requirements * pooling information @@ -141,7 +141,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ItemTransformer.java[ItemTransformer^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ItemTransformer.java[ItemTransformer^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ItemTransformer.java[ItemTransformer^] endif::[] ; the purpose is to transform values before they are sent to or received from the underlying connector * mandatory condition - http://commons.apache.org/proper/commons-jexl/[JEXL^] expression indicating whether values for diff --git a/src/main/asciidoc/reference-guide/concepts/notifications.adoc b/src/main/asciidoc/reference-guide/concepts/notifications.adoc index d25d606aad9..7a82276a764 100644 --- a/src/main/asciidoc/reference-guide/concepts/notifications.adoc +++ b/src/main/asciidoc/reference-guide/concepts/notifications.adoc @@ -40,7 +40,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/notification/RecipientsProvider.java[RecipientsProvider^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/notification/RecipientsProvider.java[RecipientsProvider^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/notification/RecipientsProvider.java[RecipientsProvider^] endif::[] interface * <> - event(s) triggering the enclosing notification @@ -116,7 +116,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java[UserTO^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java[UserTO^] +https://github.com/apache/syncope/blob/4_0_X/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java[UserTO^] endif::[] with actual value matching the _about_ condition as introduced above, can be used. diff --git a/src/main/asciidoc/reference-guide/concepts/policies.adoc b/src/main/asciidoc/reference-guide/concepts/policies.adoc index 97342b3e1f5..6544d4654a4 100644 --- a/src/main/asciidoc/reference-guide/concepts/policies.adoc +++ b/src/main/asciidoc/reference-guide/concepts/policies.adoc @@ -69,21 +69,21 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/AccountRuleConf.java[AccountRuleConf^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/AccountRuleConf.java[AccountRuleConf^] +https://github.com/apache/syncope/blob/4_0_X/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/AccountRuleConf.java[AccountRuleConf^] endif::[] . enforcing in an implementation of ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/AccountRule.java[AccountRule^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/AccountRule.java[AccountRule^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/AccountRule.java[AccountRule^] endif::[] annotated via ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AccountRuleConfClass.java[@AccountRuleConfClass^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AccountRuleConfClass.java[@AccountRuleConfClass^] +https://github.com/apache/syncope/blob/4_0_X/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AccountRuleConfClass.java[@AccountRuleConfClass^] endif::[] referring to the configuration class. @@ -92,7 +92,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/AccountRule.java[AccountRule^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/AccountRule.java[AccountRule^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/AccountRule.java[AccountRule^] endif::[] ==== @@ -103,14 +103,14 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/spring/src/main/java/org/apache/syncope/core/spring/policy/DefaultAccountRule.java[DefaultAccountRule^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/spring/src/main/java/org/apache/syncope/core/spring/policy/DefaultAccountRule.java[DefaultAccountRule^] +https://github.com/apache/syncope/blob/4_0_X/core/spring/src/main/java/org/apache/syncope/core/spring/policy/DefaultAccountRule.java[DefaultAccountRule^] endif::[] and configurable via ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultAccountRuleConf.java[DefaultAccountRuleConf^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultAccountRuleConf.java[DefaultAccountRuleConf^] +https://github.com/apache/syncope/blob/4_0_X/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultAccountRuleConf.java[DefaultAccountRuleConf^] endif::[] ) contains the following controls: @@ -173,21 +173,21 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/PasswordRuleConf.java[PasswordRuleConf^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/PasswordRuleConf.java[PasswordRuleConf^] +https://github.com/apache/syncope/blob/4_0_X/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/PasswordRuleConf.java[PasswordRuleConf^] endif::[] . enforcing in an implementation of ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/PasswordRule.java[PasswordRule^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/PasswordRule.java[PasswordRule^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/PasswordRule.java[PasswordRule^] endif::[] annotated via ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PasswordRuleConfClass.java[@PasswordRuleConfClass^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PasswordRuleConfClass.java[@PasswordRuleConfClass^] +https://github.com/apache/syncope/blob/4_0_X/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PasswordRuleConfClass.java[@PasswordRuleConfClass^] endif::[] referring to the configuration class. @@ -196,7 +196,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/PasswordRule.java[PasswordRule^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/PasswordRule.java[PasswordRule^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/PasswordRule.java[PasswordRule^] endif::[] ==== @@ -207,14 +207,14 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/spring/src/main/java/org/apache/syncope/core/spring/policy/DefaultPasswordRule.java[DefaultPasswordRule^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/spring/src/main/java/org/apache/syncope/core/spring/policy/DefaultPasswordRule.java[DefaultPasswordRule^] +https://github.com/apache/syncope/blob/4_0_X/core/spring/src/main/java/org/apache/syncope/core/spring/policy/DefaultPasswordRule.java[DefaultPasswordRule^] endif::[] and configurable via ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultPasswordRuleConf.java[DefaultPasswordRuleConf^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultPasswordRuleConf.java[DefaultPasswordRuleConf^] +https://github.com/apache/syncope/blob/4_0_X/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultPasswordRuleConf.java[DefaultPasswordRuleConf^] endif::[] ) is based on https://www.passay.org/[Passay^] and contains the following controls: @@ -248,14 +248,14 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/spring/src/main/java/org/apache/syncope/core/spring/policy/HaveIBeenPwnedPasswordRule.java[HaveIBeenPwnedPasswordRule^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/spring/src/main/java/org/apache/syncope/core/spring/policy/HaveIBeenPwnedPasswordRule.java[HaveIBeenPwnedPasswordRule^] +https://github.com/apache/syncope/blob/4_0_X/core/spring/src/main/java/org/apache/syncope/core/spring/policy/HaveIBeenPwnedPasswordRule.java[HaveIBeenPwnedPasswordRule^] endif::[] and configurable via ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/HaveIBeenPwnedPasswordRuleConf.java[HaveIBeenPwnedPasswordRuleConf^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/HaveIBeenPwnedPasswordRuleConf.java[HaveIBeenPwnedPasswordRuleConf^] +https://github.com/apache/syncope/blob/4_0_X/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/HaveIBeenPwnedPasswordRuleConf.java[HaveIBeenPwnedPasswordRuleConf^] endif::[] ) checks the provided password values against the popular https://haveibeenpwned.com["Have I Been Pwned?"^] service. @@ -281,7 +281,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultAccessPolicyConf.java[DefaultAccessPolicyConf^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultAccessPolicyConf.java[DefaultAccessPolicyConf^] +https://github.com/apache/syncope/blob/4_0_X/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultAccessPolicyConf.java[DefaultAccessPolicyConf^] endif::[] | It describes whether the client application is allowed to use WA, allowed to participate in single sign-on authentication, etc; additionally, it may be configured to require a certain set of principal attributes that must exist @@ -292,7 +292,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/HttpRequestAccessPolicyConf.java[HttpRequestAccessPolicyConf^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/HttpRequestAccessPolicyConf.java[HttpRequestAccessPolicyConf^] +https://github.com/apache/syncope/blob/4_0_X/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/HttpRequestAccessPolicyConf.java[HttpRequestAccessPolicyConf^] endif::[] | Make access decisions based on HTTP request properties as client IP address and user-agent. @@ -301,7 +301,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/OpenFGAAccessPolicyConf.java[OpenFGAAccessPolicyConf^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/OpenFGAAccessPolicyConf.java[OpenFGAAccessPolicyConf^] +https://github.com/apache/syncope/blob/4_0_X/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/OpenFGAAccessPolicyConf.java[OpenFGAAccessPolicyConf^] endif::[] | Builds an authorization request and submits it to https://openfga.dev/[OpenFGA^]'s `check` API endpoint. @@ -310,7 +310,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/RemoteEndpointAccessPolicyConf.java[RemoteEndpointAccessPolicyConf^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/RemoteEndpointAccessPolicyConf.java[RemoteEndpointAccessPolicyConf^] +https://github.com/apache/syncope/blob/4_0_X/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/RemoteEndpointAccessPolicyConf.java[RemoteEndpointAccessPolicyConf^] endif::[] | Delegate access decisions to a remote endpoint by receiving the authenticated principal as url parameter of a `GET` request; the response code that the endpoint returns is then compared against the policy setting and if a match is @@ -321,7 +321,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/TimeBasedAccessPolicyConf.java[TimeBasedAccessPolicyConf^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/TimeBasedAccessPolicyConf.java[TimeBasedAccessPolicyConf^] +https://github.com/apache/syncope/blob/4_0_X/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/TimeBasedAccessPolicyConf.java[TimeBasedAccessPolicyConf^] endif::[] | Access is only allowed within the configured timeframe. @@ -425,7 +425,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultInboundCorrelationRule.java[default^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultInboundCorrelationRule.java[default^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultInboundCorrelationRule.java[default^] endif::[] implementation attempts to match entities on the basis of the values of the provided plain attributes, according to the available <>. @@ -437,7 +437,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/InboundCorrelationRule.java[InboundCorrelationRule^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/InboundCorrelationRule.java[InboundCorrelationRule^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/InboundCorrelationRule.java[InboundCorrelationRule^] endif::[] interface. ==== @@ -463,7 +463,7 @@ https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-ja ] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPushCorrelationRule.java[default^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPushCorrelationRule.java[default^] endif::[] implementation attempts to match entities on the basis of the values of the provided plain attributes, according to the available <>. @@ -475,7 +475,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/PushCorrelationRule.java[PushCorrelationRule^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/PushCorrelationRule.java[PushCorrelationRule^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/PushCorrelationRule.java[PushCorrelationRule^] endif::[] interface. ==== diff --git a/src/main/asciidoc/reference-guide/concepts/provisioning/livesync.adoc b/src/main/asciidoc/reference-guide/concepts/provisioning/livesync.adoc index 67352700d8b..962c5d0c6b9 100644 --- a/src/main/asciidoc/reference-guide/concepts/provisioning/livesync.adoc +++ b/src/main/asciidoc/reference-guide/concepts/provisioning/livesync.adoc @@ -34,14 +34,14 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisionSorter.java[ProvisionSorter^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisionSorter.java[ProvisionSorter^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisionSorter.java[ProvisionSorter^] endif::[] or its default implementation ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultProvisionSorter.java[DefaultProvisionSorter^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultProvisionSorter.java[DefaultProvisionSorter^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultProvisionSorter.java[DefaultProvisionSorter^] endif::[] . @@ -50,7 +50,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/LiveSyncDeltaMapper.java[LiveSyncDeltaMapper^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/LiveSyncDeltaMapper.java[LiveSyncDeltaMapper^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/LiveSyncDeltaMapper.java[LiveSyncDeltaMapper^] endif::[] is invoked to transform the record into a format which is in turn provided to an internally created and processed <>. diff --git a/src/main/asciidoc/reference-guide/concepts/provisioning/propagation.adoc b/src/main/asciidoc/reference-guide/concepts/provisioning/propagation.adoc index 0a0edc296bf..5b75b234e96 100644 --- a/src/main/asciidoc/reference-guide/concepts/provisioning/propagation.adoc +++ b/src/main/asciidoc/reference-guide/concepts/provisioning/propagation.adoc @@ -74,7 +74,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java[PriorityPropagationTaskExecutor^], endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java[PriorityPropagationTaskExecutor^], +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java[PriorityPropagationTaskExecutor^], endif::[] which implements the following logic: @@ -109,7 +109,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskExecutor.java[PropagationTaskExecutor^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskExecutor.java[PropagationTaskExecutor^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskExecutor.java[PropagationTaskExecutor^] endif::[] interface can be provided, in case the required behavior does not fit into the provided implementation. @@ -121,7 +121,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationActions.java[PropagationActions^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationActions.java[PropagationActions^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationActions.java[PropagationActions^] endif::[] interface. @@ -135,7 +135,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AzurePropagationActions.java[AzurePropagationActions^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/tree/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AzurePropagationActions.java[AzurePropagationActions^] +https://github.com/apache/syncope/tree/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AzurePropagationActions.java[AzurePropagationActions^] endif::[] | Required for setup of an External Resource based on the https://connid.atlassian.net/wiki/display/BASE/Azure#Azure-Configuration[ConnId Azure connector bundle^]. @@ -144,7 +144,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DBPasswordPropagationActions.java[DBPasswordPropagationActions^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DBPasswordPropagationActions.java[DBPasswordPropagationActions^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DBPasswordPropagationActions.java[DBPasswordPropagationActions^] endif::[] | If no password value was already provided in the propagation task, sends out the internal password hash value to DBMS; the cipher algorithm associated with the password must match the value of `Password cipher algorithm` for the @@ -155,7 +155,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/GenerateRandomPasswordPropagationActions.java[GenerateRandomPasswordPropagationActions^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/tree/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/GenerateRandomPasswordPropagationActions.java[GenerateRandomPasswordPropagationActions^] +https://github.com/apache/syncope/tree/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/GenerateRandomPasswordPropagationActions.java[GenerateRandomPasswordPropagationActions^] endif::[] | If no password value was already provided in the propagation task, random password value is generated according to the defined <> and sent to the External Resource. @@ -164,7 +164,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/GoogleAppsPropagationActions.java[GoogleAppsPropagationActions^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/tree/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/GoogleAppsPropagationActions.java[GoogleAppsPropagationActions^] +https://github.com/apache/syncope/tree/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/GoogleAppsPropagationActions.java[GoogleAppsPropagationActions^] endif::[] | Required for setup of an External Resource based on the https://connid.atlassian.net/wiki/display/BASE/Google+Apps#GoogleApps-Configuration[ConnId GoogleApps connector bundle^]. @@ -173,7 +173,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java[LDAPMembershipPropagationActions^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java[LDAPMembershipPropagationActions^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java[LDAPMembershipPropagationActions^] endif::[] | If a User is associated with a Group in Syncope, keep the corresponding User as a member of the corresponding Group in LDAP or AD. @@ -182,7 +182,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPPasswordPropagationActions.java[LDAPPasswordPropagationActions^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPPasswordPropagationActions.java[LDAPPasswordPropagationActions^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPPasswordPropagationActions.java[LDAPPasswordPropagationActions^] endif::[] | If no password value was already provided in the propagation task, sends out the internal password hash value to LDAP; the cipher algorithm associated with the password must match the value of `passwordHashAlgorithm` for the diff --git a/src/main/asciidoc/reference-guide/concepts/provisioning/provisioning.adoc b/src/main/asciidoc/reference-guide/concepts/provisioning/provisioning.adoc index a2ef2d643e7..95aebec3b71 100644 --- a/src/main/asciidoc/reference-guide/concepts/provisioning/provisioning.adoc +++ b/src/main/asciidoc/reference-guide/concepts/provisioning/provisioning.adoc @@ -48,19 +48,19 @@ ifeval::["{snapshotOrRelease}" == "release"] * https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java[UserProvisioningManager^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -* https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java[UserProvisioningManager^] +* https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/UserProvisioningManager.java[UserProvisioningManager^] endif::[] ifeval::["{snapshotOrRelease}" == "release"] * https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java[GroupProvisioningManager^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -* https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java[GroupProvisioningManager^] +* https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/GroupProvisioningManager.java[GroupProvisioningManager^] endif::[] ifeval::["{snapshotOrRelease}" == "release"] * https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java[AnyObjectProvisioningManager^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -* https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java[AnyObjectProvisioningManager^] +* https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/AnyObjectProvisioningManager.java[AnyObjectProvisioningManager^] endif::[] Default implementations are available: @@ -69,19 +69,19 @@ ifeval::["{snapshotOrRelease}" == "release"] * https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java[DefaultUserProvisioningManager^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -* https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java[DefaultUserProvisioningManager^] +* https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java[DefaultUserProvisioningManager^] endif::[] ifeval::["{snapshotOrRelease}" == "release"] * https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java[DefaultGroupProvisioningManager^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -* https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java[DefaultGroupProvisioningManager^] +* https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java[DefaultGroupProvisioningManager^] endif::[] ifeval::["{snapshotOrRelease}" == "release"] * https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java[DefaultAnyObjectProvisioningManager^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -* https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java[DefaultAnyObjectProvisioningManager^] +* https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java[DefaultAnyObjectProvisioningManager^] endif::[] ==== diff --git a/src/main/asciidoc/reference-guide/concepts/provisioning/pull.adoc b/src/main/asciidoc/reference-guide/concepts/provisioning/pull.adoc index 89a8bbff382..6d25aa6eae8 100644 --- a/src/main/asciidoc/reference-guide/concepts/provisioning/pull.adoc +++ b/src/main/asciidoc/reference-guide/concepts/provisioning/pull.adoc @@ -28,14 +28,14 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisionSorter.java[ProvisionSorter^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisionSorter.java[ProvisionSorter^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisionSorter.java[ProvisionSorter^] endif::[] or its default implementation ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultProvisionSorter.java[DefaultProvisionSorter^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultProvisionSorter.java[DefaultProvisionSorter^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultProvisionSorter.java[DefaultProvisionSorter^] endif::[] . @@ -79,7 +79,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ReconFilterBuilder.java[ReconFilterBuilder^]) endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ReconFilterBuilder.java[ReconFilterBuilder^]) +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ReconFilterBuilder.java[ReconFilterBuilder^]) endif::[] of all available entities is processed. INCREMENTAL:: Only the actual modifications performed since the last pull task execution are considered. This mode @@ -110,7 +110,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/InboundActions.java[InboundActions^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/InboundActions.java[InboundActions^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/InboundActions.java[InboundActions^] endif::[] interface. @@ -124,7 +124,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/ADMembershipPullActions.java[ADMembershipPullActions^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/ADMembershipPullActions.java[ADMembershipPullActions^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/ADMembershipPullActions.java[ADMembershipPullActions^] endif::[] | If a User is associated with a Group in AD, keep the corresponding User as a member of the corresponding Group in Syncope. @@ -133,7 +133,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java[LDAPMembershipPullActions^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java[LDAPMembershipPullActions^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java[LDAPMembershipPullActions^] endif::[] | If a User is associated with a Group in LDAP, keep the corresponding User as a member of the corresponding Group in Syncope. @@ -142,7 +142,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java[LDAPPasswordPullActions^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java[LDAPPasswordPullActions^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java[LDAPPasswordPullActions^] endif::[] | Import hashed password values from LDAP; the cipher algorithm associated with the password must match the value of `passwordHashAlgorithm` for the @@ -153,7 +153,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java[DBPasswordPullActions^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java[DBPasswordPullActions^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java[DBPasswordPullActions^] endif::[] | Import hashed password values from DBMS; the cipher algorithm associated with the password must match the value of `Password cipher algorithm` for the @@ -164,7 +164,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/KafkaInboundActions.java[KafkaInboundActions^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/KafkaInboundActions.java[KafkaInboundActions^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/KafkaInboundActions.java[KafkaInboundActions^] endif::[] | Instructs to fetch the attributes required during the <> process for the https://connid.atlassian.net/wiki/display/BASE/Kafka[Apache Kafka connector bundle^]. diff --git a/src/main/asciidoc/reference-guide/concepts/provisioning/push.adoc b/src/main/asciidoc/reference-guide/concepts/provisioning/push.adoc index 699b5661df1..4be2f6151e0 100644 --- a/src/main/asciidoc/reference-guide/concepts/provisioning/push.adoc +++ b/src/main/asciidoc/reference-guide/concepts/provisioning/push.adoc @@ -29,14 +29,14 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisionSorter.java[ProvisionSorter^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisionSorter.java[ProvisionSorter^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ProvisionSorter.java[ProvisionSorter^] endif::[] or its default implementation ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultProvisionSorter.java[DefaultProvisionSorter^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultProvisionSorter.java[DefaultProvisionSorter^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultProvisionSorter.java[DefaultProvisionSorter^] endif::[] . @@ -75,6 +75,6 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PushActions.java[PushActions^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PushActions.java[PushActions^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PushActions.java[PushActions^] endif::[] interface. diff --git a/src/main/asciidoc/reference-guide/concepts/realms.adoc b/src/main/asciidoc/reference-guide/concepts/realms.adoc index bf06dd9baf4..b1c01c9d218 100644 --- a/src/main/asciidoc/reference-guide/concepts/realms.adoc +++ b/src/main/asciidoc/reference-guide/concepts/realms.adoc @@ -79,7 +79,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/api/LogicActions.java[LogicActions^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/api/LogicActions.java[LogicActions^] +https://github.com/apache/syncope/blob/4_0_X/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/api/LogicActions.java[LogicActions^] endif::[] interface. diff --git a/src/main/asciidoc/reference-guide/concepts/reports.adoc b/src/main/asciidoc/reference-guide/concepts/reports.adoc index 428933142b2..be1df0f6c6a 100644 --- a/src/main/asciidoc/reference-guide/concepts/reports.adoc +++ b/src/main/asciidoc/reference-guide/concepts/reports.adoc @@ -29,7 +29,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/AbstractReportJobDelegate.java[AbstractReportJobDelegate^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/AbstractReportJobDelegate.java[AbstractReportJobDelegate^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/AbstractReportJobDelegate.java[AbstractReportJobDelegate^] endif::[] providing the custom logic to extract information from Syncope and generate output according to the configured mime type * scheduling information: diff --git a/src/main/asciidoc/reference-guide/concepts/routes.adoc b/src/main/asciidoc/reference-guide/concepts/routes.adoc index 761e5b100c4..8c632f93fe4 100644 --- a/src/main/asciidoc/reference-guide/concepts/routes.adoc +++ b/src/main/asciidoc/reference-guide/concepts/routes.adoc @@ -68,7 +68,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/sra/src/main/java/org/apache/syncope/sra/predicates/CustomRoutePredicateFactory.java[CustomRoutePredicateFactory^]. endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/sra/src/main/java/org/apache/syncope/sra/predicates/CustomRoutePredicateFactory.java[CustomRoutePredicateFactory^]. +https://github.com/apache/syncope/blob/4_0_X/sra/src/main/java/org/apache/syncope/sra/predicates/CustomRoutePredicateFactory.java[CustomRoutePredicateFactory^]. endif::[] ==== Filters @@ -116,5 +116,5 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/sra/src/main/java/org/apache/syncope/sra/filters/CustomGatewayFilterFactory.java[CustomGatewayFilterFactory^]. endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/sra/src/main/java/org/apache/syncope/sra/filters/CustomGatewayFilterFactory.java[CustomGatewayFilterFactory^]. +https://github.com/apache/syncope/blob/4_0_X/sra/src/main/java/org/apache/syncope/sra/filters/CustomGatewayFilterFactory.java[CustomGatewayFilterFactory^]. endif::[] diff --git a/src/main/asciidoc/reference-guide/concepts/tasks.adoc b/src/main/asciidoc/reference-guide/concepts/tasks.adoc index fe9c3fc9f50..aee40faa075 100644 --- a/src/main/asciidoc/reference-guide/concepts/tasks.adoc +++ b/src/main/asciidoc/reference-guide/concepts/tasks.adoc @@ -24,7 +24,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/api/Command.java[Command^], endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/api/Command.java[Command^], +https://github.com/apache/syncope/blob/4_0_X/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/api/Command.java[Command^], endif::[] interface, designed to optionally take parameters. @@ -66,14 +66,14 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationManager.java[PropagationManager^], endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationManager.java[PropagationManager^], +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationManager.java[PropagationManager^], endif::[] executed (by default) via the ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java[PriorityPropagationTaskExecutor^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java[PriorityPropagationTaskExecutor^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java[PriorityPropagationTaskExecutor^] endif::[] during the <> process, and are permanently saved - for later re-execution or for examining the execution details - depending on the trace levels set on the related @@ -110,7 +110,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java[PullJobDelegate^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java[PullJobDelegate^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java[PullJobDelegate^] endif::[] during the <> process, and are permanently saved - for later re-execution or for examining the execution details - depending on the trace level set on the related @@ -158,7 +158,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LiveSyncJobDelegate.java[LiveSyncJobDelegate^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LiveSyncJobDelegate.java[LiveSyncJobDelegate^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LiveSyncJobDelegate.java[LiveSyncJobDelegate^] endif::[] during the <> process; the execution results are permanently saved - for examining the execution details - depending on the trace level set on the related <>. @@ -198,7 +198,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java[PushJobDelegate^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java[PushJobDelegate^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java[PushJobDelegate^] endif::[] during the <> process, and are permanently saved - for later re-execution or for examining the execution details - depending on the trace level set on the related @@ -232,14 +232,14 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManager.java[NotificationManager^], endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManager.java[NotificationManager^], +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManager.java[NotificationManager^], endif::[] executed via the ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/NotificationJob.java[NotificationJob^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/NotificationJob.java[NotificationJob^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/NotificationJob.java[NotificationJob^] endif::[] and are permanently saved - for later re-execution or for examining the execution details - depending on the trace level set on the related <>. @@ -268,7 +268,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/api/MacroActions.java[MacroActions^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/api/MacroActions.java[MacroActions^] +https://github.com/apache/syncope/blob/4_0_X/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/api/MacroActions.java[MacroActions^] endif::[] interface. @@ -284,7 +284,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java[AbstractSchedTaskJobDelegate^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java[AbstractSchedTaskJobDelegate^] +https://github.com/apache/syncope/blob/4_0_X/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java[AbstractSchedTaskJobDelegate^] endif::[] providing the custom logic to execute * scheduling information: diff --git a/src/main/asciidoc/reference-guide/concepts/typemanagement.adoc b/src/main/asciidoc/reference-guide/concepts/typemanagement.adoc index e5e66bdda97..14ea0806afc 100644 --- a/src/main/asciidoc/reference-guide/concepts/typemanagement.adoc +++ b/src/main/asciidoc/reference-guide/concepts/typemanagement.adoc @@ -58,7 +58,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/attrvalue/EmailAddressValidator.java[EmailAddressValidator^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/attrvalue/EmailAddressValidator.java[EmailAddressValidator^] +https://github.com/apache/syncope/blob/4_0_X/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/attrvalue/EmailAddressValidator.java[EmailAddressValidator^] endif::[] for reference * Mandatory condition - http://commons.apache.org/proper/commons-jexl/[JEXL^] expression indicating whether values for diff --git a/src/main/asciidoc/reference-guide/concepts/workflow.adoc b/src/main/asciidoc/reference-guide/concepts/workflow.adoc index 19a755877c1..6a0fd9208ff 100644 --- a/src/main/asciidoc/reference-guide/concepts/workflow.adoc +++ b/src/main/asciidoc/reference-guide/concepts/workflow.adoc @@ -35,19 +35,19 @@ ifeval::["{snapshotOrRelease}" == "release"] * https://github.com/apache/syncope/blob/syncope-{docVersion}/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java[UserWorkflowAdapter^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -* https://github.com/apache/syncope/blob/master/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java[UserWorkflowAdapter^] +* https://github.com/apache/syncope/blob/4_0_X/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java[UserWorkflowAdapter^] endif::[] ifeval::["{snapshotOrRelease}" == "release"] * https://github.com/apache/syncope/blob/syncope-{docVersion}/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/GroupWorkflowAdapter.java[GroupWorkflowAdapter^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -* https://github.com/apache/syncope/blob/master/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/GroupWorkflowAdapter.java[GroupWorkflowAdapter^] +* https://github.com/apache/syncope/blob/4_0_X/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/GroupWorkflowAdapter.java[GroupWorkflowAdapter^] endif::[] ifeval::["{snapshotOrRelease}" == "release"] * https://github.com/apache/syncope/blob/syncope-{docVersion}/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/AnyObjectWorkflowAdapter.java[AnyObjectWorkflowAdapter^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -* https://github.com/apache/syncope/blob/master/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/AnyObjectWorkflowAdapter.java[AnyObjectWorkflowAdapter^] +* https://github.com/apache/syncope/blob/4_0_X/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/AnyObjectWorkflowAdapter.java[AnyObjectWorkflowAdapter^] endif::[] Default implementations are available: @@ -56,19 +56,19 @@ ifeval::["{snapshotOrRelease}" == "release"] * https://github.com/apache/syncope/blob/syncope-{docVersion}/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java[DefaultUserWorkflowAdapter^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -* https://github.com/apache/syncope/blob/master/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java[DefaultUserWorkflowAdapter^] +* https://github.com/apache/syncope/blob/4_0_X/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java[DefaultUserWorkflowAdapter^] endif::[] ifeval::["{snapshotOrRelease}" == "release"] * https://github.com/apache/syncope/blob/syncope-{docVersion}/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultGroupWorkflowAdapter.java[DefaultGroupWorkflowAdapter^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -* https://github.com/apache/syncope/blob/master/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultGroupWorkflowAdapter.java[DefaultGroupWorkflowAdapter^] +* https://github.com/apache/syncope/blob/4_0_X/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultGroupWorkflowAdapter.java[DefaultGroupWorkflowAdapter^] endif::[] ifeval::["{snapshotOrRelease}" == "release"] * https://github.com/apache/syncope/blob/syncope-{docVersion}/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultAnyObjectWorkflowAdapter.java[DefaultAnyObjectWorkflowAdapter^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -* https://github.com/apache/syncope/blob/master/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultAnyObjectWorkflowAdapter.java[DefaultAnyObjectWorkflowAdapter^] +* https://github.com/apache/syncope/blob/4_0_X/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultAnyObjectWorkflowAdapter.java[DefaultAnyObjectWorkflowAdapter^] endif::[] Custom adapters can be provided by implementing the related interfaces, also as bridges towards third-party tools as @@ -86,14 +86,14 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java[DefaultUserWorkflowAdapter^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/tree/master/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java[DefaultUserWorkflowAdapter^] +https://github.com/apache/syncope/tree/4_0_X/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java[DefaultUserWorkflowAdapter^] endif::[] . No approval nor customizations needed? Stick with ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java[DefaultUserWorkflowAdapter^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/tree/master/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java[DefaultUserWorkflowAdapter^] +https://github.com/apache/syncope/tree/4_0_X/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java[DefaultUserWorkflowAdapter^] endif::[] ==== @@ -107,14 +107,14 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserWorkflowAdapter.java[FlowableUserWorkflowAdapter^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserWorkflowAdapter.java[FlowableUserWorkflowAdapter^] +https://github.com/apache/syncope/blob/4_0_X/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserWorkflowAdapter.java[FlowableUserWorkflowAdapter^] endif::[] is bootstrapped from ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/ext/flowable/flowable-bpmn/src/main/resources/userWorkflow.bpmn20.xml[userWorkflow.bpmn20.xml^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/ext/flowable/flowable-bpmn/src/main/resources/userWorkflow.bpmn20.xml[userWorkflow.bpmn20.xml^] +https://github.com/apache/syncope/blob/4_0_X/ext/flowable/flowable-bpmn/src/main/resources/userWorkflow.bpmn20.xml[userWorkflow.bpmn20.xml^] endif::[] and presents several advantages and more features, if compared to the default user adapter: @@ -264,7 +264,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/DropdownValueProvider.java[DropdownValueProvider^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/DropdownValueProvider.java[DropdownValueProvider^] +https://github.com/apache/syncope/blob/4_0_X/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/DropdownValueProvider.java[DropdownValueProvider^] endif::[] interface <3> the second form is a traditional approval form, as seen <> @@ -273,7 +273,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/task/FlowableServiceTask.java[FlowableServiceTask^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/task/FlowableServiceTask.java[FlowableServiceTask^] +https://github.com/apache/syncope/blob/4_0_X/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/task/FlowableServiceTask.java[FlowableServiceTask^] endif::[] implementation which takes care of establishing the relationship ==== diff --git a/src/main/asciidoc/reference-guide/usage/core.adoc b/src/main/asciidoc/reference-guide/usage/core.adoc index 7ef65467f0c..997a6f3db52 100644 --- a/src/main/asciidoc/reference-guide/usage/core.adoc +++ b/src/main/asciidoc/reference-guide/usage/core.adoc @@ -69,7 +69,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/spring/src/main/resources/securityContext.xml[securityContext.xml^]; endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/spring/src/main/resources/securityContext.xml[securityContext.xml^]; +https://github.com/apache/syncope/blob/4_0_X/core/spring/src/main/resources/securityContext.xml[securityContext.xml^]; endif::[] while normally not needed, this configuration can be anyway customized via the <>. @@ -84,7 +84,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTSSOProvider.java[JWTSSOProvider^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/tree/master/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTSSOProvider.java[JWTSSOProvider^] +https://github.com/apache/syncope/tree/4_0_X/core/spring/src/main/java/org/apache/syncope/core/spring/security/JWTSSOProvider.java[JWTSSOProvider^] endif::[] interface. @@ -159,7 +159,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java[ClientExceptionType^]) endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java[ClientExceptionType^]) +https://github.com/apache/syncope/blob/4_0_X/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java[ClientExceptionType^]) endif::[] and `X-Application-Error-Info` might be optionally populated with more details, if available. diff --git a/src/main/asciidoc/reference-guide/usage/customization.adoc b/src/main/asciidoc/reference-guide/usage/customization.adoc index 9a975dcb9f6..4a7013ceb5d 100644 --- a/src/main/asciidoc/reference-guide/usage/customization.adoc +++ b/src/main/asciidoc/reference-guide/usage/customization.adoc @@ -137,7 +137,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/core/spring/src/main/java/org/apache/syncope/core/spring/security/UsernamePasswordAuthenticationProvider.java[UsernamePasswordAuthenticationProvider^]. endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/core/spring/src/main/java/org/apache/syncope/core/spring/security/UsernamePasswordAuthenticationProvider.java[UsernamePasswordAuthenticationProvider^]. +https://github.com/apache/syncope/blob/4_0_X/core/spring/src/main/java/org/apache/syncope/core/spring/security/UsernamePasswordAuthenticationProvider.java[UsernamePasswordAuthenticationProvider^]. endif::[] The same happens with resources as images or HTML files; if you place @@ -149,7 +149,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html[BasePage.html^]. endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html[BasePage.html^]. +https://github.com/apache/syncope/blob/4_0_X/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.html[BasePage.html^]. endif::[] ===== Extending configuration @@ -285,13 +285,13 @@ ifeval::["{snapshotOrRelease}" == "release"] * https://github.com/apache/syncope/blob/syncope-{docVersion}/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java[PersistenceContext^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -* https://github.com/apache/syncope/blob/master/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java[PersistenceContext^] +* https://github.com/apache/syncope/blob/4_0_X/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java[PersistenceContext^] endif::[] ifeval::["{snapshotOrRelease}" == "release"] * https://github.com/apache/syncope/blob/syncope-{docVersion}/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/MasterDomain.java[MasterDomain^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -* https://github.com/apache/syncope/blob/master/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/MasterDomain.java[MasterDomain^] +* https://github.com/apache/syncope/blob/4_0_X/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/MasterDomain.java[MasterDomain^] endif::[] The `@Bean` declarations from these classes can be customized as explained <>. @@ -391,7 +391,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchClientContext.java[ElasticsearchClientContext^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchClientContext.java[ElasticsearchClientContext^] +https://github.com/apache/syncope/blob/4_0_X/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchClientContext.java[ElasticsearchClientContext^] endif::[] as explained <>. @@ -444,7 +444,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/ext/opensearch/client-opensearch/src/main/java/org/apache/syncope/ext/opensearch/client/OpenSearchClientContext.java[OpenSearchClientContext^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/ext/opensearch/client-opensearch/src/main/java/org/apache/syncope/ext/opensearch/client/OpenSearchClientContext.java[OpenSearchClientContext^] +https://github.com/apache/syncope/blob/4_0_X/ext/opensearch/client-opensearch/src/main/java/org/apache/syncope/ext/opensearch/client/OpenSearchClientContext.java[OpenSearchClientContext^] endif::[] as explained <>. @@ -503,7 +503,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/ext/openfga/client-openfga/src/main/java/org/apache/syncope/ext/openfga/client/OpenFGAProperties.java[OpenFGAProperties^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/ext/openfga/client-openfga/src/main/java/org/apache/syncope/ext/openfga/client/OpenFGAProperties.java[OpenFGAProperties^] +https://github.com/apache/syncope/blob/4_0_X/ext/openfga/client-openfga/src/main/java/org/apache/syncope/ext/openfga/client/OpenFGAProperties.java[OpenFGAProperties^] endif::[] . @@ -516,7 +516,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/ext/openfga/client-openfga/src/main/java/org/apache/syncope/ext/openfga/client/OpenFGAClientContext.java[OpenFGAClientContext^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/ext/openfga/client-openfga/src/main/java/org/apache/syncope/ext/openfga/client/OpenFGAClientContext.java[OpenFGAClientContext^] +https://github.com/apache/syncope/blob/4_0_X/ext/openfga/client-openfga/src/main/java/org/apache/syncope/ext/openfga/client/OpenFGAClientContext.java[OpenFGAClientContext^] endif::[] as explained <>. @@ -540,7 +540,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/BpmnProcessService.java[BpmnProcessService^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/BpmnProcessService.java[BpmnProcessService^] +https://github.com/apache/syncope/blob/4_0_X/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/BpmnProcessService.java[BpmnProcessService^] endif::[] for reference; . if needed, define supporting payload objects - in an extension's `common-lib` module or under `common` otherwise; @@ -549,7 +549,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/BpmnProcess.java[BpmnProcess^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/BpmnProcess.java[BpmnProcess^] +https://github.com/apache/syncope/blob/4_0_X/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/BpmnProcess.java[BpmnProcess^] endif::[] for reference; . implement - in an extension's `rest-cxf` module or under `core` otherwise - the interface defined above in a Java @@ -558,7 +558,7 @@ ifeval::["{snapshotOrRelease}" == "release"] https://github.com/apache/syncope/blob/syncope-{docVersion}/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/BpmnProcessServiceImpl.java[BpmnProcessServiceImpl^] endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] -https://github.com/apache/syncope/blob/master/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/BpmnProcessServiceImpl.java[BpmnProcessServiceImpl^] +https://github.com/apache/syncope/blob/4_0_X/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/BpmnProcessServiceImpl.java[BpmnProcessServiceImpl^] endif::[] for reference. @@ -712,5 +712,5 @@ available at runtime. <> can be part of a local project, to encapsulate special features which are specific to a given deployment. For example, the http://www.chorevolution.eu/[CHOReVOLUTION^] IdM - based on Apache Syncope - provides -https://gitlab.ow2.org/chorevolution/syncope/tree/master/ext/choreography[an extension^] +https://gitlab.ow2.org/chorevolution/syncope/tree/4_0_X/ext/choreography[an extension^] for managing via the <> and visualizing via the <> the running choreography instances. diff --git a/src/main/asciidoc/syncope-theme.yml b/src/main/asciidoc/syncope-theme.yml index a4b99a0f1b6..74ca7afc852 100644 --- a/src/main/asciidoc/syncope-theme.yml +++ b/src/main/asciidoc/syncope-theme.yml @@ -13,8 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Fork from https://github.com/asciidoctor/asciidoctor-pdf/blob/master/data/themes/default-theme.yml -# PDF styling guide: https://github.com/asciidoctor/asciidoctor-pdf/blob/master/docs/theming-guide.adoc +# Fork from https://github.com/asciidoctor/asciidoctor-pdf/blob/4_0_X/data/themes/default-theme.yml +# PDF styling guide: https://github.com/asciidoctor/asciidoctor-pdf/blob/4_0_X/docs/theming-guide.adoc page: background_color: ffffff diff --git a/src/site/xdoc/integration.xml b/src/site/xdoc/integration.xml index c4dd9fe0a8f..b46886c8358 100644 --- a/src/site/xdoc/integration.xml +++ b/src/site/xdoc/integration.xml @@ -47,7 +47,7 @@ under the License.

- 4_0_X + 4_0_X

3_0_X From 0c0aa8ad26ffe836d750d9b2a6777f8a62ecc1ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Tue, 8 Apr 2025 08:40:16 +0200 Subject: [PATCH 003/579] Upgrading Nimbus JOSE JWT and Swagger --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 36643f82d69..a16d0544e90 100644 --- a/pom.xml +++ b/pom.xml @@ -413,7 +413,7 @@ under the License. 4.1.1 1.80 - 10.1 + 10.2 3.4.4 4.2.1 @@ -446,8 +446,8 @@ under the License. 7.2.0 4.0.4 - 2.2.29 - 5.20.6 + 2.2.30 + 5.20.7 1.3.8 1.4.1-1 From 287c1276488987ed4fd680c0f41a113044120950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Wed, 9 Apr 2025 08:20:09 +0200 Subject: [PATCH 004/579] Upgrading cargo-maven3-plugin --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a16d0544e90..784c93a73b5 100644 --- a/pom.xml +++ b/pom.xml @@ -1668,7 +1668,7 @@ under the License. org.codehaus.cargo cargo-maven3-plugin - 1.10.18 + 1.10.19 ${project.build.directory}/log/cargo.log From d6f2098aa7bca038fc4fff3d8e13a9ed4028b196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Thu, 10 Apr 2025 10:25:36 +0200 Subject: [PATCH 005/579] Upgrading Wildfly --- pom.xml | 2 +- src/main/asciidoc/getting-started/systemRequirements.adoc | 2 +- .../asciidoc/reference-guide/configuration/deployment.adoc | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 784c93a73b5..7a6e66a738f 100644 --- a/pom.xml +++ b/pom.xml @@ -504,7 +504,7 @@ under the License. 60000 10.1.39 - 35.0.1.Final + 36.0.0.Final 6.2025.3 4.1.3 diff --git a/src/main/asciidoc/getting-started/systemRequirements.adoc b/src/main/asciidoc/getting-started/systemRequirements.adoc index bf69f76c911..9a34ccea9d3 100644 --- a/src/main/asciidoc/getting-started/systemRequirements.adoc +++ b/src/main/asciidoc/getting-started/systemRequirements.adoc @@ -38,7 +38,7 @@ Apache Syncope {docVersion} is verified with the following Jakarta EE containers . https://tomcat.apache.org/download-10.cgi[Apache Tomcat 10^] . https://www.payara.fish/[Payara Server 6^] - . https://www.wildfly.org/[Wildfly 35^] + . https://www.wildfly.org/[Wildfly 36^] === Internal Storage diff --git a/src/main/asciidoc/reference-guide/configuration/deployment.adoc b/src/main/asciidoc/reference-guide/configuration/deployment.adoc index 2d85e88497f..3711a02cddd 100644 --- a/src/main/asciidoc/reference-guide/configuration/deployment.adoc +++ b/src/main/asciidoc/reference-guide/configuration/deployment.adoc @@ -103,7 +103,7 @@ for the Master domain. Each JavaEE Container provides its own way to accomplish this task: * https://tomcat.apache.org/tomcat-10.0-doc/jdbc-pool.html[Apache Tomcat 10^] * https://docs.payara.fish/community/docs/Technical%20Documentation/Payara%20Server%20Documentation/Server%20Configuration%20And%20Management/JDBC%20Resource%20Management/JDBC.html[Payara Server 6^] - * https://docs.wildfly.org/35/Admin_Guide.html#DataSource[Wildfly 35^] + * https://docs.wildfly.org/36/Admin_Guide.html#DataSource[Wildfly 36^] **** ==== Apache Tomcat 10 @@ -200,7 +200,7 @@ For better performance under GNU / Linux, do not forget to include the system pr .... ==== -==== Wildfly 35 +==== Wildfly 36 Add @@ -280,7 +280,7 @@ javadocPaths=/WEB-INF/lib/syncope-common-idrepo-rest-api-${syncope.version}-java /WEB-INF/lib/syncope-common-am-rest-api-${syncope.version}-javadoc.jar .... -as `core/src/main/resources/core-wildfy.properties`. +as `core/src/main/resources/core-wildfly.properties`. Do not forget to include `widlfly` as https://docs.spring.io/spring-boot/3.4/reference/features/profiles.html[Spring Boot profile^] From 17c2644af38427409c355ec3810ce842e3cc5113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Thu, 10 Apr 2025 10:25:47 +0200 Subject: [PATCH 006/579] Upgrading Tomcat --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7a6e66a738f..c8b3605c22a 100644 --- a/pom.xml +++ b/pom.xml @@ -503,7 +503,7 @@ under the License. 9805 60000 - 10.1.39 + 10.1.40 36.0.0.Final 6.2025.3 4.1.3 From e548defda8bb68ed53958132f8a04261d65526bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Fri, 11 Apr 2025 11:24:09 +0200 Subject: [PATCH 007/579] Upgrading CAS --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c8b3605c22a..f12794a2233 100644 --- a/pom.xml +++ b/pom.xml @@ -443,7 +443,7 @@ under the License. 6.1.1 - 7.2.0 + 7.2.1 4.0.4 2.2.30 From 227ad47faf038f05e808f827ef64210a9a3b3002 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Apr 2025 08:13:26 +0200 Subject: [PATCH 008/579] Bump org.apache.commons:commons-text from 1.13.0 to 1.13.1 (#1054) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f12794a2233..461ee7ecd57 100644 --- a/pom.xml +++ b/pom.xml @@ -439,7 +439,7 @@ under the License. 3.17.0 3.4.0 - 1.13.0 + 1.13.1 6.1.1 From 3ab005a3d5a8d376b000fc28e463a0022e135a8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Tue, 15 Apr 2025 09:27:08 +0200 Subject: [PATCH 009/579] Upgrading ConnId LdUp connector --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 461ee7ecd57..8e3fc13519d 100644 --- a/pom.xml +++ b/pom.xml @@ -409,7 +409,7 @@ under the License. 3.0.7 0.5 1.0.0 - 0.1.0-SNAPSHOT + 0.1.0 4.1.1 1.80 From 5a297ff5aecc140f9ce018fbfd351fceaf3c5f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Tue, 15 Apr 2025 13:45:09 +0200 Subject: [PATCH 010/579] Upgrading ConnId --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8e3fc13519d..df12f1e90bf 100644 --- a/pom.xml +++ b/pom.xml @@ -395,7 +395,7 @@ under the License. 2025-03-07T13:42:57Z ${project.version} - 1.6.0.0 + 1.6.0.1 1.5.0 1.1.0 2.4.0 From 7f9d1aff58197a26e048e89ecb1a9c40fb717c94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Tue, 15 Apr 2025 13:51:24 +0200 Subject: [PATCH 011/579] Adding the new central-portal-snapshots repository --- pom.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pom.xml b/pom.xml index df12f1e90bf..aae0acedef2 100644 --- a/pom.xml +++ b/pom.xml @@ -1387,6 +1387,16 @@ under the License. + + central-portal-snapshots + https://central.sonatype.com/repository/maven-snapshots/ + + false + + + true + + sonatype-nexus-snapshots https://oss.sonatype.org/content/repositories/snapshots From 39de80838d7046e5d4264fa7bc56f35f0372e270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Wed, 16 Apr 2025 10:30:42 +0200 Subject: [PATCH 012/579] Upgrading Payara --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index aae0acedef2..6e778519d7e 100644 --- a/pom.xml +++ b/pom.xml @@ -505,7 +505,7 @@ under the License. 10.1.40 36.0.0.Final - 6.2025.3 + 6.2025.4 4.1.3 17-alpine From 92985bdb7bf764e16c9a800bc2afa6bf698c7ba3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Wed, 16 Apr 2025 17:41:01 +0200 Subject: [PATCH 013/579] Upgrading Commons JEXL --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6e778519d7e..8209f0a665b 100644 --- a/pom.xml +++ b/pom.xml @@ -438,7 +438,7 @@ under the License. 3.0 3.17.0 - 3.4.0 + 3.5.0 1.13.1 6.1.1 From f667a82f97cf34ac0ad4ce2c2053b9832991c124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Thu, 17 Apr 2025 07:50:18 +0200 Subject: [PATCH 014/579] Upgrading OpenSearch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8209f0a665b..a5ef740440e 100644 --- a/pom.xml +++ b/pom.xml @@ -431,7 +431,7 @@ under the License. 8.17.4 2.19.1 - 2.22.0 + 2.23.0 v1 From 5344634c36f9a966c6515eee756669810a6b6053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Thu, 17 Apr 2025 09:02:05 +0200 Subject: [PATCH 015/579] [SYNCOPE-1621] Allow to optionally select which element(s) to export --- .../console/panels/DashboardSystemPanel.java | 31 ++-- .../console/rest/SyncopeRestClient.java | 4 +- .../client/console/pages/BasePage.properties | 1 - .../console/pages/BasePage_it.properties | 1 - .../console/pages/BasePage_ja.properties | 1 - .../console/pages/BasePage_pt_BR.properties | 1 - .../console/pages/BasePage_ru.properties | 1 - .../console/panels/DashboardSystemPanel.html | 143 +++++++++--------- .../panels/DashboardSystemPanel.properties | 2 + .../DashboardSystemPanel_fr_CA.properties | 4 +- .../panels/DashboardSystemPanel_it.properties | 2 + .../panels/DashboardSystemPanel_ja.properties | 2 + .../DashboardSystemPanel_pt_BR.properties | 4 +- .../panels/DashboardSystemPanel_ru.properties | 2 + .../rest/api/service/SyncopeService.java | 18 ++- .../syncope/core/logic/SyncopeLogic.java | 11 +- .../rest/cxf/service/SyncopeServiceImpl.java | 4 +- .../api/content/ContentExporter.java | 3 +- .../jpa/content/XMLContentExporter.java | 45 +++--- .../jpa/outer/XMLContentExporterTest.java | 32 +++- .../neo4j/content/XMLContentExporter.java | 14 +- .../neo4j/outer/XMLContentExporterTest.java | 36 +++-- .../apache/syncope/fit/core/RESTITCase.java | 19 ++- .../reference-guide/howto/importexport.adoc | 13 +- 24 files changed, 235 insertions(+), 159 deletions(-) diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DashboardSystemPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DashboardSystemPanel.java index e7154909ae3..c3c6446f99a 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DashboardSystemPanel.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DashboardSystemPanel.java @@ -19,25 +19,26 @@ package org.apache.syncope.client.console.panels; import java.time.Duration; +import java.util.ArrayList; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.apache.syncope.client.console.SyncopeConsoleSession; import org.apache.syncope.client.console.rest.SyncopeRestClient; -import org.apache.syncope.client.ui.commons.Constants; +import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel; import org.apache.syncope.client.ui.commons.HttpResourceStream; -import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior; +import org.apache.syncope.client.ui.commons.markup.html.form.AjaxNumberFieldPanel; +import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel; import org.apache.syncope.client.ui.commons.rest.ResponseHolder; import org.apache.syncope.common.lib.info.SystemInfo; import org.apache.syncope.common.lib.types.IdRepoEntitlement; import org.apache.wicket.AttributeModifier; -import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.basic.Label; -import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.model.Model; +import org.apache.wicket.model.util.ListModel; import org.apache.wicket.request.handler.resource.ResourceStreamRequestHandler; import org.apache.wicket.request.resource.ContentDisposition; import org.apache.wicket.spring.injection.annot.SpringBean; @@ -67,17 +68,16 @@ public DashboardSystemPanel(final String id) { add(new Label("os", systemInfo.getOs())); add(new Label("jvm", systemInfo.getJvm())); - Model tableThresholdModel = Model.of(100); - add(new TextField<>("tableThreshold", tableThresholdModel).add(new IndicatorAjaxFormComponentUpdatingBehavior( - Constants.ON_CHANGE) { + AjaxNumberFieldPanel threshold = new AjaxNumberFieldPanel.Builder(). + min(0).step(10).enableOnChange(). + build("threshold", "threshold", Integer.class, Model.of(100)); + add(threshold.addRequiredLabel()); - private static final long serialVersionUID = -1107858522700306810L; - - @Override - protected void onUpdate(final AjaxRequestTarget target) { - // nothing to do - } - })); + ListModel elementsModel = new ListModel<>(new ArrayList<>()); + add(new MultiFieldPanel.Builder<>(elementsModel).build( + "elements", + "elements", + new AjaxTextFieldPanel("panel", "elements", Model.of()))); Link dbExportLink = new Link<>("dbExportLink") { @@ -87,7 +87,8 @@ protected void onUpdate(final AjaxRequestTarget target) { public void onClick() { try { HttpResourceStream stream = new HttpResourceStream(new ResponseHolder( - syncopeRestClient.exportInternalStorageContent(tableThresholdModel.getObject()))); + syncopeRestClient.exportInternalStorageContent( + threshold.getModelObject(), elementsModel.getObject()))); ResourceStreamRequestHandler rsrh = new ResourceStreamRequestHandler(stream); rsrh.setFileName( diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/SyncopeRestClient.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/SyncopeRestClient.java index e01b5e68228..c6db634c218 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/SyncopeRestClient.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/SyncopeRestClient.java @@ -27,8 +27,8 @@ public class SyncopeRestClient extends BaseRestClient { private static final long serialVersionUID = -9013241672773442286L; - public Response exportInternalStorageContent(final int tableThreshold) { - return getService(SyncopeService.class).exportInternalStorageContent(tableThreshold); + public Response exportInternalStorageContent(final int threshold, final List elements) { + return getService(SyncopeService.class).exportInternalStorageContent(threshold, elements); } public List searchAssignableGroups( diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.properties index 951c3c9b7f0..7b00c5e5386 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage.properties @@ -30,4 +30,3 @@ highContrast=Toggle high contrast mode fontSize=Change font size delegations=Delegations endDelegation=End Delegation -tableThreshold=Table Threshold diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage_it.properties index 42b21f5767f..024bd5cc0da 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage_it.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage_it.properties @@ -30,4 +30,3 @@ highContrast=(Dis)attiva alto contrasto fontSize=Dimensione carattere delegations=Deleghe endDelegation=Termina Delega -tableThreshold=Limite righe tabella diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage_ja.properties index 652f018a3a1..39d0b4cc005 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage_ja.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage_ja.properties @@ -30,4 +30,3 @@ highContrast=Toggle high contrast mode fontSize=Change font size delegations=Delegations endDelegation=End Delegation -tableThreshold=Table Threshold diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage_pt_BR.properties index 00d7c9f0a95..8d4868066f1 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage_pt_BR.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage_pt_BR.properties @@ -30,4 +30,3 @@ highContrast=Toggle high contrast mode fontSize=Change font size delegations=Delegations endDelegation=End Delegation -tableThreshold=Table Threshold diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage_ru.properties index b849e68598c..2e1944611b8 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage_ru.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/pages/BasePage_ru.properties @@ -30,4 +30,3 @@ highContrast=Toggle high contrast mode fontSize=Change font size delegations=Delegations endDelegation=End Delegation -tableThreshold=Table Threshold diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel.html index 4b8483a76ca..178981e6057 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel.html +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel.html @@ -17,90 +17,89 @@ under the License. --> - +

-
-

- -

-
-
-
-
-
-
- +
+

+ +

+
+
+
+
+
+
+ -
- - -
-
-
-
-
- +
+ + +
+
+
+
+
+ -
- - -
-
-
-
-
- +
+ + +
+
+
+
+
+ -
- - -
-
-
+
+ + +
+
+
+
+
+
+
+ + +
+ +
-
-
-
- +
+
+
+
+ -
- - -
-
-
-
-
- +
+ + +
+
+
+
+
+ -
- - -
-
+
+ + +
+
+
-
- -

- -
-
- - -
- - - - - -
-
-
+ +
+
+
+
- + diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel.properties index d6cdd4539be..95ed7a6f92d 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel.properties @@ -15,3 +15,5 @@ # specific language governing permissions and limitations # under the License. system.info=System Information +threshold=Threshold +elements=Elements diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_fr_CA.properties index 2e55cc89f4b..8158d718a3d 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_fr_CA.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_fr_CA.properties @@ -14,4 +14,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -system.info=Informations système +system.info=Informations syst\u00e8me +threshold=Threshold +elements=Elements diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_it.properties index c70d9e15a62..0142c20594b 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_it.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_it.properties @@ -15,3 +15,5 @@ # specific language governing permissions and limitations # under the License. system.info=Informazioni di sistema +threshold=Limite righe +elements=Elementi diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_ja.properties index c3a61e9d818..cc914ca96c1 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_ja.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_ja.properties @@ -15,3 +15,5 @@ # specific language governing permissions and limitations # under the License. system.info=\u30b7\u30b9\u30c6\u30e0\u30a4\u30f3\u30d5\u30a9\u30e1\u30fc\u30b7\u30e7\u30f3 +threshold=Threshold +elements=Elements diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_pt_BR.properties index 10216dc5167..0046d79a25b 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_pt_BR.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_pt_BR.properties @@ -14,4 +14,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -system.info=Informação do sistema +system.info=Informa\u00e7\u00e3o do sistema +threshold=Threshold +elements=Elements diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_ru.properties index 7517c166fe7..49e058f4508 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_ru.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardSystemPanel_ru.properties @@ -15,3 +15,5 @@ # specific language governing permissions and limitations # under the License. system.info=\u0421\u0438\u0441\u0442\u0435\u043c\u043d\u0430\u044f\u0020\u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f +threshold=Threshold +elements=Elements diff --git a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SyncopeService.java b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SyncopeService.java index c8fccf78b81..9cf16f03569 100644 --- a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SyncopeService.java +++ b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SyncopeService.java @@ -41,6 +41,7 @@ import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import java.io.InputStream; +import java.util.List; import org.apache.syncope.common.lib.to.GroupTO; import org.apache.syncope.common.lib.to.PagedResult; import org.apache.syncope.common.lib.to.TypeExtensionTO; @@ -81,7 +82,7 @@ public interface SyncopeService extends JAXRSService { description = "Allows the server to inform the " + "client about the fact that a specified preference was applied") }) }) @POST - @Path("/batch") + @Path("batch") @Consumes(RESTHeaders.MULTIPART_MIXED) @Produces(RESTHeaders.MULTIPART_MIXED) Response batch(InputStream input); @@ -104,7 +105,7 @@ public interface SyncopeService extends JAXRSService { @Schema(type = "integer"), description = "seconds after which attempt again to get batch results") }), @ApiResponse(responseCode = "404", description = "No batch process was found for the provided boundary") }) - @Path("/batch") + @Path("batch") @Produces(RESTHeaders.MULTIPART_MIXED) Response batch(); @@ -120,7 +121,7 @@ public interface SyncopeService extends JAXRSService { * the provided Realm */ @POST - @Path("/assignableGroups/{realm:.*}") + @Path("assignableGroups/{realm:.*}") @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) PagedResult searchAssignableGroups( @NotNull @PathParam("realm") String realm, @@ -135,17 +136,20 @@ PagedResult searchAssignableGroups( * @return User type extension information, for the provided group */ @GET - @Path("/userTypeExtension/{groupName}") + @Path("userTypeExtension/{groupName}") @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) TypeExtensionTO readUserTypeExtension(@NotNull @PathParam("groupName") String groupName); /** - * Exports internal storage content as downloadable XML file. + * Exports the internal storage content as downloadable XML file. * - * @param tableThreshold the maximum number of rows to take for each table of internal storage + * @param threshold the maximum number of rows to take for each element of internal storage + * @param elements if provided, the list of elements to export; otherwise all elements will be included * @return internal storage content as downloadable XML file */ @GET @Path("internalStorage/stream") - Response exportInternalStorageContent(@QueryParam("tableThreshold") @DefaultValue("100") int tableThreshold); + Response exportInternalStorageContent( + @QueryParam("threshold") @DefaultValue("100") int threshold, + @QueryParam("elements") List elements); } diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java index 645ed3a794a..bc3896c56ba 100644 --- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java +++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java @@ -144,12 +144,17 @@ public TypeExtensionTO readTypeExtension(final String groupName) { @PreAuthorize("hasRole('" + IdRepoEntitlement.KEYMASTER + "')") @Transactional(readOnly = true) - public void exportInternalStorageContent(final int tableThreshold, final OutputStream os) { + public void exportInternalStorageContent( + final int threshold, + final OutputStream os, + final List elements) { + try { exporter.export( AuthContextUtils.getDomain(), - tableThreshold, - os); + threshold, + os, + elements.toArray(String[]::new)); LOG.debug("Internal storage content successfully exported"); } catch (Exception e) { LOG.error("While exporting internal storage content", e); diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SyncopeServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SyncopeServiceImpl.java index 4265d36c9c9..1a3d7ff5518 100644 --- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SyncopeServiceImpl.java +++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SyncopeServiceImpl.java @@ -197,8 +197,8 @@ public Response batch() { } @Override - public Response exportInternalStorageContent(final int tableThreshold) { - StreamingOutput sout = os -> logic.exportInternalStorageContent(tableThreshold, os); + public Response exportInternalStorageContent(final int threshold, final List elements) { + StreamingOutput sout = os -> logic.exportInternalStorageContent(threshold, os, elements); return Response.ok(sout). type(MediaType.TEXT_XML). diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentExporter.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentExporter.java index 0568d8840d9..106bde63f91 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentExporter.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/content/ContentExporter.java @@ -28,6 +28,7 @@ public interface ContentExporter extends ContentDealer { void export( String domain, int threshold, - OutputStream output) + OutputStream output, + String... elements) throws SAXException, TransformerConfigurationException; } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java index 37b64d35312..f5303bfb0d8 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java @@ -59,6 +59,7 @@ import javax.sql.DataSource; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.sax.TransformerHandler; +import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.apache.cxf.helpers.IOUtils; @@ -92,7 +93,7 @@ public class XMLContentExporter extends AbstractXMLContentExporter { protected static boolean isTableAllowed(final String tableName) { return TABLE_PREFIXES_TO_BE_EXCLUDED.stream(). - noneMatch(prefix -> tableName.toUpperCase().startsWith(prefix.toUpperCase())); + noneMatch(prefix -> tableName.toUpperCase().startsWith(prefix.toUpperCase())); } protected static String getValues(final ResultSet rs, final String columnName, final Integer columnType) @@ -178,7 +179,7 @@ protected static Map> relationTables(final BidiMap< String attrName = Optional.ofNullable(field.getAnnotation(Column.class)). map(Column::name). - orElseGet(a::getName); + orElseGet(a::getName); Optional.ofNullable(field.getAnnotation(CollectionTable.class)). ifPresent(collectionTable -> relationTables.put( @@ -375,8 +376,13 @@ protected void exportTable( public void export( final String domain, final int threshold, - final OutputStream os) - throws SAXException, TransformerConfigurationException { + final OutputStream os, + final String... elements) throws SAXException, TransformerConfigurationException { + + BidiMap> entities = new DualHashBidiMap<>(); + entityManagerFactory.getMetamodel().getEntities().forEach(entity -> Optional.ofNullable( + entity.getBindableJavaType().getAnnotation(Table.class)). + ifPresent(table -> entities.put(table.name(), entity))); TransformerHandler handler = start(os); @@ -392,27 +398,26 @@ public void export( } Connection conn = DataSourceUtils.getConnection(dataSource); - try (ResultSet rs = conn.getMetaData(). - getTables(null, StringUtils.isBlank(schema) ? null : schema, null, new String[] { "TABLE" })) { - + try { Set tableNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); - - while (rs.next()) { - String tableName = rs.getString("TABLE_NAME"); - LOG.debug("Found table {}", tableName); - if (isTableAllowed(tableName)) { - tableNames.add(tableName); + if (ArrayUtils.isEmpty(elements)) { + try (ResultSet rs = conn.getMetaData().getTables(null, schema, null, new String[] { "TABLE" })) { + while (rs.next()) { + String tableName = rs.getString("TABLE_NAME"); + LOG.debug("Found table {}", tableName); + if (isTableAllowed(tableName)) { + tableNames.add(tableName); + } + } + } catch (SQLException e) { + LOG.error("While getting the list of tables", e); } + } else { + tableNames.addAll(Stream.of(elements).toList()); } - LOG.debug("Tables to be exported {}", tableNames); - BidiMap> entities = new DualHashBidiMap<>(); - entityManagerFactory.getMetamodel().getEntities().forEach(entity -> Optional.ofNullable( - entity.getBindableJavaType().getAnnotation(Table.class)). - ifPresent(table -> entities.put(table.name(), entity))); - - // then sort tables based on foreign keys and dump + // then sort tables based on foreign keys and export for (String tableName : sortByForeignKeys(conn, schema, tableNames)) { try { exportTable(dataSource, tableName, threshold, entities, relationTables(entities), handler); diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/XMLContentExporterTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/XMLContentExporterTest.java index 460415affc7..0c2711140d9 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/XMLContentExporterTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/XMLContentExporterTest.java @@ -38,6 +38,15 @@ public class XMLContentExporterTest extends AbstractTest { @Autowired private ContentExporter exporter; + private static void checkRealms(final String exported) { + List realms = exported.lines().filter(row -> row.trim().startsWith(" realms = exported.lines().filter(row -> row.trim().startsWith(" accountPolicies = exported.lines(). + filter(row -> row.trim().startsWith("> persistentEntities() { + protected List> persistentEntities(final String[] elements) { Map> entities = mappingContext.getPersistentEntities().stream(). filter(e -> !LABELS_TO_BE_EXCLUDED.contains(e.getPrimaryLabel()) && !e.getPrimaryLabel().startsWith("Abstract") @@ -88,6 +89,10 @@ protected List> persistentEntities() { collect(Collectors.toMap( Neo4jPersistentEntity::getPrimaryLabel, Function.identity(), (first, second) -> first)); + if (ArrayUtils.isNotEmpty(elements)) { + entities.entrySet().removeIf(e -> !ArrayUtils.contains(elements, e.getKey())); + } + Set roots = new HashSet<>(); Map exploited = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); @@ -191,11 +196,12 @@ protected void exportNode( public void export( final String domain, final int threshold, - final OutputStream os) throws SAXException, TransformerConfigurationException { + final OutputStream os, + final String... elements) throws SAXException, TransformerConfigurationException { TransformerHandler handler = start(os); - for (Neo4jPersistentEntity entity : persistentEntities()) { + for (Neo4jPersistentEntity entity : persistentEntities(elements)) { try (Session session = domainHolder.getDomains().get(domain).session()) { StringBuilder query = new StringBuilder("MATCH (n:" + entity.getPrimaryLabel() + ")-[r]-() "); if (Neo4jSchedTask.NODE.equals(entity.getPrimaryLabel())) { @@ -205,7 +211,7 @@ public void export( } query.append("RETURN n, collect(r) AS rels ORDER BY n.id"); - Stream records = session.run(query.toString()).stream(); + Stream records = session.run(query.toString()).stream().limit(threshold); if (Neo4jRealm.NODE.equals(entity.getPrimaryLabel())) { records = records.sorted(REALM_COMPARATOR); } diff --git a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/outer/XMLContentExporterTest.java b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/outer/XMLContentExporterTest.java index ed6c542fd75..74f84642b48 100644 --- a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/outer/XMLContentExporterTest.java +++ b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/outer/XMLContentExporterTest.java @@ -23,9 +23,6 @@ import java.io.ByteArrayOutputStream; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardOpenOption; import java.util.List; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.common.lib.SyncopeConstants; @@ -41,6 +38,15 @@ public class XMLContentExporterTest extends AbstractTest { @Autowired private ContentExporter exporter; + private static void checkRealms(final String exported) { + List realms = exported.lines().filter(row -> row.trim().startsWith(" realms = exported.lines().filter(row -> row.trim().startsWith(" accountPolicies = exported.lines(). + filter(row -> row.trim().startsWith(" 1000); - String configExport = response.readEntity(String.class); - assertFalse(configExport.isEmpty()); - assertTrue(configExport.length() > 1000); + response = SYNCOPE_SERVICE.exportInternalStorageContent(100, List.of("AccountPolicy", "Realm")); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatusInfo().getStatusCode()); + assertTrue(response.getMediaType().toString().startsWith(MediaType.TEXT_XML)); + assertNotNull(response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION)); + + String export = response.readEntity(String.class); + assertTrue(export.contains(" Date: Thu, 17 Apr 2025 12:12:06 +0200 Subject: [PATCH 016/579] [SYNCOPE-1872] Allow to control force mfa execution configuration on authentication policy (#1057) --- .../client/console/policies/AuthPolicyModalPanel.java | 6 ++++++ .../client/console/policies/AuthPolicyModalPanel.html | 3 +++ .../console/policies/PolicyDirectoryPanel.properties | 1 + .../policies/PolicyDirectoryPanel_fr_CA.properties | 1 + .../policies/PolicyDirectoryPanel_it.properties | 1 + .../policies/PolicyDirectoryPanel_ja.properties | 1 + .../policies/PolicyDirectoryPanel_pt_BR.properties | 1 + .../policies/PolicyDirectoryPanel_ru.properties | 1 + .../common/lib/policy/DefaultAuthPolicyConf.java | 10 ++++++++++ .../syncope/wa/starter/mapping/DefaultAuthMapper.java | 2 +- 10 files changed, 26 insertions(+), 1 deletion(-) diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/policies/AuthPolicyModalPanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/policies/AuthPolicyModalPanel.java index 76833d35742..d1bc313fd08 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/policies/AuthPolicyModalPanel.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/policies/AuthPolicyModalPanel.java @@ -87,6 +87,12 @@ public AuthPolicyModalPanel( new PropertyModel<>(model.getObject().getConf(), "bypassEnabled"), false)); + add(new AjaxCheckBoxPanel( + "forceMfaExecution", + "forceMfaExecution", + new PropertyModel<>(model.getObject().getConf(), "forceMfaExecution"), + false)); + add(new AjaxTextFieldPanel( "bypassPrincipalAttributeName", "bypassPrincipalAttributeName", diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/policies/AuthPolicyModalPanel.html b/client/am/console/src/main/resources/org/apache/syncope/client/console/policies/AuthPolicyModalPanel.html index e66a972c85e..b5923fc5df6 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/policies/AuthPolicyModalPanel.html +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/policies/AuthPolicyModalPanel.html @@ -27,6 +27,9 @@
+
+ +
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel.properties index d5451c65bd5..bf294793403 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel.properties @@ -56,5 +56,6 @@ enable.proxyTgtConf=Enable Proxy TGT enable.proxyStConf=Enable Proxy ST auditHistory.title=Configuration history bypassEnabled=Enable Bypass +forceMfaExecution=Force multifactor authentication bypassPrincipalAttributeName=Bypass Principal Attribute Name bypassPrincipalAttributeValue=Bypass Principal Attribute Value diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_fr_CA.properties index a951aa05624..96c63e1e034 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_fr_CA.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_fr_CA.properties @@ -56,5 +56,6 @@ enable.proxyTgtConf=Enable Proxy TGT enable.proxyStConf=Enable Proxy ST auditHistory.title=Historique de configuration bypassEnabled=Enable Bypass +forceMfaExecution=Forcer l'authentification multifacteur bypassPrincipalAttributeName=Bypass Principal Attribute Name bypassPrincipalAttributeValue=Bypass Principal Attribute Value diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_it.properties index a55a004688b..de8714010b6 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_it.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_it.properties @@ -56,5 +56,6 @@ enable.proxyTgtConf=Abilita Proxy TGT enable.proxyStConf=Abilita Proxy ST auditHistory.title=Storico delle configurazioni bypassEnabled=Abilita Bypass +forceMfaExecution=Forza l'autenticazione multifattore bypassPrincipalAttributeName=Bypass Nome Attributo bypassPrincipalAttributeValue=Bypass Valore Attributo diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_ja.properties index bd417f8aad7..622c6c13d78 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_ja.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_ja.properties @@ -56,6 +56,7 @@ enable.proxyTgtConf=Enable Proxy TGT enable.proxyStConf=Enable Proxy ST auditHistory.title=\u8a2d\u5b9a\u5c65\u6b74 bypassEnabled=Enable Bypass +forceMfaExecution=\u591a\u8981\u7d20\u8a8d\u8a3c\u3092\u5f37\u5236\u3059\u308b bypassPrincipalAttributeName=Bypass Principal Attribute Name bypassPrincipalAttributeValue=Bypass Principal Attribute Value diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_pt_BR.properties index f189b1abdd8..5342aecfa60 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_pt_BR.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_pt_BR.properties @@ -56,5 +56,6 @@ enable.proxyTgtConf=Enable Proxy TGT enable.proxyStConf=Enable Proxy ST auditHistory.title=Hist\u00f3rico de configura\u00e7\u00e3o bypassEnabled=Enable Bypass +forceMfaExecution=For\u00e7ar autentica\u00e7\u00e3o multifator bypassPrincipalAttributeName=Bypass Principal Attribute Name bypassPrincipalAttributeValue=Bypass Principal Attribute Value diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_ru.properties index e767cb8b714..26b25636da2 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_ru.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/policies/PolicyDirectoryPanel_ru.properties @@ -57,5 +57,6 @@ enable.proxyTgtConf=Enable Proxy TGT enable.proxyStConf=Enable Proxy ST auditHistory.title=\u0418\u0441\u0442\u043e\u0440\u0438\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 bypassEnabled=Enable Bypass +forceMfaExecution=\u041f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043c\u043d\u043e\u0433\u043e\u0444\u0430\u043a\u0442\u043e\u0440\u043d\u0430\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f bypassPrincipalAttributeName=Bypass Principal Attribute Name bypassPrincipalAttributeValue=Bypass Principal Attribute Value diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultAuthPolicyConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultAuthPolicyConf.java index b0a4b4f789a..0d0584f7488 100644 --- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultAuthPolicyConf.java +++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultAuthPolicyConf.java @@ -31,6 +31,8 @@ public class DefaultAuthPolicyConf implements AuthPolicyConf { private boolean bypassEnabled; + private boolean forceMfaExecution = true; + private String bypassPrincipalAttributeName; private String bypassPrincipalAttributeValue; @@ -53,6 +55,14 @@ public void setBypassEnabled(final boolean bypassEnabled) { this.bypassEnabled = bypassEnabled; } + public boolean isForceMfaExecution() { + return forceMfaExecution; + } + + public void setForceMfaExecution(final boolean forceMfaExecution) { + this.forceMfaExecution = forceMfaExecution; + } + public String getBypassPrincipalAttributeName() { return bypassPrincipalAttributeName; } diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/DefaultAuthMapper.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/DefaultAuthMapper.java index 859b983ae48..60adf1ecaaa 100644 --- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/DefaultAuthMapper.java +++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/DefaultAuthMapper.java @@ -124,7 +124,7 @@ public AuthMapperResult build( mfaPolicy.setBypassEnabled(policyConf.isBypassEnabled()); } - mfaPolicy.setForceExecution(true); + mfaPolicy.setForceExecution(policyConf.isForceMfaExecution()); mfaPolicy.setMultifactorAuthenticationProviders(mfaProviders); } From 32a8271a2c850230ce28862005acd317ddf288f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Thu, 17 Apr 2025 14:11:32 +0200 Subject: [PATCH 017/579] [SYNCOPE-1841] Hiding buttons when panel is readonly --- .../markup/html/form/AbstractMultiPanel.java | 88 +++++++++++-------- .../markup/html/form/MultiFieldPanel.html | 10 ++- .../markup/html/form/MultiFieldPanel.html | 10 ++- 3 files changed, 64 insertions(+), 44 deletions(-) diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AbstractMultiPanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AbstractMultiPanel.java index 1e317eeea4d..e403729c262 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AbstractMultiPanel.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AbstractMultiPanel.java @@ -66,32 +66,65 @@ public AbstractMultiPanel( view = new InnerView("view", name, model); if (CollectionUtils.isEmpty(model.getObject())) { - form.addOrReplace(getNoDataFragment(model, name)); + form.addOrReplace(getNoDataFragment(name)); } else { form.addOrReplace(getDataFragment()); } } - // SYNCOPE-1476 public AbstractMultiPanel setFormAsMultipart(final boolean multipart) { form.setMultiPart(multipart); return this; } - private Fragment getNoDataFragment(final IModel> model, final String label) { + private Fragment getNoDataFragment(final String label) { Fragment fragment = new Fragment("content", "noDataFragment", AbstractMultiPanel.this); fragment.add(new Label("field-label", new ResourceModel(label, label))); - fragment.add(getPlusFragment(model)); + fragment.add(getFragmentPlus()); return fragment; } private Fragment getDataFragment() { - Fragment contentFragment = new Fragment("content", "dataFragment", AbstractMultiPanel.this); - contentFragment.add(view.setOutputMarkupId(true)); - return contentFragment; + Fragment fragment = new Fragment("content", "dataFragment", AbstractMultiPanel.this); + fragment.add(view.setOutputMarkupId(true)); + return fragment; } - private Fragment getPlusFragment(final IModel> model) { + private Fragment getFragmentMinus(final ListItem item, final Panel panel, final String label) { + IndicatorAjaxSubmitLink minus = new IndicatorAjaxSubmitLink("drop") { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + protected void onSubmit(final AjaxRequestTarget target) { + // drop the current component + view.getModel().getObject().remove(item.getModelObject()); + clearInput(panel); + + if (view.getModel().getObject().isEmpty()) { + form.addOrReplace(getNoDataFragment(label)); + } + + target.add(container); + } + + @Override + protected void onError(final AjaxRequestTarget target) { + onSubmit(target); + } + }; + + Fragment fragment = new Fragment("panelMinus", "fragmentMinus", AbstractMultiPanel.this); + fragment.addOrReplace(minus); + fragment.setRenderBodyOnly(true); + + fragment.setOutputMarkupPlaceholderTag(true); + fragment.setVisible(container.isEnabled() && form.isEnabled()); + + return fragment; + } + + private Fragment getFragmentPlus() { IndicatorAjaxSubmitLink plus = new IndicatorAjaxSubmitLink("add") { private static final long serialVersionUID = -7978723352517770644L; @@ -99,9 +132,9 @@ private Fragment getPlusFragment(final IModel> model) { @Override protected void onSubmit(final AjaxRequestTarget target) { //Add current component - model.getObject().add(newModelObject()); + view.getModel().getObject().add(newModelObject()); - if (model.getObject().size() == 1) { + if (view.getModel().getObject().size() == 1) { form.addOrReplace(getDataFragment()); } @@ -121,6 +154,9 @@ protected void onError(final AjaxRequestTarget target) { fragment.addOrReplace(plus); fragment.setRenderBodyOnly(true); + fragment.setOutputMarkupPlaceholderTag(true); + fragment.setVisible(container.isEnabled() && form.isEnabled()); + return fragment; } @@ -158,36 +194,12 @@ protected void populateItem(final ListItem item) { item.add(panel.setRenderBodyOnly(true)); - IndicatorAjaxSubmitLink minus = new IndicatorAjaxSubmitLink("drop") { - - private static final long serialVersionUID = -7978723352517770644L; + item.add(getFragmentMinus(item, panel, label)); - @Override - protected void onSubmit(final AjaxRequestTarget target) { - //Drop current component - model.getObject().remove(item.getModelObject()); - clearInput(panel); - - if (model.getObject().isEmpty()) { - form.addOrReplace(getNoDataFragment(model, label)); - } - - target.add(container); - } - - @Override - protected void onError(final AjaxRequestTarget target) { - onSubmit(target); - } - }; - - item.add(minus); - - Fragment fragment = item.getIndex() == model.getObject().size() - 1 - ? getPlusFragment(model) + Fragment plus = item.getIndex() == model.getObject().size() - 1 + ? getFragmentPlus() : new Fragment("panelPlus", "emptyFragment", AbstractMultiPanel.this); - - item.add(fragment.setRenderBodyOnly(true)); + item.add(plus.setRenderBodyOnly(true)); } } diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel.html index 8dd0032b7ce..c6644e5d359 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel.html +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel.html @@ -42,14 +42,18 @@
[form field] -
- -
+ [minus] [plus]
+ +
+ +
+
+
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/markup/html/form/MultiFieldPanel.html b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/markup/html/form/MultiFieldPanel.html index 62d0c618deb..1274ee7f613 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/markup/html/form/MultiFieldPanel.html +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/markup/html/form/MultiFieldPanel.html @@ -47,14 +47,18 @@
[form field] -
- -
+ [minus] [plus]
+ +
+ +
+
+
From ed572dba50074e974d5b756e88072833fba89a34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Thu, 17 Apr 2025 14:12:35 +0200 Subject: [PATCH 018/579] [SYNCOPE-1870] Do not log stacktrace by default for NotFoundException --- .../client/console/rest/RoleRestClient.java | 16 ++++++--- .../client/lib/RestClientExceptionMapper.java | 15 +++++++- .../apache/syncope/core/logic/RoleLogic.java | 2 -- .../rest/cxf/RestServiceExceptionMapper.java | 35 +++++++++++++------ .../java/data/UserDataBinderImpl.java | 15 ++------ 5 files changed, 52 insertions(+), 31 deletions(-) diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/RoleRestClient.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/RoleRestClient.java index db47ae4f41d..8136bb15d1e 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/RoleRestClient.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/RoleRestClient.java @@ -25,7 +25,9 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.client.console.SyncopeConsoleSession; +import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.to.RoleTO; +import org.apache.syncope.common.lib.types.ClientExceptionType; import org.apache.syncope.common.rest.api.service.RoleService; /** @@ -55,15 +57,21 @@ public List list() { return getService(RoleService.class).list(); } - public String readAnyLayout(final String roleKey) { + public String readAnyLayout(final String role) { try { return IOUtils.toString(InputStream.class.cast( - getService(RoleService.class).getAnyLayout(roleKey).getEntity()), + getService(RoleService.class).getAnyLayout(role).getEntity()), StandardCharsets.UTF_8); + } catch (SyncopeClientException e) { + if (e.getType() == ClientExceptionType.NotFound) { + LOG.warn("Could not locate console layout info for role {}", role); + } else { + LOG.error("While retrieving console layout info for role {}", role, e); + } } catch (Exception e) { - LOG.error("Error retrieving console layout info for role {}", roleKey, e); - return StringUtils.EMPTY; + LOG.error(e.getMessage(), e); } + return StringUtils.EMPTY; } public void setAnyLayout(final String roleKey, final String content) { diff --git a/client/idrepo/lib/src/main/java/org/apache/syncope/client/lib/RestClientExceptionMapper.java b/client/idrepo/lib/src/main/java/org/apache/syncope/client/lib/RestClientExceptionMapper.java index 9e2bb3b5221..8eb11728ad7 100644 --- a/client/idrepo/lib/src/main/java/org/apache/syncope/client/lib/RestClientExceptionMapper.java +++ b/client/idrepo/lib/src/main/java/org/apache/syncope/client/lib/RestClientExceptionMapper.java @@ -21,6 +21,7 @@ import jakarta.ws.rs.BadRequestException; import jakarta.ws.rs.ForbiddenException; import jakarta.ws.rs.NotAuthorizedException; +import jakarta.ws.rs.NotFoundException; import jakarta.ws.rs.core.GenericType; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.ext.Provider; @@ -76,7 +77,19 @@ public Exception fromResponse(final Response response) { ex = new WebServiceException(String.format("Remote exception with status code: %s", Response.Status.fromStatusCode(statusCode).name())); } - LOG.error("Exception thrown", ex); + + if (ex instanceof NotFoundException + || (ex instanceof SyncopeClientException sce && sce.getType() == ClientExceptionType.NotFound)) { + + if (LOG.isDebugEnabled()) { + LOG.debug("Exception thrown", ex); + } else { + LOG.warn("{} thrown: {}", NotFoundException.class.getSimpleName(), ex.getMessage()); + } + } else { + LOG.error("Exception thrown", ex); + } + return ex; } diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java index 1e948fe5daf..1bc33324425 100644 --- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java +++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RoleLogic.java @@ -92,8 +92,6 @@ public String getAnyLayout(final String key) { String consoleLayout = role.getAnyLayout(); if (StringUtils.isBlank(consoleLayout)) { - LOG.error("Could not find console layout for Role '{}'", key); - throw new NotFoundException("Console layout for role " + key); } diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java index 4c680a322df..6eb45bc7bad 100644 --- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java +++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java @@ -88,7 +88,15 @@ public RestServiceExceptionMapper(final Environment env) { @Override public Response toResponse(final Exception ex) { - LOG.error("Exception thrown", ex); + if (ex instanceof NotFoundException) { + if (LOG.isDebugEnabled()) { + LOG.debug("Exception thrown", ex); + } else { + LOG.warn("{} thrown: {}", NotFoundException.class.getSimpleName(), ex.getMessage()); + } + } else { + LOG.error("Exception thrown", ex); + } ResponseBuilder builder; @@ -107,10 +115,9 @@ public Response toResponse(final Exception ex) { || ((ex instanceof PersistenceException || ex instanceof DataIntegrityViolationException) && (ex.getCause() instanceof EntityExistsException || ex.getMessage().contains("already exists")))) { - builder = builder(ClientExceptionType.EntityExists, - getPersistenceErrorMessage( - ex instanceof PersistenceException || ex instanceof DataIntegrityViolationException - ? ex.getCause() : ex)); + builder = builder(ClientExceptionType.EntityExists, getPersistenceErrorMessage( + ex instanceof PersistenceException || ex instanceof DataIntegrityViolationException + ? ex.getCause() : ex)); } else if (ex instanceof DataIntegrityViolationException || ex instanceof UncategorizedDataAccessException) { builder = builder(ClientExceptionType.DataIntegrityViolation, getPersistenceErrorMessage(ex)); } else if (ex instanceof ConnectorException) { @@ -256,17 +263,23 @@ private static ResponseBuilder processBadRequestExceptions(final Exception ex) { if (ex instanceof WorkflowException) { return builder(ClientExceptionType.Workflow, ExceptionUtils.getRootCauseMessage(ex)); - } else if (ex instanceof PersistenceException) { + } + if (ex instanceof PersistenceException) { return builder(ClientExceptionType.GenericPersistence, ExceptionUtils.getRootCauseMessage(ex)); - } else if (ibatisPersistenceException != null && ibatisPersistenceException.isAssignableFrom(ex.getClass())) { + } + if (ibatisPersistenceException != null && ibatisPersistenceException.isAssignableFrom(ex.getClass())) { return builder(ClientExceptionType.Workflow, "Currently unavailable. Please try later."); - } else if (ex instanceof UncategorizedDataAccessException) { + } + if (ex instanceof UncategorizedDataAccessException) { return builder(ClientExceptionType.DataIntegrityViolation, ExceptionUtils.getRootCauseMessage(ex)); - } else if (ex instanceof ConfigurationException) { + } + if (ex instanceof ConfigurationException) { return builder(ClientExceptionType.InvalidConnIdConf, ExceptionUtils.getRootCauseMessage(ex)); - } else if (ex instanceof ParsingValidationException) { + } + if (ex instanceof ParsingValidationException) { return builder(ClientExceptionType.InvalidValues, ExceptionUtils.getRootCauseMessage(ex)); - } else if (ex instanceof MalformedPathException) { + } + if (ex instanceof MalformedPathException) { return builder(ClientExceptionType.InvalidPath, ExceptionUtils.getRootCauseMessage(ex)); } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java index 9ef36df0091..9d3ca8a22dc 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java @@ -181,23 +181,12 @@ public UserTO getAuthenticatedUserTO() { return authUserTO; } - protected RuntimeException aggregateException( - final SyncopeClientCompositeException scce, - final RuntimeException e, - final ClientExceptionType clientExceptionType) { - - SyncopeClientException sce = SyncopeClientException.build(clientExceptionType); - sce.getElements().add(e.getMessage()); - scce.addException(sce); - return scce; - } - protected void setPassword(final User user, final String password, final SyncopeClientCompositeException scce) { try { setCipherAlgorithm(user); user.setPassword(password); } catch (IllegalArgumentException e) { - throw aggregateException(scce, e, ClientExceptionType.NotFound); + throw new NotFoundException(e.getMessage()); } } @@ -209,7 +198,7 @@ protected void setSecurityAnswer( setCipherAlgorithm(user); user.setSecurityAnswer(securityAnswer); } catch (IllegalArgumentException e) { - throw aggregateException(scce, e, ClientExceptionType.NotFound); + throw new NotFoundException(e.getMessage()); } } From bd0df1b7591f5257953df8a195da55729e0814c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Thu, 17 Apr 2025 15:08:23 +0200 Subject: [PATCH 019/579] [SYNCOPE-1841] Fix tests --- .../wicket/markup/html/form/MultiPanel.html | 10 ++++++--- .../java/data/UserDataBinderImpl.java | 21 ++++++++++++++++--- .../syncope/fit/console/PoliciesITCase.java | 3 +-- .../syncope/fit/console/UsersITCase.java | 4 ++-- 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiPanel.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiPanel.html index d604c609583..2604c8c9f10 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiPanel.html +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/MultiPanel.html @@ -49,15 +49,19 @@
[form field]
-
- -
+ [plus]
[plus]
+ +
+ +
+
+
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java index 9d3ca8a22dc..578b6094dab 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java @@ -181,12 +181,26 @@ public UserTO getAuthenticatedUserTO() { return authUserTO; } - protected void setPassword(final User user, final String password, final SyncopeClientCompositeException scce) { + protected SyncopeClientException addToSyncopeClientException( + final SyncopeClientCompositeException scce, + final RuntimeException e) { + + SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.NotFound); + sce.getElements().add(e.getMessage()); + scce.addException(sce); + return scce; + } + + protected void setPassword( + final User user, + final String password, + final SyncopeClientCompositeException scce) { + try { setCipherAlgorithm(user); user.setPassword(password); } catch (IllegalArgumentException e) { - throw new NotFoundException(e.getMessage()); + throw addToSyncopeClientException(scce, e); } } @@ -194,11 +208,12 @@ protected void setSecurityAnswer( final User user, final String securityAnswer, final SyncopeClientCompositeException scce) { + try { setCipherAlgorithm(user); user.setSecurityAnswer(securityAnswer); } catch (IllegalArgumentException e) { - throw new NotFoundException(e.getMessage()); + throw addToSyncopeClientException(scce, e); } } diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java index f13de47669e..9b03cc1def7 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java @@ -697,8 +697,7 @@ public void createComposeDeleteInboundPolicy() { "body:content:tabbedPanel:panel:outerObjectsRepeater:1:outer:container:content:" + "togglePanelContainer:container:actions:actions:actionRepeater:2:action:action"); - TESTER.assertComponent("body:content:tabbedPanel:panel:outerObjectsRepeater:5:outer", - Modal.class); + TESTER.assertComponent("body:content:tabbedPanel:panel:outerObjectsRepeater:5:outer", Modal.class); Component modal = TESTER.getComponentFromLastRenderedPage( "body:content:tabbedPanel:panel:outerObjectsRepeater:5:outer"); diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java index 80857705d9d..17e5ee32112 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java @@ -518,11 +518,11 @@ public void editUserMemberships() { // ... remove all values from multivalue field TESTER.executeAjaxEvent(TAB_PANEL + "outerObjectsRepeater:0:" + "outer:form:content:form:view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:body:" - + "content:schemas:6:panel:multiValueContainer:innerForm:content:view:1:drop", + + "content:schemas:6:panel:multiValueContainer:innerForm:content:view:1:panelMinus:drop", Constants.ON_CLICK); TESTER.executeAjaxEvent(TAB_PANEL + "outerObjectsRepeater:0:" + "outer:form:content:form:view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:body:" - + "content:schemas:6:panel:multiValueContainer:innerForm:content:view:0:drop", + + "content:schemas:6:panel:multiValueContainer:innerForm:content:view:0:panelMinus:drop", Constants.ON_CLICK); formTester = TESTER.newFormTester(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form"); From d3d7d5c9053fd5b279375c6fdfd1633c6a8aeb97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Tue, 22 Apr 2025 08:31:44 +0200 Subject: [PATCH 020/579] Upgrading Swagger UI --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a5ef740440e..e5d0fad6a43 100644 --- a/pom.xml +++ b/pom.xml @@ -447,7 +447,7 @@ under the License. 4.0.4 2.2.30 - 5.20.7 + 5.21.0 1.3.8 1.4.1-1 From 9faa2cd35c597d74d0539fdea35ae6e33516b791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Wed, 23 Apr 2025 09:42:30 +0200 Subject: [PATCH 021/579] Prefer Mutable/MutableObject over AtomicReference for utility --- .../ClientAppModalPanelBuilder.java | 2 +- .../syncope/client/console/panels/OIDC.java | 25 +++++++------- .../console/rest/OIDCJWKSRestClient.java | 9 ++--- .../any/LinkedAccountDetailsPanel.java | 15 +++++---- .../zookeeper/ZookeeperTestingServer.java | 13 ++++---- .../apache/syncope/core/logic/GroupLogic.java | 14 +++++--- .../persistence/api/utils/URIUtilsTest.java | 15 +++++---- .../validation/AttributableValidator.java | 31 +++++++++-------- .../dao/repo/ExternalResourceRepoExtImpl.java | 11 ++++--- .../dao/repo/ExternalResourceRepoExtImpl.java | 11 ++++--- .../core/provisioning/api/Connector.java | 10 +++--- .../java/ConnectorFacadeProxy.java | 18 +++++----- .../java/DefaultMappingManager.java | 33 ++++++++++--------- .../java/data/JEXLItemTransformerImpl.java | 11 ++++--- .../java/data/SchemaDataBinderImpl.java | 27 +++++++-------- .../java/job/MacroJobDelegate.java | 20 ++++++----- .../AbstractPropagationTaskExecutor.java | 19 ++++++----- .../pushpull/stream/CSVStreamConnector.java | 12 +++---- .../java/job/SyncopeTaskSchedulerTest.java | 9 ++--- ...sernamePasswordAuthenticationProvider.java | 22 +++++++------ .../actuate/DomainsHealthIndicator.java | 9 ++--- .../ExternalResourcesHealthIndicator.java | 9 ++--- .../client/OpenFGAHealthIndicator.java | 11 ++++--- .../apache/syncope/fit/AbstractITCase.java | 19 ++++++----- .../core/AbstractNotificationTaskITCase.java | 9 ++--- .../syncope/fit/core/AbstractTaskITCase.java | 21 ++++++------ .../apache/syncope/fit/core/BatchITCase.java | 13 ++++---- .../apache/syncope/fit/core/GroupITCase.java | 11 ++++--- .../syncope/fit/core/KeymasterITCase.java | 11 ++++--- .../syncope/fit/core/LiveSyncITCase.java | 9 ++--- .../syncope/fit/core/PullTaskITCase.java | 9 ++--- .../apache/syncope/fit/core/ReportITCase.java | 14 ++++---- .../org/apache/syncope/sra/RouteProvider.java | 29 ++++++++-------- .../syncope/sra/ZookeeperTestingServer.java | 21 ++++++------ .../wa/starter/ZookeeperTestingServer.java | 19 ++++++----- 35 files changed, 288 insertions(+), 253 deletions(-) diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/clientapps/ClientAppModalPanelBuilder.java b/client/am/console/src/main/java/org/apache/syncope/client/console/clientapps/ClientAppModalPanelBuilder.java index 4694247dc7c..784023fbe04 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/clientapps/ClientAppModalPanelBuilder.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/clientapps/ClientAppModalPanelBuilder.java @@ -301,7 +301,7 @@ protected void onUpdate(final AjaxRequestTarget target) { AjaxTextFieldPanel clientSecret = new AjaxTextFieldPanel( "field", "clientSecret", new PropertyModel<>(clientAppTO, "clientSecret"), false); clientSecret.setChoices(List.of(RandomStringUtils.secure().nextNumeric(15))); - fields.add(clientSecret.setRequired(true)); + fields.add(clientSecret); AjaxTextFieldPanel idTokenIssuer = new AjaxTextFieldPanel( "field", "idTokenIssuer", new PropertyModel<>(clientAppTO, "idTokenIssuer"), false); diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/panels/OIDC.java b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/OIDC.java index 4bc40ab029f..416752079af 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/panels/OIDC.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/OIDC.java @@ -21,7 +21,8 @@ import com.fasterxml.jackson.databind.json.JsonMapper; import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal; import java.io.IOException; -import java.util.concurrent.atomic.AtomicReference; +import java.util.Optional; +import org.apache.commons.lang3.mutable.Mutable; import org.apache.syncope.client.console.SyncopeConsoleSession; import org.apache.syncope.client.console.rest.OIDCJWKSRestClient; import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal; @@ -82,7 +83,7 @@ public OIDC(final String id, final String waPrefix, final PageReference pageRef) WebMarkupContainer container = new WebMarkupContainer("container"); add(container.setOutputMarkupId(true)); - AtomicReference oidcjwksto = oidcJWKSRestClient.get(); + Mutable oidcjwksto = oidcJWKSRestClient.get(); view = new AjaxLink<>("view") { @@ -93,10 +94,10 @@ public void onClick(final AjaxRequestTarget target) { String pretty; try { pretty = MAPPER.writerWithDefaultPrettyPrinter(). - writeValueAsString(MAPPER.readTree(oidcjwksto.get().getJson())); + writeValueAsString(MAPPER.readTree(oidcjwksto.getValue().getJson())); } catch (IOException e) { LOG.error("Could not pretty-print", e); - pretty = oidcjwksto.get().getJson(); + pretty = Optional.ofNullable(oidcjwksto.getValue()).map(OIDCJWKSTO::getJson).orElse(null); } viewModal.header(Model.of("JSON Web Key Sets")); @@ -108,12 +109,12 @@ public void onClick(final AjaxRequestTarget target) { protected void onComponentTag(final ComponentTag tag) { super.onComponentTag(tag); - if (oidcjwksto.get() == null) { + if (oidcjwksto.getValue() == null) { tag.put("class", "btn btn-app disabled"); } } }; - view.setEnabled(oidcjwksto.get() != null); + view.setEnabled(oidcjwksto.getValue() != null); container.add(view.setOutputMarkupId(true)); MetaDataRoleAuthorizationStrategy.authorize(view, ENABLE, AMEntitlement.OIDC_JWKS_READ); @@ -124,7 +125,7 @@ protected void onComponentTag(final ComponentTag tag) { @Override public void onClick(final AjaxRequestTarget target) { try { - oidcjwksto.set(oidcJWKSRestClient.generate()); + oidcjwksto.setValue(oidcJWKSRestClient.generate()); generate.setEnabled(false); view.setEnabled(true); @@ -141,12 +142,12 @@ public void onClick(final AjaxRequestTarget target) { protected void onComponentTag(final ComponentTag tag) { super.onComponentTag(tag); - if (oidcjwksto.get() != null) { + if (oidcjwksto.getValue() != null) { tag.put("class", "btn btn-app disabled"); } } }; - generate.setEnabled(oidcjwksto.get() == null); + generate.setEnabled(oidcjwksto.getValue() == null); container.add(generate.setOutputMarkupId(true)); MetaDataRoleAuthorizationStrategy.authorize(generate, ENABLE, AMEntitlement.OIDC_JWKS_GENERATE); @@ -158,7 +159,7 @@ protected void onComponentTag(final ComponentTag tag) { public void onClick(final AjaxRequestTarget target) { try { oidcJWKSRestClient.delete(); - oidcjwksto.set(null); + oidcjwksto.setValue(null); generate.setEnabled(true); view.setEnabled(false); @@ -175,12 +176,12 @@ public void onClick(final AjaxRequestTarget target) { protected void onComponentTag(final ComponentTag tag) { super.onComponentTag(tag); - if (oidcjwksto.get() == null) { + if (oidcjwksto.getValue() == null) { tag.put("class", "btn btn-app disabled"); } } }; - delete.setEnabled(oidcjwksto.get() != null); + delete.setEnabled(oidcjwksto.getValue() != null); container.add(delete.setOutputMarkupId(true)); MetaDataRoleAuthorizationStrategy.authorize(delete, ENABLE, AMEntitlement.OIDC_JWKS_DELETE); diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/rest/OIDCJWKSRestClient.java b/client/am/console/src/main/java/org/apache/syncope/client/console/rest/OIDCJWKSRestClient.java index 8743bd71106..864cfaace10 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/rest/OIDCJWKSRestClient.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/rest/OIDCJWKSRestClient.java @@ -19,7 +19,8 @@ package org.apache.syncope.client.console.rest; import jakarta.ws.rs.core.Response; -import java.util.concurrent.atomic.AtomicReference; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.syncope.common.lib.to.OIDCJWKSTO; import org.apache.syncope.common.rest.api.service.OIDCJWKSService; @@ -27,10 +28,10 @@ public class OIDCJWKSRestClient extends BaseRestClient { private static final long serialVersionUID = -1392090291817187902L; - public AtomicReference get() { - AtomicReference result = new AtomicReference<>(); + public Mutable get() { + MutableObject result = new MutableObject<>(); try { - result.set(getService(OIDCJWKSService.class).get()); + result.setValue(getService(OIDCJWKSService.class).get()); } catch (Exception e) { LOG.debug("While getting OIDC JKS", e); } diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.java index 466b5d2c236..9ed98ba837b 100644 --- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.java +++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/any/LinkedAccountDetailsPanel.java @@ -23,9 +23,10 @@ import java.util.List; import java.util.Objects; import java.util.Optional; -import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.commons.lang3.tuple.Pair; import org.apache.syncope.client.console.rest.ResourceRestClient; import org.apache.syncope.client.lib.SyncopeClient; @@ -159,12 +160,12 @@ private void setConnObjectFieldChoices( final String resource, final String searchTerm) { - AtomicReference resourceRemoteKey = new AtomicReference<>(ConnIdSpecialName.NAME); + Mutable resourceRemoteKey = new MutableObject<>(ConnIdSpecialName.NAME); try { resourceRestClient.read(resource).getProvision(AnyTypeKind.USER.name()). flatMap(provision -> Optional.ofNullable(provision.getMapping())). flatMap(ItemContainer::getConnObjectKeyItem). - ifPresent(connObjectKeyItem -> resourceRemoteKey.set(connObjectKeyItem.getExtAttrName())); + ifPresent(connObjectKeyItem -> resourceRemoteKey.setValue(connObjectKeyItem.getExtAttrName())); } catch (Exception ex) { LOG.error("While reading mapping for resource {}", resource, ex); } @@ -172,17 +173,17 @@ private void setConnObjectFieldChoices( ConnObjectTOQuery.Builder builder = new ConnObjectTOQuery.Builder().size(SEARCH_SIZE); if (StringUtils.isNotBlank(searchTerm)) { builder.fiql(SyncopeClient.getConnObjectTOFiqlSearchConditionBuilder(). - is(resourceRemoteKey.get()).equalTo(searchTerm + "*").query()).build(); + is(resourceRemoteKey.getValue()).equalTo(searchTerm + "*").query()).build(); } Pair> items = resourceRestClient.searchConnObjects( resource, AnyTypeKind.USER.name(), builder, - new SortParam<>(resourceRemoteKey.get(), true)); + new SortParam<>(resourceRemoteKey.getValue(), true)); connObjectKeyFieldValues = items.getRight().stream(). - map(item -> item.getAttr(resourceRemoteKey.get()). - map(attr -> attr.getValues().getFirst()).orElse(null)). + map(item -> item.getAttr(resourceRemoteKey.getValue()). + map(attr -> attr.getValues().getFirst()).orElse(null)). filter(Objects::nonNull). collect(Collectors.toList()); ajaxTextFieldPanel.setChoices(connObjectKeyFieldValues); diff --git a/common/keymaster/client-zookeeper/src/test/java/org/apache/syncope/common/keymaster/client/zookeeper/ZookeeperTestingServer.java b/common/keymaster/client-zookeeper/src/test/java/org/apache/syncope/common/keymaster/client/zookeeper/ZookeeperTestingServer.java index bd7682684d7..c9748120d71 100644 --- a/common/keymaster/client-zookeeper/src/test/java/org/apache/syncope/common/keymaster/client/zookeeper/ZookeeperTestingServer.java +++ b/common/keymaster/client-zookeeper/src/test/java/org/apache/syncope/common/keymaster/client/zookeeper/ZookeeperTestingServer.java @@ -24,9 +24,10 @@ import java.util.HashMap; import java.util.Map; import java.util.Properties; -import java.util.concurrent.atomic.AtomicReference; import javax.security.auth.login.AppConfigurationEntry; import javax.security.auth.login.Configuration; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.curator.test.InstanceSpec; import org.apache.curator.test.TestingServer; @@ -36,14 +37,14 @@ public final class ZookeeperTestingServer { public static void start() throws Exception { if (ZK_SERVER == null) { - AtomicReference username = new AtomicReference<>(); - AtomicReference password = new AtomicReference<>(); + Mutable username = new MutableObject<>(); + Mutable password = new MutableObject<>(); try (InputStream propStream = ZookeeperServiceOpsTest.class.getResourceAsStream("/test.properties")) { Properties props = new Properties(); props.load(propStream); - username.set(props.getProperty("keymaster.username")); - password.set(props.getProperty("keymaster.password")); + username.setValue(props.getProperty("keymaster.username")); + password.setValue(props.getProperty("keymaster.password")); } catch (Exception e) { fail("Could not load /test.properties", e); } @@ -55,7 +56,7 @@ public static void start() throws Exception { "org.apache.zookeeper.server.auth.DigestLoginModule", AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, Map.of( - "user_" + username.get(), password.get() + "user_" + username.getValue(), password.getValue() )) }; diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java index 6edfdbcd35f..ba8631710d7 100644 --- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java +++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java @@ -245,8 +245,7 @@ public ProvisioningResult update(final GroupUR req, final boolean nullP @PreAuthorize("hasRole('" + IdRepoEntitlement.GROUP_DELETE + "')") @Override public ProvisioningResult delete(final String key, final boolean nullPriorityAsync) { - GroupTO group = binder.getGroupTO(key); - Pair> before = beforeDelete(group); + Pair> before = beforeDelete(binder.getGroupTO(key)); Set authRealms = RealmUtils.getEffective( AuthContextUtils.getAuthorizations().get(IdRepoEntitlement.GROUP_DELETE), @@ -267,10 +266,15 @@ public ProvisioningResult delete(final String key, final boolean nullPr List statuses = provisioningManager.delete( before.getLeft().getKey(), nullPriorityAsync, AuthContextUtils.getUsername(), REST_CONTEXT); - GroupTO groupTO = new GroupTO(); - groupTO.setKey(before.getLeft().getKey()); + GroupTO deletedTO; + if (groupDAO.existsById(before.getLeft().getKey())) { + deletedTO = binder.getGroupTO(before.getLeft().getKey()); + } else { + deletedTO = new GroupTO(); + deletedTO.setKey(before.getLeft().getKey()); + } - return afterDelete(groupTO, statuses, before.getRight()); + return afterDelete(deletedTO, statuses, before.getRight()); } protected GroupTO updateChecks(final String key) { diff --git a/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/utils/URIUtilsTest.java b/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/utils/URIUtilsTest.java index 15b1e89d9d4..ce39e187328 100644 --- a/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/utils/URIUtilsTest.java +++ b/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/utils/URIUtilsTest.java @@ -25,22 +25,23 @@ import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; -import java.util.concurrent.atomic.AtomicReference; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.junit.jupiter.api.Test; public class URIUtilsTest extends AbstractTest { @Test public void buildForConnId() throws URISyntaxException, MalformedURLException { - AtomicReference location = new AtomicReference<>(); - location.set("www.tirasa.net"); + Mutable location = new MutableObject<>(); + location.setValue("www.tirasa.net"); IllegalArgumentException exception = - assertThrows(IllegalArgumentException.class, () -> URIUtils.buildForConnId(location.get())); + assertThrows(IllegalArgumentException.class, () -> URIUtils.buildForConnId(location.getValue())); assertEquals(exception.getClass(), IllegalArgumentException.class); - location.set("connid:test/location"); - URI expectedURI = new URI(location.get().trim()); - assertEquals(expectedURI, URIUtils.buildForConnId(location.get())); + location.setValue("connid:test/location"); + URI expectedURI = new URI(location.getValue().trim()); + assertEquals(expectedURI, URIUtils.buildForConnId(location.getValue())); assertDoesNotThrow(() -> URIUtils.buildForConnId("file:Z:\\syncope\\fit\\core-reference\\target/bundles/")); assertDoesNotThrow(() -> URIUtils.buildForConnId("file:/Z:\\syncope\\fit\\core-reference\\target/bundles/")); diff --git a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/AttributableValidator.java b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/AttributableValidator.java index 72b71e076de..92d20b6bfc9 100644 --- a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/AttributableValidator.java +++ b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/AttributableValidator.java @@ -19,7 +19,8 @@ package org.apache.syncope.core.persistence.common.validation; import jakarta.validation.ConstraintValidatorContext; -import java.util.concurrent.atomic.AtomicReference; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.syncope.common.lib.types.EntityViolationType; import org.apache.syncope.core.persistence.api.ApplicationContextProvider; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; @@ -112,20 +113,18 @@ public boolean isValid(final Attributable entity, final ConstraintValidatorConte context.disableDefaultConstraintViolation(); - AtomicReference isValid = new AtomicReference<>(Boolean.TRUE); - entity.getPlainAttrs().forEach(attr -> { - PlainSchema schema = schemaDAO.findById(attr.getSchema()).orElse(null); - if (schema == null) { - isValid.getAndSet(false); - context.buildConstraintViolationWithTemplate( - getTemplate(EntityViolationType.InvalidSchema, "Invalid schema " + attr.getSchema())). - addPropertyNode(attr.getSchema()).addConstraintViolation(); - } else { - isValid.getAndSet(isValid.get() && isValid(attr, schema, context)); - attr.getValues().forEach(value -> isValid.getAndSet(isValid.get() && isValid(value, context))); - } - }); - - return isValid.get(); + Mutable isValid = new MutableObject<>(true); + entity.getPlainAttrs().forEach(attr -> schemaDAO.findById(attr.getSchema()).ifPresentOrElse( + schema -> { + isValid.setValue(isValid.getValue() && isValid(attr, schema, context)); + attr.getValues().forEach(value -> isValid.setValue(isValid.getValue() && isValid(value, context))); + }, () -> { + isValid.setValue(false); + context.buildConstraintViolationWithTemplate( + getTemplate(EntityViolationType.InvalidSchema, "Invalid schema " + attr.getSchema())). + addPropertyNode(attr.getSchema()).addConstraintViolation(); + })); + + return isValid.getValue(); } } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/ExternalResourceRepoExtImpl.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/ExternalResourceRepoExtImpl.java index 1a4a600a938..184087be017 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/ExternalResourceRepoExtImpl.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/ExternalResourceRepoExtImpl.java @@ -22,7 +22,8 @@ import jakarta.persistence.TypedQuery; import java.util.List; import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.syncope.common.lib.types.IdMEntitlement; import org.apache.syncope.common.lib.types.TaskType; import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; @@ -150,14 +151,14 @@ public ExternalResource save(final ExternalResource resource) { @Override public void deleteMapping(final String schemaKey) { findAll().forEach(resource -> { - AtomicBoolean removed = new AtomicBoolean(false); + Mutable removed = new MutableObject<>(false); - resource.getProvisions().forEach(provision -> removed.set( - removed.get() + resource.getProvisions().forEach(provision -> removed.setValue( + removed.getValue() || (provision.getMapping() != null && provision.getMapping().getItems().removeIf(item -> schemaKey.equals(item.getIntAttrName()))))); - if (removed.get()) { + if (removed.getValue()) { entityManager.merge(resource); } }); diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/ExternalResourceRepoExtImpl.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/ExternalResourceRepoExtImpl.java index dfd1f22da31..47c76c4a2d2 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/ExternalResourceRepoExtImpl.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/ExternalResourceRepoExtImpl.java @@ -21,8 +21,9 @@ import java.util.List; import java.util.Optional; import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; import javax.cache.Cache; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.syncope.common.lib.types.IdMEntitlement; import org.apache.syncope.common.lib.types.TaskType; import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; @@ -275,14 +276,14 @@ public ExternalResource save(final ExternalResource resource) { @Override public void deleteMapping(final String schemaKey) { findAll().forEach(resource -> { - AtomicBoolean removed = new AtomicBoolean(false); + Mutable removed = new MutableObject<>(false); - resource.getProvisions().forEach(provision -> removed.set( - removed.get() + resource.getProvisions().forEach(provision -> removed.setValue( + removed.getValue() || (provision.getMapping() != null && provision.getMapping().getItems().removeIf(item -> schemaKey.equals(item.getIntAttrName()))))); - if (removed.get()) { + if (removed.getValue()) { ((Neo4jExternalResource) resource).list2json(); ExternalResource saved = neo4jTemplate.save(resource); ((Neo4jExternalResource) saved).postSave(); diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java index 51ff2875045..0cce5d60b0f 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/Connector.java @@ -21,7 +21,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; +import org.apache.commons.lang3.mutable.Mutable; import org.apache.syncope.core.persistence.api.entity.ConnInstance; import org.apache.syncope.core.provisioning.api.pushpull.ReconFilterBuilder; import org.identityconnectors.framework.common.objects.Attribute; @@ -71,7 +71,7 @@ Uid create( ObjectClass objectClass, Set attrs, OperationOptions options, - AtomicReference propagationAttempted); + Mutable propagationAttempted); /** * Update user, group or any object on a connector instance. @@ -88,7 +88,7 @@ Uid update( Uid uid, Set attrs, OperationOptions options, - AtomicReference propagationAttempted); + Mutable propagationAttempted); /** * Partial update user, group or any object on a connector instance. @@ -105,7 +105,7 @@ Set updateDelta( Uid uid, Set modifications, OperationOptions options, - AtomicReference propagationAttempted); + Mutable propagationAttempted); /** * Delete user, group or any object on a connector instance. @@ -119,7 +119,7 @@ void delete( ObjectClass objectClass, Uid uid, OperationOptions options, - AtomicReference propagationAttempted); + Mutable propagationAttempted); /** * Fetches all remote objects (for use during full reconciliation). diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java index 9444d6fc4de..ae678a0dd14 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java @@ -25,7 +25,7 @@ import java.util.Set; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; +import org.apache.commons.lang3.mutable.Mutable; import org.apache.syncope.common.lib.types.ConnectorCapability; import org.apache.syncope.core.persistence.api.ApplicationContextProvider; import org.apache.syncope.core.persistence.api.entity.ConnInstance; @@ -162,12 +162,12 @@ public Uid create( final ObjectClass objectClass, final Set attrs, final OperationOptions options, - final AtomicReference propagationAttempted) { + final Mutable propagationAttempted) { Uid result = null; if (connInstance.getCapabilities().contains(ConnectorCapability.CREATE)) { - propagationAttempted.set(true); + propagationAttempted.setValue(true); Future future = asyncFacade.create(connector, objectClass, attrs, options); try { @@ -197,12 +197,12 @@ public Uid update( final Uid uid, final Set attrs, final OperationOptions options, - final AtomicReference propagationAttempted) { + final Mutable propagationAttempted) { Uid result = null; if (connInstance.getCapabilities().contains(ConnectorCapability.UPDATE)) { - propagationAttempted.set(true); + propagationAttempted.setValue(true); Future future = asyncFacade.update(connector, objectClass, uid, attrs, options); @@ -234,12 +234,12 @@ public Set updateDelta( final Uid uid, final Set modifications, final OperationOptions options, - final AtomicReference propagationAttempted) { + final Mutable propagationAttempted) { Set result = null; if (connInstance.getCapabilities().contains(ConnectorCapability.UPDATE_DELTA)) { - propagationAttempted.set(true); + propagationAttempted.setValue(true); Future> future = asyncFacade.updateDelta(connector, objectClass, uid, modifications, options); @@ -271,10 +271,10 @@ public void delete( final ObjectClass objectClass, final Uid uid, final OperationOptions options, - final AtomicReference propagationAttempted) { + final Mutable propagationAttempted) { if (connInstance.getCapabilities().contains(ConnectorCapability.DELETE)) { - propagationAttempted.set(true); + propagationAttempted.setValue(true); Future future = asyncFacade.delete(connector, objectClass, uid, options); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java index bde85abe237..001ecce60c5 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java @@ -27,13 +27,14 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import javax.cache.Cache; import org.apache.commons.jexl3.JexlContext; import org.apache.commons.jexl3.MapContext; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.commons.lang3.reflect.FieldUtils; import org.apache.commons.lang3.tuple.Pair; import org.apache.syncope.common.lib.Attr; @@ -329,7 +330,7 @@ public Pair> prepareAttrsFromAny( any, provision, any.getPlainAttrs()); Set attributes = new HashSet<>(); - AtomicReference connObjectKeyValue = new AtomicReference<>(); + Mutable connObjectKeyValue = new MutableObject<>(); MappingUtils.getPropagationItems(provision.getMapping().getItems().stream()).forEach(mapItem -> { LOG.debug("Processing expression '{}'", mapItem.getIntAttrName()); @@ -345,25 +346,25 @@ public Pair> prepareAttrsFromAny( AccountGetter.DEFAULT, AccountGetter.DEFAULT, PlainAttrGetter.DEFAULT), - attributes).ifPresent(connObjectKeyValue::set); + attributes).ifPresent(connObjectKeyValue::setValue); } catch (Exception e) { LOG.error("Expression '{}' processing failed", mapItem.getIntAttrName(), e); } }); - MappingUtils.getConnObjectKeyItem(provision).ifPresent(connObjectKeyItem -> { - Attribute connObjectKeyAttr = AttributeUtil.find(connObjectKeyItem.getExtAttrName(), attributes); + MappingUtils.getConnObjectKeyItem(provision).ifPresent(item -> { + Attribute connObjectKeyAttr = AttributeUtil.find(item.getExtAttrName(), attributes); if (connObjectKeyAttr != null) { attributes.remove(connObjectKeyAttr); - attributes.add(AttributeBuilder.build(connObjectKeyItem.getExtAttrName(), connObjectKeyValue.get())); + attributes.add(AttributeBuilder.build(item.getExtAttrName(), connObjectKeyValue.getValue())); } - Name name = evaluateNAME(any, provision, connObjectKeyValue.get()); + Name name = evaluateNAME(any, provision, connObjectKeyValue.getValue()); attributes.add(name); - Optional.ofNullable(connObjectKeyValue.get()). + Optional.ofNullable(connObjectKeyValue.getValue()). filter(cokv -> connObjectKeyAttr == null && !cokv.equals(name.getNameValue())). - ifPresent(cokv -> attributes.add(AttributeBuilder.build(connObjectKeyItem.getExtAttrName(), cokv))); + ifPresent(cokv -> attributes.add(AttributeBuilder.build(item.getExtAttrName(), cokv))); }); Optional.ofNullable(enable).ifPresent(e -> attributes.add(AttributeBuilder.buildEnabled(e))); @@ -373,7 +374,7 @@ public Pair> prepareAttrsFromAny( ifPresent(attributes::remove); } - return Pair.of(connObjectKeyValue.get(), attributes); + return Pair.of(connObjectKeyValue.getValue(), attributes); } @Transactional(readOnly = true) @@ -452,7 +453,7 @@ public Pair> prepareAttrsFromRealm(final Realm realm, fin LOG.debug("Preparing resource attributes for {} with orgUnit {}", realm, orgUnit); Set attributes = new HashSet<>(); - AtomicReference connObjectKeyValue = new AtomicReference<>(); + Mutable connObjectKeyValue = new MutableObject<>(); MappingUtils.getPropagationItems(orgUnit.getItems().stream()).forEach(orgUnitItem -> { LOG.debug("Processing expression '{}'", orgUnitItem.getIntAttrName()); @@ -460,7 +461,7 @@ public Pair> prepareAttrsFromRealm(final Realm realm, fin String value = getIntValue(realm, orgUnitItem); if (orgUnitItem.isConnObjectKey()) { - connObjectKeyValue.set(value); + connObjectKeyValue.setValue(value); } Optional.ofNullable(AttributeUtil.find(orgUnitItem.getExtAttrName(), attributes)).ifPresentOrElse( @@ -487,12 +488,12 @@ public Pair> prepareAttrsFromRealm(final Realm realm, fin orgUnit.getConnObjectKeyItem().ifPresent(item -> { Optional.ofNullable(AttributeUtil.find(item.getExtAttrName(), attributes)).ifPresent(attr -> { attributes.remove(attr); - attributes.add(AttributeBuilder.build(item.getExtAttrName(), connObjectKeyValue.get())); + attributes.add(AttributeBuilder.build(item.getExtAttrName(), connObjectKeyValue.getValue())); }); - attributes.add(evaluateNAME(realm, orgUnit, connObjectKeyValue.get())); + attributes.add(evaluateNAME(realm, orgUnit, connObjectKeyValue.getValue())); }); - return Pair.of(connObjectKeyValue.get(), attributes); + return Pair.of(connObjectKeyValue.getValue(), attributes); } protected Optional decodePassword(final Account account) { @@ -991,7 +992,7 @@ public void setIntValues(final Item mapItem, final Attribute attr, final AnyTO a GroupableRelatableTO groupableTO; Group group; if (anyTO instanceof final GroupableRelatableTO groupableRelatableTO - && intAttrName.getMembershipOfGroup() != null) { + && intAttrName.getMembershipOfGroup() != null) { groupableTO = groupableRelatableTO; group = groupDAO.findByName(intAttrName.getMembershipOfGroup()).orElse(null); } else { diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java index 04ca6712e54..546a4f16153 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java @@ -21,10 +21,11 @@ import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.atomic.AtomicReference; import org.apache.commons.jexl3.JexlContext; import org.apache.commons.jexl3.MapContext; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.commons.lang3.tuple.Pair; import org.apache.syncope.common.lib.to.AnyTO; import org.apache.syncope.common.lib.to.EntityTO; @@ -150,16 +151,16 @@ public Pair> beforePropagation( return JEXLItemTransformer.super.beforePropagation(item, any, schemaType, values); } - AtomicReference tType = new AtomicReference<>(); + Mutable tType = new MutableObject<>(); if (values.isEmpty()) { PlainAttrValue value = new PlainAttrValue(); - tType.set(beforePropagation(any, schemaType, value)); + tType.setValue(beforePropagation(any, schemaType, value)); values.add(value); } else { - values.forEach(value -> tType.set(beforePropagation(any, schemaType, value))); + values.forEach(value -> tType.setValue(beforePropagation(any, schemaType, value))); } - return Pair.of(tType.get(), values); + return Pair.of(tType.getValue(), values); } @Override diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java index 840c424313e..39489825a5a 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java @@ -19,8 +19,9 @@ package org.apache.syncope.core.provisioning.java.data; import java.util.Optional; -import java.util.concurrent.atomic.AtomicReference; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.syncope.common.lib.SyncopeClientCompositeException; import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.to.DerSchemaTO; @@ -138,7 +139,7 @@ protected PlainSchema fill(final PlainSchema schema, final PlainSchemaTO schemaT PlainSchema saved = plainSchemaDAO.save(schema); - AtomicReference atc = new AtomicReference<>(); + Mutable atc = new MutableObject<>(); if (schemaTO.getAnyTypeClass() != null && (saved.getAnyTypeClass() == null || !schemaTO.getAnyTypeClass().equals(saved.getAnyTypeClass().getKey()))) { @@ -148,7 +149,7 @@ protected PlainSchema fill(final PlainSchema schema, final PlainSchemaTO schemaT anyTypeClass.add(saved); saved.setAnyTypeClass(anyTypeClass); - atc.set(anyTypeClass); + atc.setValue(anyTypeClass); }, () -> LOG.debug("Invalid {}{}, ignoring...", AnyTypeClass.class.getSimpleName(), schemaTO.getAnyTypeClass())); @@ -156,11 +157,11 @@ protected PlainSchema fill(final PlainSchema schema, final PlainSchemaTO schemaT saved.getAnyTypeClass().getPlainSchemas().remove(saved); saved.setAnyTypeClass(null); - atc.set(saved.getAnyTypeClass()); + atc.setValue(saved.getAnyTypeClass()); } PlainSchema filled = plainSchemaDAO.save(saved); - Optional.ofNullable(atc.get()).ifPresent(anyTypeClassDAO::save); + Optional.ofNullable(atc.getValue()).ifPresent(anyTypeClassDAO::save); return filled; } @@ -252,7 +253,7 @@ protected DerSchema fill(final DerSchema schema, final DerSchemaTO schemaTO) { DerSchema saved = derSchemaDAO.save(schema); - AtomicReference atc = new AtomicReference<>(); + Mutable atc = new MutableObject<>(); if (schemaTO.getAnyTypeClass() != null && (saved.getAnyTypeClass() == null || !schemaTO.getAnyTypeClass().equals(saved.getAnyTypeClass().getKey()))) { @@ -262,7 +263,7 @@ protected DerSchema fill(final DerSchema schema, final DerSchemaTO schemaTO) { anyTypeClass.add(saved); saved.setAnyTypeClass(anyTypeClass); - atc.set(anyTypeClass); + atc.setValue(anyTypeClass); }, () -> LOG.debug("Invalid {}{}, ignoring...", AnyTypeClass.class.getSimpleName(), schemaTO.getAnyTypeClass())); @@ -270,11 +271,11 @@ protected DerSchema fill(final DerSchema schema, final DerSchemaTO schemaTO) { saved.getAnyTypeClass().getDerSchemas().remove(saved); saved.setAnyTypeClass(null); - atc.set(saved.getAnyTypeClass()); + atc.setValue(saved.getAnyTypeClass()); } DerSchema filled = derSchemaDAO.save(saved); - Optional.ofNullable(atc.get()).ifPresent(anyTypeClassDAO::save); + Optional.ofNullable(atc.getValue()).ifPresent(anyTypeClassDAO::save); return filled; } @@ -332,7 +333,7 @@ protected VirSchema fill(final VirSchema schema, final VirSchemaTO schemaTO) { VirSchema saved = virSchemaDAO.save(schema); - AtomicReference atc = new AtomicReference<>(); + Mutable atc = new MutableObject<>(); if (schemaTO.getAnyTypeClass() != null && (saved.getAnyTypeClass() == null || !schemaTO.getAnyTypeClass().equals(saved.getAnyTypeClass().getKey()))) { @@ -342,7 +343,7 @@ protected VirSchema fill(final VirSchema schema, final VirSchemaTO schemaTO) { anyTypeClass.add(saved); saved.setAnyTypeClass(anyTypeClass); - atc.set(anyTypeClass); + atc.setValue(anyTypeClass); }, () -> LOG.debug("Invalid {}{}, ignoring...", AnyTypeClass.class.getSimpleName(), schemaTO.getAnyTypeClass())); @@ -350,11 +351,11 @@ protected VirSchema fill(final VirSchema schema, final VirSchemaTO schemaTO) { saved.getAnyTypeClass().getVirSchemas().remove(saved); saved.setAnyTypeClass(null); - atc.set(saved.getAnyTypeClass()); + atc.setValue(saved.getAnyTypeClass()); } VirSchema filled = virSchemaDAO.save(saved); - Optional.ofNullable(atc.get()).ifPresent(anyTypeClassDAO::save); + Optional.ofNullable(atc.getValue()).ifPresent(anyTypeClassDAO::save); return filled; } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/MacroJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/MacroJobDelegate.java index 475e9f86e35..a2fd5aa0dff 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/MacroJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/MacroJobDelegate.java @@ -32,13 +32,14 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import org.apache.commons.jexl3.JexlContext; import org.apache.commons.jexl3.MapContext; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.commons.lang3.tuple.Pair; import org.apache.syncope.common.lib.command.CommandArgs; import org.apache.syncope.common.lib.form.FormProperty; @@ -155,7 +156,7 @@ protected Optional check( : List.of(value.split(";")); if (!actions.map(a -> a.getDropdownValues(fpd.getName()).keySet()). - orElseGet(Set::of).containsAll(values)) { + orElseGet(Set::of).containsAll(values)) { throw new JobExecutionException("Not allowed for " + fpd.getName() + ": " + values); } @@ -188,12 +189,12 @@ protected String run( final boolean dryRun) throws JobExecutionException { - Future>> future = taskExecutor.submit( + Future>> future = taskExecutor.submit( new DelegatingSecurityContextCallable<>(() -> { - AtomicReference> error = new AtomicReference<>(); + Mutable> error = new MutableObject<>(); - for (int i = 0; i < commands.size() && error.get() == null; i++) { + for (int i = 0; i < commands.size() && error.getValue() == null; i++) { Pair, CommandArgs> command = commands.get(i); try { @@ -217,7 +218,7 @@ protected String run( LOG.error("While running {} with args {}, continuing on error", command.getLeft().getClass().getName(), command.getRight(), t); } else { - error.set(Pair.of(AopUtils.getTargetClass(command.getLeft()).getName(), t)); + error.setValue(Pair.of(AopUtils.getTargetClass(command.getLeft()).getName(), t)); } } output.append("\n\n"); @@ -227,9 +228,10 @@ protected String run( })); try { - AtomicReference> error = future.get(); - if (error.get() != null) { - throw new JobExecutionException("While running " + error.get().getLeft(), error.get().getRight()); + Mutable> error = future.get(); + if (error.getValue() != null) { + throw new JobExecutionException("While running " + + error.getValue().getLeft(), error.getValue().getRight()); } } catch (ExecutionException | InterruptedException e) { throw new JobExecutionException("While waiting for macro commands completion", e); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java index b3cff0c3b4a..b26a0af4a5e 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java @@ -28,9 +28,10 @@ import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.stream.Collectors; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.syncope.common.lib.to.ExecTO; import org.apache.syncope.common.lib.to.Item; import org.apache.syncope.common.lib.to.OrgUnit; @@ -218,7 +219,7 @@ protected void checkMandatoryMissing( protected Uid doCreate( final PropagationTaskInfo taskInfo, final Connector connector, - final AtomicReference propagationAttempted) { + final Mutable propagationAttempted) { Set attrs = taskInfo.getPropagationData().getAttributes(); @@ -257,7 +258,7 @@ protected Uid doUpdate( final PropagationTaskInfo taskInfo, final Connector connector, final ConnectorObject beforeObj, - final AtomicReference propagationAttempted) { + final Mutable propagationAttempted) { Set attrs = taskInfo.getPropagationData().getAttributes(); @@ -321,7 +322,7 @@ protected Uid doUpdateDelta( final PropagationTaskInfo taskInfo, final Set modifications, final Connector connector, - final AtomicReference propagationAttempted) { + final Mutable propagationAttempted) { Uid uid = new Uid(taskInfo.getConnObjectKey()); @@ -346,7 +347,7 @@ protected Uid createOrUpdate( final boolean fetchRemoteObj, final ConnectorObject beforeObj, final Connector connector, - final AtomicReference propagationAttempted) { + final Mutable propagationAttempted) { PropagationData propagationData = taskInfo.getPropagationData(); @@ -370,7 +371,7 @@ protected Uid delete( final boolean fetchRemoteObj, final ConnectorObject beforeObj, final Connector connector, - final AtomicReference propagationAttempted) { + final Mutable propagationAttempted) { Uid result; @@ -547,7 +548,7 @@ protected TaskExec doExecute( String failureReason = null; // Flag to state whether any propagation has been attempted - AtomicReference propagationAttempted = new AtomicReference<>(false); + Mutable propagationAttempted = new MutableObject<>(false); boolean fetchRemoteObj = isFetchRemoteObj(taskInfo); @@ -592,7 +593,7 @@ protected TaskExec doExecute( default: } - exec.setStatus(propagationAttempted.get() + exec.setStatus(propagationAttempted.getValue() ? ExecStatus.SUCCESS.name() : ExecStatus.NOT_ATTEMPTED.name()); @@ -604,7 +605,7 @@ protected TaskExec doExecute( exec.setStatus(ExecStatus.FAILURE.name()); - propagationAttempted.set(true); + propagationAttempted.setValue(true); LOG.error("Exception during provision on resource {}", taskInfo.getResource().getKey(), e); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/CSVStreamConnector.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/CSVStreamConnector.java index 7fec41ffb77..cfe628e1168 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/CSVStreamConnector.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/CSVStreamConnector.java @@ -31,9 +31,9 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.mutable.Mutable; import org.apache.syncope.common.rest.api.beans.CSVPullSpec; import org.apache.syncope.core.persistence.api.entity.ConnInstance; import org.apache.syncope.core.provisioning.api.Connector; @@ -149,7 +149,7 @@ public Uid create( final ObjectClass objectClass, final Set attrs, final OperationOptions options, - final AtomicReference propagationAttempted) { + final Mutable propagationAttempted) { synchronized (schemaBuilder) { if (schemaBuilder.size() == 0) { @@ -190,7 +190,7 @@ public Uid create( } catch (IOException e) { throw new ConnectorException("Could not write object " + row, e); } - propagationAttempted.set(Boolean.TRUE); + propagationAttempted.setValue(true); return null; } @@ -200,7 +200,7 @@ public Uid update( final Uid uid, final Set attrs, final OperationOptions options, - final AtomicReference propagationAttempted) { + final Mutable propagationAttempted) { return null; } @@ -211,7 +211,7 @@ public Set updateDelta( final Uid uid, final Set modifications, final OperationOptions options, - final AtomicReference propagationAttempted) { + final Mutable propagationAttempted) { return Set.of(); } @@ -221,7 +221,7 @@ public void delete( final ObjectClass objectClass, final Uid uid, final OperationOptions options, - final AtomicReference propagationAttempted) { + final Mutable propagationAttempted) { // nothing to do } diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/job/SyncopeTaskSchedulerTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/job/SyncopeTaskSchedulerTest.java index 50969dd3b5c..2882d5527c6 100644 --- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/job/SyncopeTaskSchedulerTest.java +++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/job/SyncopeTaskSchedulerTest.java @@ -27,7 +27,8 @@ import java.time.Instant; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.syncope.core.persistence.api.dao.JobStatusDAO; import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; import org.apache.syncope.core.provisioning.api.job.JobExecutionException; @@ -42,13 +43,13 @@ @Transactional public class SyncopeTaskSchedulerTest extends AbstractTest { - private static final AtomicInteger VALUE = new AtomicInteger(); + private static final Mutable VALUE = new MutableObject<>(0); private static class TestJob extends Job { @Override protected void execute(final JobExecutionContext context) throws JobExecutionException { - VALUE.set(1); + VALUE.setValue(1); } } @@ -76,6 +77,6 @@ public void schedule() { assertTrue(scheduler.getNextTrigger(AuthContextUtils.getDomain(), job.getContext().getJobName()).isPresent()); - await().atMost(10, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> VALUE.get() == 1); + await().atMost(10, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> VALUE.getValue() == 1); } } diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/UsernamePasswordAuthenticationProvider.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/UsernamePasswordAuthenticationProvider.java index dd9e119eace..99c8e1ea136 100644 --- a/core/spring/src/main/java/org/apache/syncope/core/spring/security/UsernamePasswordAuthenticationProvider.java +++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/UsernamePasswordAuthenticationProvider.java @@ -19,8 +19,9 @@ package org.apache.syncope.core.spring.security; import java.util.Optional; -import java.util.concurrent.atomic.AtomicReference; import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.commons.lang3.tuple.Triple; import org.apache.syncope.common.keymaster.client.api.DomainOps; import org.apache.syncope.common.keymaster.client.api.KeymasterException; @@ -90,16 +91,16 @@ public Authentication authenticate(final Authentication authentication) { } } - AtomicReference username = new AtomicReference<>(); + Mutable username = new MutableObject<>(); Boolean authenticated; - AtomicReference delegationKey = new AtomicReference<>(); + Mutable delegationKey = new MutableObject<>(); if (securityProperties.getAnonymousUser().equals(authentication.getName())) { - username.set(securityProperties.getAnonymousUser()); + username.setValue(securityProperties.getAnonymousUser()); credentialChecker.checkIsDefaultAnonymousKeyInUse(); authenticated = authentication.getCredentials().toString().equals(securityProperties.getAnonymousKey()); } else if (securityProperties.getAdminUser().equals(authentication.getName())) { - username.set(securityProperties.getAdminUser()); + username.setValue(securityProperties.getAdminUser()); if (SyncopeConstants.MASTER_DOMAIN.equals(domainKey)) { credentialChecker.checkIsDefaultAdminPasswordInUse(); authenticated = encryptorManager.getInstance().verify( @@ -121,20 +122,21 @@ public Authentication authenticate(final Authentication authentication) { () -> dataAccessor.authenticate(domainKey, authentication)); authenticated = authResult.getMiddle(); if (authResult.getLeft() != null && authResult.getMiddle() != null) { - username.set(authResult.getLeft().getUsername()); + username.setValue(authResult.getLeft().getUsername()); if (!authenticated) { AuthContextUtils.runAsAdmin(domainKey, () -> provisioningManager.internalSuspend( authResult.getLeft().getKey(), securityProperties.getAdminUser(), "Failed authentication")); } } - delegationKey.set(authResult.getRight()); + delegationKey.setValue(authResult.getRight()); } - if (username.get() == null) { - username.set(authentication.getPrincipal().toString()); + if (username.getValue() == null) { + username.setValue(authentication.getPrincipal().toString()); } - return finalizeAuthentication(authenticated, domainKey, username.get(), delegationKey.get(), authentication); + return finalizeAuthentication( + authenticated, domainKey, username.getValue(), delegationKey.getValue(), authentication); } protected Authentication finalizeAuthentication( diff --git a/core/starter/src/main/java/org/apache/syncope/core/starter/actuate/DomainsHealthIndicator.java b/core/starter/src/main/java/org/apache/syncope/core/starter/actuate/DomainsHealthIndicator.java index ff3143da206..9742c96250e 100644 --- a/core/starter/src/main/java/org/apache/syncope/core/starter/actuate/DomainsHealthIndicator.java +++ b/core/starter/src/main/java/org/apache/syncope/core/starter/actuate/DomainsHealthIndicator.java @@ -18,7 +18,8 @@ */ package org.apache.syncope.core.starter.actuate; -import java.util.concurrent.atomic.AtomicReference; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.syncope.core.persistence.api.DomainHolder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,15 +41,15 @@ public DomainsHealthIndicator(final DomainHolder domainHolder) { public Health health() { Health.Builder builder = new Health.Builder(); - AtomicReference anyDown = new AtomicReference<>(Boolean.FALSE); + Mutable anyDown = new MutableObject<>(false); domainHolder.getHealthInfo().forEach((domain, status) -> { builder.withDetail(domain, status ? Status.UP : Status.DOWN); if (!status) { - anyDown.set(true); + anyDown.setValue(true); } }); - builder.status(anyDown.get() ? Status.DOWN : Status.UP); + builder.status(anyDown.getValue() ? Status.DOWN : Status.UP); return builder.build(); } diff --git a/core/starter/src/main/java/org/apache/syncope/core/starter/actuate/ExternalResourcesHealthIndicator.java b/core/starter/src/main/java/org/apache/syncope/core/starter/actuate/ExternalResourcesHealthIndicator.java index 17c58feb96c..91b8eea099b 100644 --- a/core/starter/src/main/java/org/apache/syncope/core/starter/actuate/ExternalResourcesHealthIndicator.java +++ b/core/starter/src/main/java/org/apache/syncope/core/starter/actuate/ExternalResourcesHealthIndicator.java @@ -18,8 +18,9 @@ */ package org.apache.syncope.core.starter.actuate; -import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Stream; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.syncope.common.keymaster.client.api.DomainOps; import org.apache.syncope.common.keymaster.client.api.model.Domain; import org.apache.syncope.common.lib.SyncopeConstants; @@ -61,7 +62,7 @@ public ExternalResourcesHealthIndicator( public Health health() { Health.Builder builder = new Health.Builder(); - AtomicReference anyDown = new AtomicReference<>(Boolean.FALSE); + Mutable anyDown = new MutableObject<>(false); Stream.concat(Stream.of(SyncopeConstants.MASTER_DOMAIN), domainOps.list().stream().map(Domain::getKey)). forEach(domain -> AuthContextUtils.runAsAdmin(domain, () -> { @@ -83,12 +84,12 @@ public Health health() { builder.withDetail(domain + "#" + resource.getKey(), status); if (status != Status.UP) { - anyDown.set(true); + anyDown.setValue(true); } }); })); - builder.status(anyDown.get() ? Status.DOWN : Status.UP); + builder.status(anyDown.getValue() ? Status.DOWN : Status.UP); return builder.build(); } diff --git a/ext/openfga/client-openfga/src/main/java/org/apache/syncope/ext/openfga/client/OpenFGAHealthIndicator.java b/ext/openfga/client-openfga/src/main/java/org/apache/syncope/ext/openfga/client/OpenFGAHealthIndicator.java index cb768cd4e1d..2f2374897d6 100644 --- a/ext/openfga/client-openfga/src/main/java/org/apache/syncope/ext/openfga/client/OpenFGAHealthIndicator.java +++ b/ext/openfga/client-openfga/src/main/java/org/apache/syncope/ext/openfga/client/OpenFGAHealthIndicator.java @@ -19,7 +19,8 @@ package org.apache.syncope.ext.openfga.client; import java.util.Map; -import java.util.concurrent.atomic.AtomicReference; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.syncope.core.persistence.api.DomainHolder; import org.apache.syncope.ext.openfga.client.model.ListStoresResponse; import org.springframework.boot.actuate.health.Health; @@ -45,7 +46,7 @@ public Health health() { Health.Builder builder = new Health.Builder(); builder.withDetail("baseUri", clientFactory.getBaseUri()); - AtomicReference anyDown = new AtomicReference<>(Boolean.FALSE); + Mutable anyDown = new MutableObject<>(Boolean.FALSE); domainHolder.getDomains().keySet().forEach(domain -> { try { @@ -57,15 +58,15 @@ public Health health() { "status", Status.UP.getCode())); } else { builder.withDetail(domain, Status.DOWN); - anyDown.set(true); + anyDown.setValue(true); } } catch (Exception e) { builder.withDetail(domain, Status.DOWN).withException(e); - anyDown.set(true); + anyDown.setValue(true); } }); - builder.status(anyDown.get() ? Status.DOWN : Status.UP); + builder.status(anyDown.getValue() ? Status.DOWN : Status.UP); return builder.build(); } diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java index 3e0c89b1fd9..edfbfaec5a8 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java @@ -52,9 +52,10 @@ import java.util.Properties; import java.util.UUID; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; import javax.sql.DataSource; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.commons.lang3.tuple.Pair; import org.apache.cxf.jaxrs.client.WebClient; import org.apache.syncope.client.lib.SyncopeAnonymousClient; @@ -901,17 +902,17 @@ protected static T queryForObject( final Class requiredType, final Object... args) { - AtomicReference object = new AtomicReference<>(); + Mutable object = new MutableObject<>(); await().atMost(maxWaitSeconds, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> { try { - object.set(jdbcTemplate.queryForObject(sql, requiredType, args)); - return object.get() != null; + object.setValue(jdbcTemplate.queryForObject(sql, requiredType, args)); + return object.getValue() != null; } catch (Exception e) { return false; } }); - return object.get(); + return object.getValue(); } protected static List queryForList( @@ -921,17 +922,17 @@ protected static List queryForList( final Class requiredType, final Object... args) { - AtomicReference> object = new AtomicReference<>(); + Mutable> object = new MutableObject<>(); await().atMost(maxWaitSeconds, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> { try { - object.set(jdbcTemplate.queryForList(sql, requiredType, args)); - return object.get() != null; + object.setValue(jdbcTemplate.queryForList(sql, requiredType, args)); + return object.getValue() != null; } catch (Exception e) { return false; } }); - return object.get(); + return object.getValue(); } protected static OIDCRPClientAppTO buildOIDCRP() { diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractNotificationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractNotificationTaskITCase.java index b12d2c92f21..f9fd733b8db 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractNotificationTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractNotificationTaskITCase.java @@ -29,7 +29,8 @@ import java.io.InputStream; import java.util.Properties; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.junit.jupiter.api.BeforeAll; public abstract class AbstractNotificationTaskITCase extends AbstractTaskITCase { @@ -79,11 +80,11 @@ protected static void verifyMail( final String mailAddress, final int maxWaitSeconds) throws Exception { - AtomicReference read = new AtomicReference<>(false); + Mutable read = new MutableObject<>(false); await().atMost(maxWaitSeconds, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> { try { - read.set(pop3(sender, subject, mailAddress)); - return read.get(); + read.setValue(pop3(sender, subject, mailAddress)); + return read.getValue(); } catch (Exception e) { return false; } diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java index 3569062c52a..18d28bc857e 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java @@ -29,7 +29,8 @@ import java.util.Set; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.syncope.client.lib.SyncopeClient; import org.apache.syncope.common.lib.SyncopeConstants; import org.apache.syncope.common.lib.request.ResourceDR; @@ -81,22 +82,22 @@ protected static ExecTO execTask( final int maxWaitSeconds, final boolean dryRun) { - AtomicReference taskTO = new AtomicReference<>(taskService.read(type, taskKey, true)); - int preSyncSize = taskTO.get().getExecutions().size(); + Mutable taskTO = new MutableObject<>(taskService.read(type, taskKey, true)); + int preSyncSize = taskTO.getValue().getExecutions().size(); ExecTO execution = taskService.execute(new ExecSpecs.Builder().key(taskKey).dryRun(dryRun).build()); Optional.ofNullable(initialStatus).ifPresent(status -> assertEquals(status, execution.getStatus())); assertNotNull(execution.getExecutor()); await().atMost(maxWaitSeconds, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> { try { - taskTO.set(taskService.read(type, taskKey, true)); - return preSyncSize < taskTO.get().getExecutions().size(); + taskTO.setValue(taskService.read(type, taskKey, true)); + return preSyncSize < taskTO.getValue().getExecutions().size(); } catch (Exception e) { return false; } }); - return taskTO.get().getExecutions().stream().max(Comparator.comparing(ExecTO::getStart)).orElseThrow(); + return taskTO.getValue().getExecutions().stream().max(Comparator.comparing(ExecTO::getStart)).orElseThrow(); } public static ExecTO execSchedTask( @@ -154,20 +155,20 @@ protected void execProvisioningTasks( } protected NotificationTaskTO findNotificationTask(final String notification, final int maxWaitSeconds) { - AtomicReference notificationTask = new AtomicReference<>(); + Mutable notificationTask = new MutableObject<>(); await().atMost(maxWaitSeconds, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> { try { PagedResult tasks = TASK_SERVICE.search( new TaskQuery.Builder(TaskType.NOTIFICATION).notification(notification).build()); if (!tasks.getResult().isEmpty()) { - notificationTask.set(tasks.getResult().getFirst()); + notificationTask.setValue(tasks.getResult().getFirst()); } } catch (Exception e) { // ignore } - return notificationTask.get() != null; + return notificationTask.getValue() != null; }); - return notificationTask.get(); + return notificationTask.getValue(); } } diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/BatchITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/BatchITCase.java index 7e732de59b8..b7527c48c19 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/BatchITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/BatchITCase.java @@ -38,7 +38,8 @@ import java.util.List; import java.util.UUID; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.cxf.jaxrs.client.Client; import org.apache.cxf.jaxrs.client.WebClient; import org.apache.syncope.client.lib.batch.BatchRequest; @@ -146,7 +147,7 @@ private static void check(final List resItems) throws IOExcep assertNotNull(resItems.getFirst().getHeaders().get(RESTHeaders.DOMAIN)); assertNotNull(resItems.getFirst().getHeaders().get(RESTHeaders.RESOURCE_KEY)); assertEquals(RESTHeaders.APPLICATION_YAML, resItems.getFirst(). - getHeaders().get(HttpHeaders.CONTENT_TYPE).getFirst()); + getHeaders().get(HttpHeaders.CONTENT_TYPE).getFirst()); ProvisioningResult user = YAML_MAPPER.readValue( resItems.get(0).getContent(), new TypeReference<>() { }); @@ -229,16 +230,16 @@ public void webClientAsync() throws IOException { header(HttpHeaders.AUTHORIZATION, "Bearer " + ADMIN_CLIENT.getJWT()). type(RESTHeaders.multipartMixedWith(boundary.substring(2))); - AtomicReference holder = new AtomicReference<>(); + Mutable holder = new MutableObject<>(); await().atMost(MAX_WAIT_SECONDS, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> { try { - holder.set(client.get()); - return holder.get().getStatus() != Response.Status.ACCEPTED.getStatusCode(); + holder.setValue(client.get()); + return holder.getValue().getStatus() != Response.Status.ACCEPTED.getStatusCode(); } catch (Exception e) { return false; } }); - response = holder.get(); + response = holder.getValue(); assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); assertTrue(response.getMediaType().toString(). startsWith(RESTHeaders.multipartMixedWith(boundary.substring(2)))); diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java index 9a2c6b7c9b7..29390422b35 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java @@ -39,8 +39,9 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; import org.apache.commons.lang3.SerializationUtils; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.syncope.client.lib.SyncopeClient; import org.apache.syncope.common.lib.AnyOperations; import org.apache.syncope.common.lib.Attr; @@ -957,16 +958,16 @@ public void provisionMembers() throws InterruptedException { ExecTO exec = GROUP_SERVICE.provisionMembers(groupTO.getKey(), ProvisionAction.PROVISION); assertNotNull(exec.getRefKey()); - AtomicReference> execs = new AtomicReference<>(); + Mutable> execs = new MutableObject<>(); await().atMost(MAX_WAIT_SECONDS, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> { try { - execs.set(TASK_SERVICE.read(TaskType.SCHEDULED, exec.getRefKey(), true).getExecutions()); - return !execs.get().isEmpty(); + execs.setValue(TASK_SERVICE.read(TaskType.SCHEDULED, exec.getRefKey(), true).getExecutions()); + return !execs.getValue().isEmpty(); } catch (Exception e) { return false; } }); - assertEquals(TaskJob.Status.SUCCESS.name(), execs.get().getFirst().getStatus()); + assertEquals(TaskJob.Status.SUCCESS.name(), execs.getValue().getFirst().getStatus()); // 6. verify that the user above is now fond on LDAP ConnObject userOnLdap = diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/KeymasterITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/KeymasterITCase.java index cd9e1d1b48d..b51459e2c3d 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/KeymasterITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/KeymasterITCase.java @@ -37,8 +37,9 @@ import java.util.Map; import java.util.UUID; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.syncope.client.lib.SyncopeClientFactoryBean; import org.apache.syncope.common.keymaster.client.api.KeymasterException; import org.apache.syncope.common.keymaster.client.api.model.Domain; @@ -154,16 +155,16 @@ private List findNetworkServices( final Function, Boolean> check, final int maxWaitSeconds) { - AtomicReference> holder = new AtomicReference<>(); + Mutable> holder = new MutableObject<>(); await().atMost(maxWaitSeconds, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> { try { - holder.set(serviceOps.list(type)); - return !check.apply(holder.get()); + holder.setValue(serviceOps.list(type)); + return !check.apply(holder.getValue()); } catch (Exception e) { return false; } }); - return holder.get(); + return holder.getValue(); } @Test diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LiveSyncITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LiveSyncITCase.java index 455c0fa40e6..7c4b766dfa9 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LiveSyncITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LiveSyncITCase.java @@ -34,7 +34,8 @@ import java.util.Objects; import java.util.UUID; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.KafkaConsumer; import org.apache.kafka.clients.producer.KafkaProducer; @@ -138,7 +139,7 @@ private static KafkaConsumer createConsumer() { } private static boolean found(final SyncDeltaType syncDeltaType, final String username) { - AtomicBoolean found = new AtomicBoolean(false); + Mutable found = new MutableObject<>(false); try (KafkaConsumer consumer = createConsumer()) { consumer.poll(Duration.ofSeconds(10)).forEach(record -> { if (ACCOUNT_TOPIC.equals(record.topic())) { @@ -156,11 +157,11 @@ private static boolean found(final SyncDeltaType syncDeltaType, final String use fail(e.getMessage(), e); } - found.set(syncDeltaType == sdt && username.equals(uid)); + found.setValue(syncDeltaType == sdt && username.equals(uid)); } }); } - return found.get(); + return found.getValue(); } @Test diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java index ea147a3437d..e9149da0fef 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java @@ -49,10 +49,11 @@ import java.util.UUID; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.SerializationUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.commons.lang3.tuple.Triple; import org.apache.syncope.client.lib.SyncopeClient; import org.apache.syncope.client.lib.batch.BatchRequest; @@ -490,20 +491,20 @@ public void reconcileFromLDAP() { execSchedTask(TASK_SERVICE, TaskType.PULL, LDAP_PULL_TASK, MAX_WAIT_SECONDS, false); // 4. verify that LDAP group membership is pulled as Syncope membership - AtomicReference numMembers = new AtomicReference<>(); + Mutable numMembers = new MutableObject<>(); await().atMost(MAX_WAIT_SECONDS, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> { try { PagedResult members = USER_SERVICE.search( new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM). fiql(SyncopeClient.getUserSearchConditionBuilder().inGroups(groupTO.getKey()).query()). build()); - numMembers.set(members.getResult().size()); + numMembers.setValue(members.getResult().size()); return !members.getResult().isEmpty(); } catch (Exception e) { return false; } }); - assertEquals(1, numMembers.get()); + assertEquals(1, numMembers.getValue()); // SYNCOPE-1343, verify that the title attribute has been reset matchingUsers = USER_SERVICE.search( diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java index f33fec80b07..3c841e798db 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReportITCase.java @@ -33,7 +33,8 @@ import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.to.ExecTO; import org.apache.syncope.common.lib.to.ReportTO; @@ -53,21 +54,22 @@ public class ReportITCase extends AbstractITCase { protected static String execReport(final String reportKey) { - AtomicReference reportTO = new AtomicReference<>(REPORT_SERVICE.read(reportKey)); - int preExecSize = reportTO.get().getExecutions().size(); + Mutable reportTO = new MutableObject<>(REPORT_SERVICE.read(reportKey)); + int preExecSize = reportTO.getValue().getExecutions().size(); ExecTO execution = REPORT_SERVICE.execute(new ExecSpecs.Builder().key(reportKey).build()); assertNotNull(execution.getExecutor()); await().atMost(MAX_WAIT_SECONDS, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> { try { - reportTO.set(REPORT_SERVICE.read(reportKey)); - return preExecSize < reportTO.get().getExecutions().size(); + reportTO.setValue(REPORT_SERVICE.read(reportKey)); + return preExecSize < reportTO.getValue().getExecutions().size(); } catch (Exception e) { return false; } }); - ExecTO exec = reportTO.get().getExecutions().stream().max(Comparator.comparing(ExecTO::getStart)).orElseThrow(); + ExecTO exec = reportTO.getValue().getExecutions().stream(). + max(Comparator.comparing(ExecTO::getStart)).orElseThrow(); assertEquals(ReportJob.Status.SUCCESS.name(), exec.getStatus()); return exec.getKey(); } diff --git a/sra/src/main/java/org/apache/syncope/sra/RouteProvider.java b/sra/src/main/java/org/apache/syncope/sra/RouteProvider.java index 4745d108c79..1a48dc1fd4c 100644 --- a/sra/src/main/java/org/apache/syncope/sra/RouteProvider.java +++ b/sra/src/main/java/org/apache/syncope/sra/RouteProvider.java @@ -22,11 +22,12 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; -import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.stream.Stream; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.syncope.client.lib.AnonymousAuthenticationHandler; import org.apache.syncope.client.lib.SyncopeClient; import org.apache.syncope.client.lib.SyncopeClientFactoryBean; @@ -273,15 +274,15 @@ protected GatewayFilter toFilter(final SRARouteTO route, final SRARouteFilter gw break; case RETRY: - AtomicInteger retries = new AtomicInteger(); + Mutable retries = new MutableObject<>(); try { - retries.set(Integer.valueOf(gwfilter.getArgs().trim())); + retries.setValue(Integer.valueOf(gwfilter.getArgs().trim())); } catch (NumberFormatException e) { LOG.error("Unexpected argument value: {}", gwfilter.getArgs().trim(), e); - retries.set(0); + retries.setValue(0); } filter = ctx.getBean(RetryGatewayFilterFactory.class). - apply(c -> c.setRetries(retries.get())); + apply(c -> c.setRetries(retries.getValue())); break; case SAVE_SESSION: @@ -319,15 +320,15 @@ protected GatewayFilter toFilter(final SRARouteTO route, final SRARouteFilter gw break; case STRIP_PREFIX: - AtomicInteger parts = new AtomicInteger(); + Mutable parts = new MutableObject<>(); try { - parts.set(Integer.valueOf(gwfilter.getArgs().trim())); + parts.setValue(Integer.valueOf(gwfilter.getArgs().trim())); } catch (NumberFormatException e) { LOG.error("Unexpected argument value: {}", gwfilter.getArgs().trim(), e); - parts.set(0); + parts.setValue(0); } filter = ctx.getBean(StripPrefixGatewayFilterFactory.class). - apply(c -> c.setParts(parts.get())); + apply(c -> c.setParts(parts.getValue())); break; case REQUEST_HEADER_TO_REQUEST_URI: @@ -337,7 +338,7 @@ protected GatewayFilter toFilter(final SRARouteTO route, final SRARouteFilter gw case SET_REQUEST_SIZE: filter = ctx.getBean(RequestSizeGatewayFilterFactory.class). - apply(c -> c.setMaxSize(DataSize.ofBytes(Long.valueOf(gwfilter.getArgs().trim())))); + apply(c -> c.setMaxSize(DataSize.ofBytes(Long.parseLong(gwfilter.getArgs().trim())))); break; case SET_REQUEST_HOST: @@ -476,16 +477,16 @@ protected AsyncPredicate toPredicate(final SRARoutePredicate case WEIGHT: String[] weigthArgs = gwpredicate.getArgs().split(","); - AtomicInteger weight = new AtomicInteger(); + Mutable weight = new MutableObject(); try { - weight.set(Integer.valueOf(weigthArgs[1].trim())); + weight.setValue(Integer.valueOf(weigthArgs[1].trim())); } catch (NumberFormatException e) { LOG.error("Unexpected argument value: {}", weigthArgs[1].trim(), e); - weight.set(0); + weight.setValue(0); } predicate = ctx.getBean(WeightRoutePredicateFactory.class). applyAsync(c -> c.setGroup(weigthArgs[0].trim()). - setWeight(weight.get())); + setWeight(weight.getValue())); break; case CUSTOM: diff --git a/sra/src/test/java/org/apache/syncope/sra/ZookeeperTestingServer.java b/sra/src/test/java/org/apache/syncope/sra/ZookeeperTestingServer.java index fe4c29910e8..0549ebc3ce5 100644 --- a/sra/src/test/java/org/apache/syncope/sra/ZookeeperTestingServer.java +++ b/sra/src/test/java/org/apache/syncope/sra/ZookeeperTestingServer.java @@ -24,7 +24,6 @@ import java.util.HashMap; import java.util.Map; import java.util.Properties; -import java.util.concurrent.atomic.AtomicReference; import javax.security.auth.login.AppConfigurationEntry; import javax.security.auth.login.Configuration; import org.apache.commons.lang3.StringUtils; @@ -34,33 +33,35 @@ import org.apache.zookeeper.server.auth.SASLAuthenticationProvider; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; +import wiremock.org.apache.commons.lang3.mutable.Mutable; +import wiremock.org.apache.commons.lang3.mutable.MutableObject; public class ZookeeperTestingServer implements ApplicationContextInitializer { @Override public void initialize(final ConfigurableApplicationContext ctx) { - AtomicReference port = new AtomicReference<>(); - AtomicReference username = new AtomicReference<>(); - AtomicReference password = new AtomicReference<>(); + Mutable port = new MutableObject<>(); + Mutable username = new MutableObject<>(); + Mutable password = new MutableObject<>(); try (InputStream propStream = getClass().getResourceAsStream("/test.properties")) { Properties props = new Properties(); props.load(propStream); - port.set(Integer.valueOf(StringUtils.substringAfter(props.getProperty("keymaster.address"), ":"))); - username.set(props.getProperty("keymaster.username")); - password.set(props.getProperty("keymaster.password")); + port.setValue(Integer.valueOf(StringUtils.substringAfter(props.getProperty("keymaster.address"), ":"))); + username.setValue(props.getProperty("keymaster.username")); + password.setValue(props.getProperty("keymaster.password")); } catch (Exception e) { throw new IllegalStateException("Could not load /test.properties", e); } - if (AbstractTest.available(port.get())) { + if (AbstractTest.available(port.getValue())) { Configuration.setConfiguration(new Configuration() { private final AppConfigurationEntry[] entries = { new AppConfigurationEntry( DigestLoginModule.class.getName(), AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, - Map.of("user_" + username.get(), password.get())) + Map.of("user_" + username.getValue(), password.getValue())) }; @Override @@ -71,7 +72,7 @@ public AppConfigurationEntry[] getAppConfigurationEntry(final String name) { Map customProperties = new HashMap<>(); customProperties.put("authProvider.1", SASLAuthenticationProvider.class.getName()); - InstanceSpec spec = new InstanceSpec(null, port.get(), -1, -1, true, 1, -1, -1, customProperties); + InstanceSpec spec = new InstanceSpec(null, port.getValue(), -1, -1, true, 1, -1, -1, customProperties); try { new TestingServer(spec, true); diff --git a/wa/starter/src/test/java/org/apache/syncope/wa/starter/ZookeeperTestingServer.java b/wa/starter/src/test/java/org/apache/syncope/wa/starter/ZookeeperTestingServer.java index 273a6a55b33..03e5aae2026 100644 --- a/wa/starter/src/test/java/org/apache/syncope/wa/starter/ZookeeperTestingServer.java +++ b/wa/starter/src/test/java/org/apache/syncope/wa/starter/ZookeeperTestingServer.java @@ -24,10 +24,11 @@ import java.util.HashMap; import java.util.Map; import java.util.Properties; -import java.util.concurrent.atomic.AtomicReference; import javax.security.auth.login.AppConfigurationEntry; import javax.security.auth.login.Configuration; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.curator.test.InstanceSpec; import org.apache.curator.test.TestingServer; import org.apache.zookeeper.server.auth.DigestLoginModule; @@ -39,16 +40,16 @@ public class ZookeeperTestingServer implements ApplicationContextInitializer port = new AtomicReference<>(); - AtomicReference username = new AtomicReference<>(); - AtomicReference password = new AtomicReference<>(); + Mutable port = new MutableObject<>(); + Mutable username = new MutableObject<>(); + Mutable password = new MutableObject<>(); try (InputStream propStream = getClass().getResourceAsStream("/test.properties")) { Properties props = new Properties(); props.load(propStream); - port.set(Integer.valueOf(StringUtils.substringAfter(props.getProperty("keymaster.address"), ":"))); - username.set(props.getProperty("keymaster.username")); - password.set(props.getProperty("keymaster.password")); + port.setValue(Integer.valueOf(StringUtils.substringAfter(props.getProperty("keymaster.address"), ":"))); + username.setValue(props.getProperty("keymaster.username")); + password.setValue(props.getProperty("keymaster.password")); } catch (Exception e) { throw new IllegalStateException("Could not load /test.properties", e); } @@ -59,7 +60,7 @@ public void initialize(final ConfigurableApplicationContext ctx) { new AppConfigurationEntry( DigestLoginModule.class.getName(), AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, - Map.of("user_" + username.get(), password.get())) + Map.of("user_" + username.getValue(), password.getValue())) }; @Override @@ -70,7 +71,7 @@ public AppConfigurationEntry[] getAppConfigurationEntry(final String name) { Map customProperties = new HashMap<>(); customProperties.put("authProvider.1", SASLAuthenticationProvider.class.getName()); - InstanceSpec spec = new InstanceSpec(null, port.get(), -1, -1, true, 1, -1, -1, customProperties); + InstanceSpec spec = new InstanceSpec(null, port.getValue(), -1, -1, true, 1, -1, -1, customProperties); try { new TestingServer(spec, true); From d8ffba55a837d1f415ed51e0b97bf14d26ed3f41 Mon Sep 17 00:00:00 2001 From: Matteo Tatoni Date: Thu, 24 Apr 2025 15:52:04 +0200 Subject: [PATCH 022/579] [SYNCOPE-1873] - Add LocalDateTime support to DateOps (#1059) --- .../syncope/client/ui/commons/DateOps.java | 38 +++++++++++++++++-- .../client/console/panels/BeanPanel.java | 4 ++ .../data/table/DatePropertyColumn.java | 3 ++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/DateOps.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/DateOps.java index 17216b409b7..4e0d591cb25 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/DateOps.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/DateOps.java @@ -19,6 +19,7 @@ package org.apache.syncope.client.ui.commons; import java.io.Serializable; +import java.time.LocalDateTime; import java.time.OffsetDateTime; import java.time.ZoneId; import java.time.ZoneOffset; @@ -52,6 +53,10 @@ public String format(final OffsetDateTime date) { public String format(final ZonedDateTime date) { return Optional.ofNullable(date).map(v -> fdf.format(convert(date))).orElse(StringUtils.EMPTY); } + + public String format(final LocalDateTime date) { + return Optional.ofNullable(date).map(v -> fdf.format(convert(v))).orElse(StringUtils.EMPTY); + } } public static final class WrappedDateModel implements IModel, Serializable { @@ -70,6 +75,14 @@ public static WrappedDateModel ofZoned(final IModel zoned) { return instance; } + public static WrappedDateModel ofLocal(final IModel local) { + WrappedDateModel instance = new WrappedDateModel(); + instance.local = local; + return instance; + } + + private IModel local; + private IModel offset; private IModel zoned; @@ -80,15 +93,24 @@ private WrappedDateModel() { @Override public Date getObject() { - return offset == null ? convert(zoned.getObject()) : convert(offset.getObject()); + if (offset != null) { + return convert(offset.getObject()); + } else if (zoned != null) { + return convert(zoned.getObject()); + } else if (local != null) { + return convert(local.getObject()); + } + return null; } @Override public void setObject(final Date object) { - if (offset == null) { - zoned.setObject(toZonedDateTime(object)); - } else { + if (offset != null) { offset.setObject(toOffsetDateTime(object)); + } else if (zoned != null) { + zoned.setObject(toZonedDateTime(object)); + } else if (local != null) { + local.setObject(toLocalDateTime(object)); } } } @@ -105,6 +127,10 @@ public static Date convert(final ZonedDateTime date) { return Optional.ofNullable(date).map(v -> new Date(v.toInstant().toEpochMilli())).orElse(null); } + public static Date convert(final LocalDateTime date) { + return Optional.ofNullable(date).map(v -> Date.from(v.atZone(DEFAULT_ZONE).toInstant())).orElse(null); + } + public static OffsetDateTime toOffsetDateTime(final Date date) { return Optional.ofNullable(date).map(v -> v.toInstant().atOffset(DEFAULT_OFFSET)).orElse(null); } @@ -113,6 +139,10 @@ public static ZonedDateTime toZonedDateTime(final Date date) { return Optional.ofNullable(date).map(v -> ZonedDateTime.ofInstant(v.toInstant(), DEFAULT_ZONE)).orElse(null); } + public static LocalDateTime toLocalDateTime(final Date date) { + return Optional.ofNullable(date).map(v -> LocalDateTime.ofInstant(v.toInstant(), DEFAULT_ZONE)).orElse(null); + } + private DateOps() { // private constructor for static utility class } diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/BeanPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/BeanPanel.java index da2d1ea029f..7fe73bef1b4 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/BeanPanel.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/BeanPanel.java @@ -26,6 +26,7 @@ import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.time.Duration; +import java.time.LocalDateTime; import java.time.OffsetDateTime; import java.time.ZonedDateTime; import java.util.ArrayList; @@ -306,6 +307,9 @@ private Triple> buildSinglePanel( } else if (ZonedDateTime.class.equals(type)) { panel = new AjaxDateTimeFieldPanel(id, fieldName, DateOps.WrappedDateModel.ofZoned(model), DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT); + } else if (LocalDateTime.class.equals(type)) { + panel = new AjaxDateTimeFieldPanel(id, fieldName, DateOps.WrappedDateModel.ofLocal(model), + DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT); } else if (type.isEnum()) { panel = new AjaxDropDownChoicePanel(id, fieldName, model). setChoices(List.of(type.getEnumConstants())); diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/DatePropertyColumn.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/DatePropertyColumn.java index 8dd39b0b3a6..de3c99c11a6 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/DatePropertyColumn.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/DatePropertyColumn.java @@ -18,6 +18,7 @@ */ package org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table; +import java.time.LocalDateTime; import java.time.OffsetDateTime; import java.time.ZonedDateTime; import java.util.Date; @@ -52,6 +53,8 @@ public void populateItem(final Item> item, final String compon convertedDate = SyncopeConsoleSession.get().getDateFormat().format(offsetDateTime); } else if (date.getObject() instanceof final ZonedDateTime zonedDateTime) { convertedDate = SyncopeConsoleSession.get().getDateFormat().format(zonedDateTime); + } else if (date.getObject() instanceof final LocalDateTime localDateTime) { + convertedDate = SyncopeConsoleSession.get().getDateFormat().format(localDateTime); } else if (date.getObject() instanceof final Date date1) { convertedDate = SyncopeConsoleSession.get().getDateFormat().format(date1); } From c6746c800b2af3db655ddcabbe2d162b84778497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Thu, 24 Apr 2025 17:26:37 +0200 Subject: [PATCH 023/579] Upgrading Spring Boot --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e5d0fad6a43..025dfde0ecf 100644 --- a/pom.xml +++ b/pom.xml @@ -415,7 +415,7 @@ under the License. 1.80 10.2 - 3.4.4 + 3.4.5 4.2.1 4.1.0 From d00160f9da2420373d95733819db3933fa924af9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Sat, 26 Apr 2025 07:50:20 +0200 Subject: [PATCH 024/579] Upgrading Wicket --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 025dfde0ecf..945c309dbc8 100644 --- a/pom.xml +++ b/pom.xml @@ -461,7 +461,7 @@ under the License. 2.0.7 4.4.3 - 10.4.0 + 10.5.0 10.4.0 10.0.0-M1 7.0.9 From 0ce50d6b65a0ed3d3ad399ed9217c0a064316601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Mon, 28 Apr 2025 08:26:31 +0200 Subject: [PATCH 025/579] Upgrading gmavenplus-plugin --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 945c309dbc8..2b0df257a2c 100644 --- a/pom.xml +++ b/pom.xml @@ -1880,7 +1880,7 @@ under the License. org.codehaus.gmavenplus gmavenplus-plugin - 4.1.1 + 4.2.0 org.apache.groovy From 8e376bb00b5a51d9d08c3079c8962e5daf6d2605 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Apr 2025 00:16:54 +0000 Subject: [PATCH 026/579] Bump wicket-bootstrap.version from 7.0.9 to 7.0.10 Bumps `wicket-bootstrap.version` from 7.0.9 to 7.0.10. Updates `de.agilecoders.wicket:wicket-bootstrap-core` from 7.0.9 to 7.0.10 - [Commits](https://github.com/l0rdn1kk0n/wicket-bootstrap/compare/bootstrap-parent-7.0.9...bootstrap-parent-7.0.10) Updates `de.agilecoders.wicket:wicket-bootstrap-extensions` from 7.0.9 to 7.0.10 - [Commits](https://github.com/l0rdn1kk0n/wicket-bootstrap/compare/bootstrap-parent-7.0.9...bootstrap-parent-7.0.10) --- updated-dependencies: - dependency-name: de.agilecoders.wicket:wicket-bootstrap-core dependency-version: 7.0.10 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: de.agilecoders.wicket:wicket-bootstrap-extensions dependency-version: 7.0.10 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2b0df257a2c..9a56930925b 100644 --- a/pom.xml +++ b/pom.xml @@ -464,7 +464,7 @@ under the License. 10.5.0 10.4.0 10.0.0-M1 - 7.0.9 + 7.0.10 4.0.4 4.0.0 From eb5a3c4e81e3f24293187cb0be98790cda9c4a0f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Apr 2025 00:25:12 +0000 Subject: [PATCH 027/579] Bump org.openapitools:openapi-generator-maven-plugin Bumps org.openapitools:openapi-generator-maven-plugin from 7.12.0 to 7.13.0. --- updated-dependencies: - dependency-name: org.openapitools:openapi-generator-maven-plugin dependency-version: 7.13.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9a56930925b..53d588c8ebb 100644 --- a/pom.xml +++ b/pom.xml @@ -1636,7 +1636,7 @@ under the License. org.openapitools openapi-generator-maven-plugin - 7.12.0 + 7.13.0 From 600d5ed7d607645faf9f6e5c58e4b78c65ba1a26 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Apr 2025 00:41:16 +0000 Subject: [PATCH 028/579] Bump co.elastic.clients:elasticsearch-java from 8.17.4 to 9.0.0 Bumps [co.elastic.clients:elasticsearch-java](https://github.com/elastic/elasticsearch-java) from 8.17.4 to 9.0.0. - [Release notes](https://github.com/elastic/elasticsearch-java/releases) - [Changelog](https://github.com/elastic/elasticsearch-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/elastic/elasticsearch-java/compare/v8.17.4...v9.0.0) --- updated-dependencies: - dependency-name: co.elastic.clients:elasticsearch-java dependency-version: 9.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .../client/ElasticsearchClientContext.java | 19 +++++++++-- .../ElasticsearchClientFactoryBean.java | 32 ++++++++----------- .../client/ElasticsearchIndexManager.java | 7 ++-- .../dao/ElasticsearchRealmSearchDAO.java | 4 ++- pom.xml | 2 +- 5 files changed, 38 insertions(+), 26 deletions(-) diff --git a/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchClientContext.java b/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchClientContext.java index 77664ccb032..b26c9043007 100644 --- a/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchClientContext.java +++ b/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchClientContext.java @@ -19,11 +19,15 @@ package org.apache.syncope.ext.elasticsearch.client; import co.elastic.clients.elasticsearch.ElasticsearchClient; -import org.apache.http.HttpHost; +import java.net.URISyntaxException; +import java.util.Objects; +import org.apache.hc.core5.http.HttpHost; import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.identityconnectors.common.CollectionUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.boot.actuate.health.HealthContributor; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -35,11 +39,20 @@ @Configuration(proxyBeanMethods = false) public class ElasticsearchClientContext { + protected static final Logger LOG = LoggerFactory.getLogger(ElasticsearchClientContext.class); + @ConditionalOnMissingBean @Bean public ElasticsearchClientFactoryBean elasticsearchClientFactoryBean(final ElasticsearchProperties props) { - return new ElasticsearchClientFactoryBean( - CollectionUtil.nullAsEmpty(props.getHosts()).stream().map(HttpHost::create).toList()); + return new ElasticsearchClientFactoryBean(CollectionUtil.nullAsEmpty(props.getHosts()).stream(). + map(host -> { + try { + return HttpHost.create(host); + } catch (URISyntaxException e) { + LOG.error("Invalid host: {}", host, e); + return null; + } + }).filter(Objects::nonNull).toList()); } @ConditionalOnMissingBean diff --git a/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchClientFactoryBean.java b/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchClientFactoryBean.java index e8d4ba36ff3..9377b0cf9ed 100644 --- a/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchClientFactoryBean.java +++ b/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchClientFactoryBean.java @@ -20,22 +20,18 @@ import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.json.jackson.JacksonJsonpMapper; -import co.elastic.clients.transport.rest_client.RestClientTransport; +import co.elastic.clients.transport.rest5_client.Rest5ClientTransport; +import co.elastic.clients.transport.rest5_client.low_level.Rest5Client; +import co.elastic.clients.transport.rest5_client.low_level.Rest5ClientBuilder; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.json.JsonMapper; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.List; -import org.apache.http.Header; -import org.apache.http.HttpHeaders; -import org.apache.http.HttpHost; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.CredentialsProvider; -import org.apache.http.impl.client.BasicCredentialsProvider; -import org.apache.http.message.BasicHeader; -import org.elasticsearch.client.RestClient; -import org.elasticsearch.client.RestClientBuilder; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.HttpHeaders; +import org.apache.hc.core5.http.HttpHost; +import org.apache.hc.core5.http.message.BasicHeader; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; @@ -56,7 +52,7 @@ public class ElasticsearchClientFactoryBean implements FactoryBean b.setDefaultCredentialsProvider(credentialsProvider)); + String encodedAuth = Base64.getEncoder(). + encodeToString((username + ":" + password).getBytes(StandardCharsets.UTF_8)); + builder.setDefaultHeaders( + new Header[] { new BasicHeader(HttpHeaders.AUTHORIZATION, "Bearer " + encodedAuth) }); } else if (serviceToken != null) { builder.setDefaultHeaders( new Header[] { new BasicHeader(HttpHeaders.AUTHORIZATION, "Bearer " + serviceToken) }); @@ -117,7 +113,7 @@ public ElasticsearchClient getObject() { } restClient = builder.build(); - client = new ElasticsearchClient(new RestClientTransport( + client = new ElasticsearchClient(new Rest5ClientTransport( restClient, new JacksonJsonpMapper(JsonMapper.builder(). findAndAddModules().disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS).build()))); diff --git a/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchIndexManager.java b/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchIndexManager.java index 6c6331c8295..9df9e33c932 100644 --- a/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchIndexManager.java +++ b/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchIndexManager.java @@ -39,6 +39,7 @@ import co.elastic.clients.elasticsearch.indices.ExistsRequest; import co.elastic.clients.elasticsearch.indices.IndexSettings; import co.elastic.clients.elasticsearch.indices.IndexSettingsAnalysis; +import co.elastic.clients.util.NamedValue; import java.io.IOException; import java.util.List; import java.util.Map; @@ -116,7 +117,7 @@ public IndexSettings defaultSettings() { public TypeMapping defaultAnyMapping() { return new TypeMapping.Builder(). - dynamicTemplates(List.of(Map.of( + dynamicTemplates(List.of(new NamedValue<>( "strings", new DynamicTemplate.Builder(). matchMappingType("string"). @@ -129,7 +130,7 @@ public TypeMapping defaultAnyMapping() { public TypeMapping defaultRealmMapping() { return new TypeMapping.Builder(). - dynamicTemplates(List.of(Map.of( + dynamicTemplates(List.of(new NamedValue<>( "strings", new DynamicTemplate.Builder(). matchMappingType("string"). @@ -142,7 +143,7 @@ public TypeMapping defaultRealmMapping() { public TypeMapping defaultAuditMapping() { return new TypeMapping.Builder(). - dynamicTemplates(List.of(Map.of( + dynamicTemplates(List.of(new NamedValue<>( "strings", new DynamicTemplate.Builder(). matchMappingType("string"). diff --git a/ext/elasticsearch/persistence/src/main/java/org/apache/syncope/core/persistence/elasticsearch/dao/ElasticsearchRealmSearchDAO.java b/ext/elasticsearch/persistence/src/main/java/org/apache/syncope/core/persistence/elasticsearch/dao/ElasticsearchRealmSearchDAO.java index 265409d09c0..53936c2d8c4 100644 --- a/ext/elasticsearch/persistence/src/main/java/org/apache/syncope/core/persistence/elasticsearch/dao/ElasticsearchRealmSearchDAO.java +++ b/ext/elasticsearch/persistence/src/main/java/org/apache/syncope/core/persistence/elasticsearch/dao/ElasticsearchRealmSearchDAO.java @@ -21,6 +21,7 @@ import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch._types.ScriptLanguage; import co.elastic.clients.elasticsearch._types.ScriptSortType; +import co.elastic.clients.elasticsearch._types.ScriptSource; import co.elastic.clients.elasticsearch._types.SearchType; import co.elastic.clients.elasticsearch._types.SortOptions; import co.elastic.clients.elasticsearch._types.SortOrder; @@ -54,7 +55,8 @@ public class ElasticsearchRealmSearchDAO implements RealmSearchDAO { new SortOptions.Builder(). script(s -> s.type(ScriptSortType.Number). script(t -> t.lang(ScriptLanguage.Painless). - source("doc['fullPath'].value.chars().filter(ch -> ch == '/').count()")). + source(new ScriptSource.Builder(). + scriptString("doc['fullPath'].value.chars().filter(ch -> ch == '/').count()").build())). order(SortOrder.Asc)). build()); diff --git a/pom.xml b/pom.xml index 53d588c8ebb..60db5d51d12 100644 --- a/pom.xml +++ b/pom.xml @@ -429,7 +429,7 @@ under the License. 4.0.0 - 8.17.4 + 9.0.0 2.19.1 2.23.0 From 46662bc9ac0ae406b6de9e0e437bb247faccb829 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Apr 2025 23:10:01 +0000 Subject: [PATCH 029/579] Bump org.jsoup:jsoup from 1.19.1 to 1.20.1 Bumps [org.jsoup:jsoup](https://github.com/jhy/jsoup) from 1.19.1 to 1.20.1. - [Release notes](https://github.com/jhy/jsoup/releases) - [Changelog](https://github.com/jhy/jsoup/blob/master/CHANGES.md) - [Commits](https://github.com/jhy/jsoup/compare/jsoup-1.19.1...jsoup-1.20.1) --- updated-dependencies: - dependency-name: org.jsoup:jsoup dependency-version: 1.20.1 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 60db5d51d12..285f4b7a8bc 100644 --- a/pom.xml +++ b/pom.xml @@ -1316,7 +1316,7 @@ under the License. org.jsoup jsoup - 1.19.1 + 1.20.1 From 268ee88d99dd709ccfc2fee40057705343fc880c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Wed, 30 Apr 2025 13:16:38 +0200 Subject: [PATCH 030/579] [SYNCOPE-1875] Re-generate SAML SP keystore only if not found --- .../saml/WASAML2ClientKeystoreGenerator.java | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientKeystoreGenerator.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientKeystoreGenerator.java index 8de963dddf8..a02327dab0b 100644 --- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientKeystoreGenerator.java +++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientKeystoreGenerator.java @@ -49,36 +49,40 @@ public WASAML2ClientKeystoreGenerator(final WARestClient waRestClient, final SAM @Override public boolean shouldGenerate() { - return true; + try { + SAML2SPEntityTO spEntity = waRestClient.getService(SAML2SPEntityService.class).get(saml2Client.getName()); + return spEntity.getKeystore() == null; + } catch (Exception e) { + LOG.error("While attempting to read if keystore is available for SP Entity {}", saml2Client.getName(), e); + return true; + } } @Override protected void store(final KeyStore ks, final X509Certificate certificate, final PrivateKey privateKey) throws Exception { + String encodedKeystore; try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { char[] password = saml2Configuration.getKeystorePassword().toCharArray(); ks.store(out, password); out.flush(); - String encodedKeystore = Base64.getEncoder().encodeToString(out.toByteArray()); + encodedKeystore = Base64.getEncoder().encodeToString(out.toByteArray()); LOG.debug("Encoded keystore {}", encodedKeystore); + } - SAML2SPEntityTO entityTO; - try { - entityTO = waRestClient.getService(SAML2SPEntityService.class).get(saml2Client.getName()); - entityTO.setKeystore(encodedKeystore); - } catch (Exception e) { - LOG.debug("SP Entity {} not found, creating new", saml2Client.getName(), e); - - entityTO = new SAML2SPEntityTO.Builder(). - key(saml2Client.getName()). - keystore(encodedKeystore). - build(); - } + SAML2SPEntityTO entityTO; + try { + entityTO = waRestClient.getService(SAML2SPEntityService.class).get(saml2Client.getName()); + entityTO.setKeystore(encodedKeystore); + } catch (Exception e) { + LOG.debug("SP Entity {} keystore not found, creating new", saml2Client.getName(), e); - LOG.debug("Storing SP Entity {}", entityTO); - waRestClient.getService(SAML2SPEntityService.class).set(entityTO); + entityTO = new SAML2SPEntityTO.Builder().key(saml2Client.getName()).keystore(encodedKeystore).build(); } + + LOG.debug("Storing SP Entity {}", entityTO); + waRestClient.getService(SAML2SPEntityService.class).set(entityTO); } @Override @@ -91,7 +95,7 @@ public InputStream retrieve() throws Exception { } catch (Exception e) { String message = "Unable to fetch SAML2 SP keystore for " + saml2Client.getName(); LOG.error(message, e); - throw new Exception(message); + throw new Exception(message, e); } } } From ac27e64cb7bf0f57c299c49e870664146eae673e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 May 2025 08:47:39 +0200 Subject: [PATCH 031/579] Bump org.opensearch.client:opensearch-rest-client from 2.19.1 to 2.19.2 (#1067) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 285f4b7a8bc..f60a537e71d 100644 --- a/pom.xml +++ b/pom.xml @@ -430,7 +430,7 @@ under the License. 4.0.0 9.0.0 - 2.19.1 + 2.19.2 2.23.0 v1 From d69a8d082a132cb53b77d5ad94eebd07f0bcb0d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 May 2025 23:44:09 +0000 Subject: [PATCH 032/579] Bump org.apache.pdfbox:pdfbox from 3.0.4 to 3.0.5 Bumps org.apache.pdfbox:pdfbox from 3.0.4 to 3.0.5. --- updated-dependencies: - dependency-name: org.apache.pdfbox:pdfbox dependency-version: 3.0.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f60a537e71d..0ff0de6bbe6 100644 --- a/pom.xml +++ b/pom.xml @@ -1160,7 +1160,7 @@ under the License. org.apache.pdfbox pdfbox - 3.0.4 + 3.0.5 commons-logging From c2807c3141903722b93cbad1730e5b47c44c472c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Fri, 2 May 2025 11:56:44 +0200 Subject: [PATCH 033/579] Upgrading TestContainers for GHA --- pom.xml | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/pom.xml b/pom.xml index 0ff0de6bbe6..35a5a52c203 100644 --- a/pom.xml +++ b/pom.xml @@ -473,6 +473,8 @@ under the License. 5.8.0 3.9.3 + 1.21.0 + 2.1.0 17.4.0 @@ -1319,6 +1321,49 @@ under the License. 1.20.1 + + org.testcontainers + testcontainers + ${testcontainers.version} + test + + + org.testcontainers + jdbc + ${testcontainers.version} + test + + + org.testcontainers + database-commons + ${testcontainers.version} + test + + + org.testcontainers + mysql + ${testcontainers.version} + test + + + org.testcontainers + mariadb + ${testcontainers.version} + test + + + org.testcontainers + oracle-free + ${testcontainers.version} + test + + + org.testcontainers + openfga + ${testcontainers.version} + test + + org.postgresql postgresql From 17337411b2bf97ce5bb0972d72a1037ee7862588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Sun, 4 May 2025 12:54:58 +0200 Subject: [PATCH 034/579] Upgrading CAS --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 35a5a52c203..957feec369b 100644 --- a/pom.xml +++ b/pom.xml @@ -443,7 +443,7 @@ under the License. 6.1.1 - 7.2.1 + 7.2.2 4.0.4 2.2.30 From 6bd0d37afe5796910a0fb89fc48cc387384e87c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Mon, 5 May 2025 20:30:30 +0200 Subject: [PATCH 035/579] [SYNCOPE-1874] Realm attributes (#1064) --- .../policies/AttrReleasePolicyModalPanel.java | 2 +- .../commons/layout/AbstractAnyFormLayout.java | 1 - .../markup/html/form/AjaxCheckBoxPanel.java | 4 +- .../ui/commons/markup/html/form/AjaxGrid.java | 21 +- .../markup/html/form/AjaxGridFieldPanel.java | 15 +- .../html/form/AjaxNumberFieldPanel.java | 6 +- .../markup/html/form/DateFieldPanel.java | 4 +- .../commons/markup/html/form/FieldPanel.java | 4 +- .../ui/commons/wizards/any/AnyWrapper.java | 4 +- .../syncope/client/console/pages/Realms.java | 3 +- .../client/console/panels/BeanPanel.java | 2 +- .../console/panels/PlainSchemaDetails.java | 2 +- .../syncope/client/console/panels/Realm.java | 78 ++-- .../client/console/panels/RealmDetails.java | 102 +++-- .../console/panels/RealmWizardBuilder.java | 92 ++++- .../client/console/panels/TogglePanel.java | 3 +- .../client/console/rest/SchemaRestClient.java | 5 + .../console/tasks/FormPropertyDefsPanel.java | 6 +- .../html/repeater/data/table/AttrColumn.java | 16 +- .../console/wizards/any/AbstractAttrs.java | 50 +-- .../wizards/any/AbstractAttrsWizardStep.java | 24 +- .../client/console/wizards/any/DerAttrs.java | 15 +- .../console/wizards/any/PlainAttrs.java | 24 +- .../console/wizards/any/Relationships.java | 2 +- .../client/console/wizards/any/VirAttrs.java | 39 +- .../MyDropdownValueProvider.groovy | 4 +- .../client/console/panels/RealmDetails.html | 8 +- .../console/panels/RealmDetails.properties | 2 + .../panels/RealmDetails_fr_CA.properties | 2 + .../console/panels/RealmDetails_it.properties | 2 + .../console/panels/RealmDetails_ja.properties | 2 + .../panels/RealmDetails_pt_BR.properties | 2 + .../console/panels/RealmDetails_ru.properties | 2 + .../syncope/common/lib/RealmMember.java | 3 +- .../AttributableTO.java} | 5 +- .../syncope/common/lib/to/MembershipTO.java | 3 +- .../apache/syncope/common/lib/to/RealmTO.java | 68 +++- .../rest/api/service/SchemaService.java | 9 +- .../apache/syncope/core/logic/RealmLogic.java | 9 +- .../syncope/core/logic/SchemaLogic.java | 6 +- .../rest/cxf/service/SchemaServiceImpl.java | 6 + .../api/attrvalue/DropdownValueProvider.java | 4 +- .../persistence/api/dao/PlainSchemaDAO.java | 2 + .../persistence/api/entity/EntityFactory.java | 2 + .../core/persistence/api/entity/Realm.java | 8 +- .../persistence/api/utils/RealmUtils.java | 38 +- .../common/CommonPersistenceContext.java | 7 + .../common/validation/RealmValidator.java | 21 + .../persistence/jpa/PersistenceContext.java | 3 +- .../core/persistence/jpa/dao/JPARealmDAO.java | 28 ++ .../dao/repo/AbstractPlainSchemaRepoExt.java | 3 +- .../repo/MariaDBPlainSchemaRepoExtImpl.java | 20 + .../dao/repo/MySQLPlainSchemaRepoExtImpl.java | 20 + .../repo/OraclePlainSchemaRepoExtImpl.java | 19 + .../dao/repo/PGPlainSchemaRepoExtImpl.java | 20 + .../jpa/dao/repo/PlainSchemaRepoExt.java | 2 + .../jpa/entity/AbstractEntityFactory.java | 5 + .../core/persistence/jpa/entity/JPARealm.java | 134 +++++-- .../jpa/entity/JSONEntityListener.java | 4 +- .../jpa/entity/JSONRealmListener.java | 46 +++ .../core/persistence/jpa/AbstractTest.java | 5 +- .../core/persistence/jpa/outer/GroupTest.java | 4 +- .../core/persistence/jpa/outer/RealmTest.java | 39 +- .../test/resources/domains/MasterContent.xml | 4 +- .../neo4j/dao/repo/PlainSchemaRepoExt.java | 2 + .../dao/repo/PlainSchemaRepoExtImpl.java | 28 +- .../persistence/neo4j/entity/AbstractAny.java | 34 +- .../neo4j/entity/AbstractAttributable.java | 79 ++++ .../entity/AbstractGroupableRelatable.java | 14 +- .../neo4j/entity/Neo4jEntityFactory.java | 5 + .../persistence/neo4j/entity/Neo4jRealm.java | 82 ++-- .../neo4j/entity/group/Neo4jGroup.java | 19 - .../persistence/neo4j/outer/RealmTest.java | 41 +- .../test/resources/domains/MasterContent.xml | 4 +- .../core/provisioning/api/DerAttrHandler.java | 18 + .../provisioning/api/IntAttrNameParser.java | 41 +- .../core/provisioning/api/MappingManager.java | 48 ++- .../api/data/ItemTransformer.java | 19 + .../core/provisioning/api/jexl/JexlUtils.java | 15 +- .../api/IntAttrNameParserTest.java | 85 +++- .../provisioning/api/jexl/JexlUtilsTest.java | 4 +- .../java/DefaultDerAttrHandler.java | 34 +- .../java/DefaultMappingManager.java | 372 +++++++++++++----- .../java/DefaultVirAttrHandler.java | 30 +- .../java/ProvisioningContext.java | 22 +- ...tAnyDataBinder.java => AnyDataBinder.java} | 164 ++------ .../java/data/AnyObjectDataBinderImpl.java | 22 +- .../java/data/AttributableDataBinder.java | 168 ++++++++ .../java/data/GroupDataBinderImpl.java | 37 +- .../java/data/RealmDataBinderImpl.java | 271 +++++++++---- .../java/data/ResourceDataBinderImpl.java | 19 +- .../java/data/UserDataBinderImpl.java | 10 +- .../DefaultPropagationManager.java | 47 ++- .../DefaultRealmPullResultHandler.java | 9 +- .../DefaultRealmPushResultHandler.java | 14 +- .../java/pushpull/OutboundMatcher.java | 10 +- ...CClient.properties => OIDCC4UI.properties} | 0 .../console/pages/OIDCC4UI_it.properties | 2 +- .../syncope/fit/console/PoliciesITCase.java | 4 +- .../syncope/fit/console/RealmsITCase.java | 36 +- .../apache/syncope/fit/core/RealmITCase.java | 27 +- pom.xml | 4 +- .../reference-guide/concepts/realms.adoc | 1 + .../concepts/typemanagement.adoc | 6 +- 104 files changed, 2066 insertions(+), 876 deletions(-) rename common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/{Attributable.java => to/AttributableTO.java} (90%) create mode 100644 core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JSONRealmListener.java create mode 100644 core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractAttributable.java rename core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/{AbstractAnyDataBinder.java => AnyDataBinder.java} (79%) create mode 100644 core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AttributableDataBinder.java rename ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/pages/{OIDCClient.properties => OIDCC4UI.properties} (100%) diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/policies/AttrReleasePolicyModalPanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/policies/AttrReleasePolicyModalPanel.java index 2995d794ca8..52bba25e29b 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/policies/AttrReleasePolicyModalPanel.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/policies/AttrReleasePolicyModalPanel.java @@ -79,7 +79,7 @@ public AttrReleasePolicyModalPanel( add(new AjaxGridFieldPanel<>( "releaseAttrs", "releaseAttrs", - new PropertyModel<>(model.getObject().getConf(), "releaseAttrs"))); + new PropertyModel<>(model.getObject().getConf(), "releaseAttrs"), false)); AjaxTextFieldPanel allowedAttr = new AjaxTextFieldPanel("panel", "allowedAttrs", new Model<>()); add(new MultiFieldPanel.Builder( diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/layout/AbstractAnyFormLayout.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/layout/AbstractAnyFormLayout.java index 87462253ae1..3e2ba898205 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/layout/AbstractAnyFormLayout.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/layout/AbstractAnyFormLayout.java @@ -45,5 +45,4 @@ public List getWhichDerAttrs() { public List getWhichVirAttrs() { return whichVirAttrs; } - } diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxCheckBoxPanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxCheckBoxPanel.java index 5e88f1b994e..36f546e60b6 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxCheckBoxPanel.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxCheckBoxPanel.java @@ -25,7 +25,7 @@ import org.apache.syncope.client.ui.commons.Constants; import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior; import org.apache.syncope.common.lib.Attr; -import org.apache.syncope.common.lib.Attributable; +import org.apache.syncope.common.lib.to.AttributableTO; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.html.form.CheckBox; import org.apache.wicket.markup.html.list.ListItem; @@ -130,7 +130,7 @@ public void setObject(final Boolean object) { @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - public FieldPanel setNewModel(final Attributable attributable, final String schema) { + public FieldPanel setNewModel(final AttributableTO attributable, final String schema) { field.setModel(new Model() { private static final long serialVersionUID = -4214654722524358000L; diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxGrid.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxGrid.java index a5de0ce93ef..3d933145d08 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxGrid.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxGrid.java @@ -37,7 +37,6 @@ import org.wicketstuff.egrid.column.panel.ActionsPanel; import org.wicketstuff.egrid.component.EditableDataTable; import org.wicketstuff.egrid.provider.IEditableDataProvider; -import org.wicketstuff.egrid.toolbar.HeadersToolbar; import org.wicketstuff.egrid.toolbar.NavigationToolbar; public class AjaxGrid extends Panel { @@ -64,22 +63,22 @@ public AjaxGrid( final String id, final List, S>> columns, final IEditableDataProvider, S> dataProvider, - final long rowsPerPage) { + final long rowsPerPage, + final boolean readonly) { super(id); List, S>> newCols = new ArrayList<>(); newCols.addAll(columns); - newCols.add(new AjaxGridActionsColumn<>(new Model<>("Actions"))); + if (!readonly) { + newCols.add(new AjaxGridActionsColumn<>(new Model<>("Actions"))); + } dataTable = new EditableDataTable<>("dataTable", newCols, dataProvider, rowsPerPage); dataTable.setOutputMarkupId(true); dataTable.addTopToolbar(new NavigationToolbar(dataTable)); - if (displayHeader()) { - dataTable.addTopToolbar(new HeadersToolbar<>(dataTable, dataProvider)); - } - if (displayAdd()) { + if (!readonly) { dataTable.addBottomToolbar(newAddBottomToolbar(dataTable, dataProvider)); } @@ -131,14 +130,6 @@ protected boolean allowDelete(final Item> rowItem) { return true; } - protected boolean displayHeader() { - return true; - } - - protected boolean displayAdd() { - return true; - } - protected void onCancel(final AjaxRequestTarget target, final IModel> rowModel) { } diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxGridFieldPanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxGridFieldPanel.java index e94dae3fa29..34e19c03be0 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxGridFieldPanel.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxGridFieldPanel.java @@ -43,7 +43,12 @@ public class AjaxGridFieldPanel extends Panel { protected final IModel> model; - public AjaxGridFieldPanel(final String id, final String name, final IModel> model) { + public AjaxGridFieldPanel( + final String id, + final String name, + final IModel> model, + final boolean readonly) { + super(id, model); add(new Label(AbstractFieldPanel.LABEL, new ResourceModel(name, name))); @@ -53,15 +58,11 @@ public AjaxGridFieldPanel(final String id, final String name, final IModel(model.getObject().entrySet().stream(). map(e -> MutablePair.of(e.getKey(), e.getValue())).collect(Collectors.toList()), ""), - 10) { + 10, + readonly) { private static final long serialVersionUID = -1315456128897492459L; - @Override - protected boolean displayHeader() { - return false; - } - @Override protected void onAdd(final AjaxRequestTarget target, final Pair newRow) { model.getObject().put(newRow.getLeft(), newRow.getRight()); diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxNumberFieldPanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxNumberFieldPanel.java index 0d6a40272c3..1a9da14125a 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxNumberFieldPanel.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxNumberFieldPanel.java @@ -29,7 +29,7 @@ import org.apache.syncope.client.ui.commons.Constants; import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior; import org.apache.syncope.common.lib.Attr; -import org.apache.syncope.common.lib.Attributable; +import org.apache.syncope.common.lib.to.AttributableTO; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.head.JavaScriptHeaderItem; @@ -109,7 +109,7 @@ public T getObject() { T value = null; if (list != null && !list.isEmpty() && list.getFirst() != null - && !list.getFirst().toString().isEmpty()) { + && !list.getFirst().toString().isEmpty()) { value = reference.equals(Integer.class) ? reference.cast(NumberUtils.toInt(list.getFirst().toString())) : reference.equals(Long.class) @@ -197,7 +197,7 @@ public void setObject(final T object) { } @Override - public FieldPanel setNewModel(final Attributable attributable, final String schema) { + public FieldPanel setNewModel(final AttributableTO attributable, final String schema) { field.setModel(new Model<>() { private static final long serialVersionUID = -4214654722524358000L; diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/DateFieldPanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/DateFieldPanel.java index 9c8ae0c5e2d..4912f8cabb1 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/DateFieldPanel.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/DateFieldPanel.java @@ -27,7 +27,7 @@ import java.util.function.Predicate; import org.apache.commons.lang3.time.FastDateFormat; import org.apache.syncope.common.lib.Attr; -import org.apache.syncope.common.lib.Attributable; +import org.apache.syncope.common.lib.to.AttributableTO; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.head.JavaScriptHeaderItem; import org.apache.wicket.markup.html.list.ListItem; @@ -124,7 +124,7 @@ public void setObject(final Date object) { } @Override - public FieldPanel setNewModel(final Attributable attributable, final String schema) { + public FieldPanel setNewModel(final AttributableTO attributable, final String schema) { field.setModel(new Model<>() { private static final long serialVersionUID = -4214654722524358000L; diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/FieldPanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/FieldPanel.java index 8003f4f78ad..ae30df19f96 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/FieldPanel.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/FieldPanel.java @@ -28,7 +28,7 @@ import org.apache.commons.lang3.SerializationUtils; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.common.lib.Attr; -import org.apache.syncope.common.lib.Attributable; +import org.apache.syncope.common.lib.to.AttributableTO; import org.apache.wicket.AttributeModifier; import org.apache.wicket.PageReference; import org.apache.wicket.markup.html.form.FormComponent; @@ -132,7 +132,7 @@ public FieldPanel setNewModel(final IModel model) { } @SuppressWarnings({ "rawtypes", "unchecked" }) - public FieldPanel setNewModel(final Attributable attributable, final String schema) { + public FieldPanel setNewModel(final AttributableTO attributable, final String schema) { field.setModel(new Model() { private static final long serialVersionUID = -4214654722524358000L; diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/any/AnyWrapper.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/any/AnyWrapper.java index 6fec895f0a4..f82c1ab1179 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/any/AnyWrapper.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/any/AnyWrapper.java @@ -19,9 +19,9 @@ package org.apache.syncope.client.ui.commons.wizards.any; import java.io.Serializable; -import org.apache.syncope.common.lib.to.AnyTO; +import org.apache.syncope.common.lib.to.AttributableTO; -public abstract class AnyWrapper implements Serializable { +public abstract class AnyWrapper implements Serializable { private static final long serialVersionUID = 8058288034211558375L; diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java index 8f52b007509..d2554b2f393 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Realms.java @@ -220,7 +220,7 @@ protected void setWindowClosedReloadCallback(final BaseModal modal) { @Override protected void onClickCreate(final AjaxRequestTarget target) { - this.wizardBuilder.setParentPath(realmChoicePanel.getCurrentRealm().getFullPath()); + this.wizardBuilder.setParent(realmChoicePanel.getCurrentRealm()); send(this, Broadcast.EXACT, new AjaxWizard.NewItemActionEvent(new RealmTO(), target) { @Override @@ -232,7 +232,6 @@ public String getEventDescription() { @Override protected void onClickEdit(final AjaxRequestTarget target, final RealmTO realmTO) { - this.wizardBuilder.setParentPath(realmTO.getFullPath()); send(this, Broadcast.EXACT, new AjaxWizard.EditItemActionEvent(realmTO, target) { @Override diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/BeanPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/BeanPanel.java index 7fe73bef1b4..319971734ae 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/BeanPanel.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/BeanPanel.java @@ -266,7 +266,7 @@ protected void populateItem(final ListItem item) { } } else if (Map.class.equals(field.getType())) { panel = new AjaxGridFieldPanel( - "value", field.getName(), new PropertyModel<>(bean, field.getName())).hideLabel(); + "value", field.getName(), new PropertyModel<>(bean, field.getName()), false).hideLabel(); Optional.ofNullable(field.getAnnotation(io.swagger.v3.oas.annotations.media.Schema.class)). ifPresent(annot -> setDescription(item, annot.description())); } else { diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/PlainSchemaDetails.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/PlainSchemaDetails.java index 8f5813a2600..f230c5683e1 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/PlainSchemaDetails.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/PlainSchemaDetails.java @@ -140,7 +140,7 @@ public PlainSchemaDetails(final String id, final PlainSchemaTO schemaTO) { // enum enumValues = new AjaxGridFieldPanel<>( - "enumValues", "enumValues", new PropertyModel<>(schemaTO, "enumValues")); + "enumValues", "enumValues", new PropertyModel<>(schemaTO, "enumValues"), false); enumParams = new WebMarkupContainer("enumParams"); enumParams.setOutputMarkupPlaceholderTag(true); diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java index 3d983ee4ac0..66a92dd3d35 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/Realm.java @@ -148,9 +148,8 @@ public boolean isVisible() { } @Override - @SuppressWarnings("unchecked") protected Panel customResultBody(final String panelId, final RealmTO item, final Serializable result) { - if (!(result instanceof final ProvisioningResult provisioningResult)) { + if (!(result instanceof ProvisioningResult provisioningResult)) { throw new IllegalStateException("Unsupported result type"); } @@ -273,58 +272,53 @@ protected RealmDetailsTabPanel() { @Override public Panel getPanel(final String panelId) { ActionsPanel actionPanel = new ActionsPanel<>("actions", null); - if (securityCheck(Set.of( - IdRepoEntitlement.REALM_CREATE, - IdRepoEntitlement.REALM_UPDATE, - IdRepoEntitlement.REALM_DELETE))) { - if (securityCheck(Set.of(IdRepoEntitlement.REALM_CREATE))) { - actionPanel.add(new ActionLink<>(realmTO) { + if (securityCheck(Set.of(IdRepoEntitlement.REALM_CREATE))) { + actionPanel.add(new ActionLink<>(realmTO) { - private static final long serialVersionUID = 2802988981431379827L; + private static final long serialVersionUID = 2802988981431379827L; - @Override - public void onClick(final AjaxRequestTarget target, final RealmTO ignore) { - onClickCreate(target); - } - }, ActionLink.ActionType.CREATE, IdRepoEntitlement.REALM_CREATE).hideLabel(); - } + @Override + public void onClick(final AjaxRequestTarget target, final RealmTO ignore) { + onClickCreate(target); + } + }, ActionLink.ActionType.CREATE, IdRepoEntitlement.REALM_CREATE).hideLabel(); + } - if (securityCheck(Set.of(IdRepoEntitlement.REALM_UPDATE))) { - actionPanel.add(new ActionLink<>(realmTO) { + if (securityCheck(Set.of(IdRepoEntitlement.REALM_UPDATE))) { + actionPanel.add(new ActionLink<>(realmTO) { - private static final long serialVersionUID = 2802988981431379828L; + private static final long serialVersionUID = 2802988981431379828L; - @Override - public void onClick(final AjaxRequestTarget target, final RealmTO ignore) { - onClickEdit(target, realmTO); - } - }, ActionLink.ActionType.EDIT, IdRepoEntitlement.REALM_UPDATE).hideLabel(); - } + @Override + public void onClick(final AjaxRequestTarget target, final RealmTO ignore) { + onClickEdit(target, realmTO); + } + }, ActionLink.ActionType.EDIT, IdRepoEntitlement.REALM_UPDATE).hideLabel(); + } - if (securityCheck(Set.of(IdRepoEntitlement.REALM_UPDATE))) { - actionPanel.add(new ActionLink<>(realmTO) { + if (securityCheck(Set.of(IdRepoEntitlement.REALM_UPDATE))) { + actionPanel.add(new ActionLink<>(realmTO) { - private static final long serialVersionUID = 2802988981431379827L; + private static final long serialVersionUID = 2802988981431379827L; - @Override - public void onClick(final AjaxRequestTarget target, final RealmTO ignore) { - onClickTemplate(target); - } - }, ActionLink.ActionType.TEMPLATE, IdRepoEntitlement.REALM_UPDATE).hideLabel(); - } + @Override + public void onClick(final AjaxRequestTarget target, final RealmTO ignore) { + onClickTemplate(target); + } + }, ActionLink.ActionType.TEMPLATE, IdRepoEntitlement.REALM_UPDATE).hideLabel(); + } - if (securityCheck(Set.of(IdRepoEntitlement.REALM_DELETE))) { - actionPanel.add(new ActionLink<>(realmTO) { + if (securityCheck(Set.of(IdRepoEntitlement.REALM_DELETE))) { + actionPanel.add(new ActionLink<>(realmTO) { - private static final long serialVersionUID = 2802988981431379829L; + private static final long serialVersionUID = 2802988981431379829L; - @Override - public void onClick(final AjaxRequestTarget target, final RealmTO ignore) { - onClickDelete(target, realmTO); - } - }, ActionLink.ActionType.DELETE, IdRepoEntitlement.REALM_DELETE, true).hideLabel(); - } + @Override + public void onClick(final AjaxRequestTarget target, final RealmTO ignore) { + onClickDelete(target, realmTO); + } + }, ActionLink.ActionType.DELETE, IdRepoEntitlement.REALM_DELETE, true).hideLabel(); } RealmDetails panel = new RealmDetails(panelId, realmTO, actionPanel, false); diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java index c02ef37cf78..86bfecf4953 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmDetails.java @@ -18,17 +18,25 @@ */ package org.apache.syncope.client.console.panels; +import java.util.Comparator; import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; import org.apache.syncope.client.console.SyncopeWebApplication; import org.apache.syncope.client.console.commons.RealmPolicyProvider; +import org.apache.syncope.client.console.rest.AnyTypeClassRestClient; import org.apache.syncope.client.console.rest.ImplementationRestClient; import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel; import org.apache.syncope.client.ui.commons.Constants; +import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel; +import org.apache.syncope.client.ui.commons.markup.html.form.AjaxGridFieldPanel; import org.apache.syncope.client.ui.commons.markup.html.form.AjaxPalettePanel; import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel; import org.apache.syncope.client.ui.commons.markup.html.form.FieldPanel; +import org.apache.syncope.common.lib.Attr; import org.apache.syncope.common.lib.SyncopeConstants; +import org.apache.syncope.common.lib.to.AnyTypeClassTO; import org.apache.syncope.common.lib.to.ImplementationTO; import org.apache.syncope.common.lib.to.RealmTO; import org.apache.syncope.common.lib.types.IdRepoImplementationType; @@ -38,8 +46,10 @@ import org.apache.wicket.markup.repeater.RepeatingView; import org.apache.wicket.model.IModel; import org.apache.wicket.model.LoadableDetachableModel; +import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.model.util.ListModel; +import org.apache.wicket.model.util.MapModel; import org.apache.wicket.spring.injection.annot.SpringBean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,6 +60,17 @@ public class RealmDetails extends Panel { protected static final Logger LOG = LoggerFactory.getLogger(RealmDetails.class); + protected final IModel> anyTypeClasses = new LoadableDetachableModel<>() { + + private static final long serialVersionUID = 5275935387613157437L; + + @Override + protected List load() { + return anyTypeClassRestClient.list().stream(). + map(AnyTypeClassTO::getKey).sorted().collect(Collectors.toList()); + } + }; + protected final IModel> logicActions = new LoadableDetachableModel<>() { private static final long serialVersionUID = 5275935387613157437L; @@ -71,15 +92,18 @@ protected List load() { } }; - private final ActionsPanel actionsPanel; + @SpringBean + protected AnyTypeClassRestClient anyTypeClassRestClient; @SpringBean protected ImplementationRestClient implementationRestClient; - + @SpringBean - private RealmPolicyProvider realmPolicyProvider; + protected RealmPolicyProvider realmPolicyProvider; + + protected final WebMarkupContainer container; - private final WebMarkupContainer container; + protected final AjaxDropDownChoicePanel anyTypeClass; public RealmDetails(final String id, final RealmTO realmTO) { this(id, realmTO, null, true); @@ -93,50 +117,70 @@ public RealmDetails( super(id); - this.actionsPanel = actionsPanel; - container = new WebMarkupContainer("container"); container.setOutputMarkupId(true); container.setRenderBodyOnly(unwrapped); add(container); - final WebMarkupContainer generics = new WebMarkupContainer("generics"); - container.add(generics.setVisible(unwrapped)); + WebMarkupContainer generics = new WebMarkupContainer("generics"); + container.add(generics); FieldPanel name = new AjaxTextFieldPanel( Constants.NAME_FIELD_NAME, Constants.NAME_FIELD_NAME, new PropertyModel<>(realmTO, Constants.NAME_FIELD_NAME), false); - name.addRequiredLabel(); - generics.add(name); + generics.add(name.addRequiredLabel().setVisible(unwrapped)); FieldPanel fullPath = new AjaxTextFieldPanel( "fullPath", "fullPath", new PropertyModel<>(realmTO, "fullPath"), false); fullPath.setEnabled(false); - generics.add(fullPath); + generics.add(fullPath.setVisible(unwrapped)); + + anyTypeClass = new AjaxDropDownChoicePanel<>( + "anyTypeClass", "anyTypeClass", new PropertyModel<>(realmTO, "anyTypeClass"), true); + anyTypeClass.setChoices(anyTypeClasses.getObject()); + generics.add(anyTypeClass); + + Map attrs = realmTO.getPlainAttrs().stream(). + sorted(Comparator.comparing(Attr::getSchema)). + collect(Collectors.toMap(Attr::getSchema, attr -> attr.getValues().toString())); + container.add(new AjaxGridFieldPanel<>( + "plainAttrs", + "plainAttrs", + new MapModel<>(attrs), + true).setOutputMarkupPlaceholderTag(true).setVisible(!unwrapped)); RepeatingView policies = new RepeatingView("policies"); realmPolicyProvider.add(realmTO, policies); container.add(policies); - AjaxPalettePanel actions = new AjaxPalettePanel.Builder(). - setAllowMoveAll(true).setAllowOrder(true). - build("actions", - new PropertyModel<>(realmTO, "actions"), - new ListModel<>(logicActions.getObject())); - actions.setOutputMarkupId(true); - container.add(actions); - - container.add(new AjaxPalettePanel.Builder().build("resources", - new PropertyModel<>(realmTO, "resources"), - new ListModel<>(resources.getObject())). - setOutputMarkupId(true). - setEnabled(!SyncopeConstants.ROOT_REALM.equals(realmTO.getName())). - setVisible(!SyncopeConstants.ROOT_REALM.equals(realmTO.getName()))); + if (unwrapped) { + container.add(new AjaxPalettePanel.Builder(). + setAllowMoveAll(true).setAllowOrder(true). + build("actions", + new PropertyModel<>(realmTO, "actions"), + new ListModel<>(logicActions.getObject())). + setOutputMarkupId(true)); + } else { + container.add(new AjaxTextFieldPanel( + "actions", "actions", Model.of(realmTO.getActions().toString()))); + } + + if (unwrapped) { + container.add(new AjaxPalettePanel.Builder().build("resources", + new PropertyModel<>(realmTO, "resources"), + new ListModel<>(resources.getObject())). + setOutputMarkupId(true). + setEnabled(!SyncopeConstants.ROOT_REALM.equals(realmTO.getName())). + setVisible(!SyncopeConstants.ROOT_REALM.equals(realmTO.getName()))); + } else { + container.add(new AjaxTextFieldPanel( + "resources", "resources", Model.of(realmTO.getResources().toString()))); + } if (actionsPanel == null) { - add(new Fragment("actions", "emptyFragment", this).setRenderBodyOnly(true)); + add(new Fragment("actionsPanel", "emptyFragment", this).setRenderBodyOnly(true)); } else { - Fragment fragment = new Fragment("actions", "actionsFragment", this); + Fragment fragment = new Fragment("actionsPanel", "actionsFragment", this); fragment.add(actionsPanel); add(fragment.setRenderBodyOnly(true)); } @@ -147,7 +191,7 @@ public RealmDetails setContentEnabled(final boolean enable) { return this; } - public ActionsPanel getActionsPanel() { - return actionsPanel; + public Optional getAnyTypeClassValue() { + return Optional.ofNullable(anyTypeClass.getModelObject()); } } diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmWizardBuilder.java index 6c83311a3ec..b087756d39c 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmWizardBuilder.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/RealmWizardBuilder.java @@ -19,9 +19,14 @@ package org.apache.syncope.client.console.panels; import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; import org.apache.syncope.client.console.rest.RealmRestClient; import org.apache.syncope.client.console.wizards.BaseAjaxWizardBuilder; -import org.apache.syncope.common.lib.to.ProvisioningResult; +import org.apache.syncope.client.console.wizards.any.DerAttrs; +import org.apache.syncope.client.console.wizards.any.PlainAttrs; +import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper; import org.apache.syncope.common.lib.to.RealmTO; import org.apache.wicket.PageReference; import org.apache.wicket.behavior.AttributeAppender; @@ -32,44 +37,93 @@ public class RealmWizardBuilder extends BaseAjaxWizardBuilder { private static final long serialVersionUID = 5945391813567245081L; + protected static final class RealmWrapper extends AnyWrapper { + + private static final long serialVersionUID = 4347624290770782509L; + + public RealmWrapper(final RealmTO attributable) { + super(attributable); + } + } + protected final RealmRestClient realmRestClient; - protected String parentPath; + protected RealmTO parent; public RealmWizardBuilder(final RealmRestClient realmRestClient, final PageReference pageRef) { super(new RealmTO(), pageRef); this.realmRestClient = realmRestClient; } + public void setParent(final RealmTO parent) { + this.parent = parent; + } + @Override protected Serializable onApplyInternal(final RealmTO modelObject) { - ProvisioningResult result; - if (modelObject.getKey() == null) { - result = realmRestClient.create(this.parentPath, modelObject); - } else { - result = realmRestClient.update(modelObject); - } - return result; + return parent == null + ? realmRestClient.update(modelObject) + : realmRestClient.create(parent.getFullPath(), modelObject); } @Override protected WizardModel buildModelSteps(final RealmTO modelObject, final WizardModel wizardModel) { - wizardModel.add(new Realm(modelObject)); + Optional.ofNullable(parent).map(RealmTO::getAnyTypeClass).ifPresent(modelObject::setAnyTypeClass); + + RealmDetails details = new RealmDetails("details", modelObject); + details.add(new AttributeAppender("style", "overflow-x:hidden;")); + + wizardModel.add(new Realm(details)); + + RealmWrapper wrapper = new RealmWrapper(modelObject); + + List anyTypeClasses = new ArrayList<>(); + Optional.ofNullable((modelObject.getAnyTypeClass())).ifPresent(anyTypeClasses::add); + + wizardModel.add(new PlainAttrs(wrapper, mode, anyTypeClasses, List.of()) { + + private static final long serialVersionUID = 8167894751609598306L; + + @Override + public PageReference getPageReference() { + return pageRef; + } + + @Override + public boolean evaluate() { + anyTypeClasses.clear(); + details.getAnyTypeClassValue().ifPresent(anyTypeClasses::add); + super.evaluate(); + return true; + } + }); + + wizardModel.add(new DerAttrs(wrapper, anyTypeClasses, List.of()) { + + private static final long serialVersionUID = 4298394879912549771L; + + @Override + public PageReference getPageReference() { + return pageRef; + } + + @Override + public boolean evaluate() { + anyTypeClasses.clear(); + details.getAnyTypeClassValue().ifPresent(anyTypeClasses::add); + return super.evaluate(); + } + }); + return wizardModel; } - public static class Realm extends WizardStep { + protected static class Realm extends WizardStep { private static final long serialVersionUID = -2123790676338327104L; - public Realm(final RealmTO modelObject) { - RealmDetails realmDetail = new RealmDetails("details", modelObject); - realmDetail.add(new AttributeAppender("style", "overflow-x:hidden;")); - add(realmDetail); + protected Realm(final RealmDetails details) { + add(details); } } - - public void setParentPath(final String parentPath) { - this.parentPath = parentPath; - } } diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/TogglePanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/TogglePanel.java index 2a3030724cb..e69bf99c185 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/TogglePanel.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/TogglePanel.java @@ -28,6 +28,7 @@ import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper; import org.apache.syncope.common.keymaster.client.api.model.Domain; import org.apache.syncope.common.lib.Attr; +import org.apache.syncope.common.lib.to.AnyTO; import org.apache.syncope.common.lib.to.EntityTO; import org.apache.syncope.common.lib.to.JobTO; import org.apache.wicket.AttributeModifier; @@ -165,7 +166,7 @@ protected String getTargetKey(final Serializable modelObject) { } else if (modelObject instanceof EntityTO entityTO) { key = entityTO.getKey(); } else if (modelObject instanceof final AnyWrapper anyWrapper) { - key = anyWrapper.getInnerObject().getKey(); + key = anyWrapper.getInnerObject() instanceof AnyTO anyTO ? anyTO.getKey() : null; } else if (modelObject instanceof Attr attr) { key = attr.getSchema(); } else if (modelObject instanceof ConfParam confParam) { diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java index 4b534f785d6..8609cd22b61 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java @@ -25,6 +25,7 @@ import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.to.AnyTO; import org.apache.syncope.common.lib.to.AnyTypeTO; +import org.apache.syncope.common.lib.to.RealmTO; import org.apache.syncope.common.lib.to.SchemaTO; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.SchemaType; @@ -116,4 +117,8 @@ public void delete(final SchemaType schemaType, final String key) { public List getDropdownValues(final String key, final AnyTO anyTO) { return getService(SchemaService.class).getDropdownValues(key, anyTO).getValues(); } + + public List getDropdownValues(final String key, final RealmTO realmTO) { + return getService(SchemaService.class).getDropdownValues(key, realmTO).getValues(); + } } diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel.java index 3529397e637..f27ed56a561 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/tasks/FormPropertyDefsPanel.java @@ -100,7 +100,8 @@ protected void populateItem(final ListItem item) { AjaxGridFieldPanel labels = new AjaxGridFieldPanel<>( "labels", "labels", - new PropertyModel<>(fpd, "labels")); + new PropertyModel<>(fpd, "labels"), + false); item.add(labels.hideLabel()); AjaxCheckBoxPanel readable = new AjaxCheckBoxPanel( @@ -176,7 +177,8 @@ public void validate(final IValidatable validatable) { AjaxGridFieldPanel enumValues = new AjaxGridFieldPanel<>( "enumValues", "enumValues", - new PropertyModel<>(fpd, "enumValues")); + new PropertyModel<>(fpd, "enumValues"), + false); enumValues.setVisible(fpd.getType() == FormPropertyType.Enum); item.add(enumValues.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true)); diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/AttrColumn.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/AttrColumn.java index 43d6db503d1..17cfcde775d 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/AttrColumn.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/AttrColumn.java @@ -20,7 +20,7 @@ import java.util.ArrayList; import java.util.List; -import org.apache.syncope.common.lib.Attributable; +import org.apache.syncope.common.lib.to.AttributableTO; import org.apache.syncope.common.lib.types.SchemaType; import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator; import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn; @@ -29,7 +29,7 @@ import org.apache.wicket.model.IModel; import org.apache.wicket.model.ResourceModel; -public class AttrColumn extends AbstractColumn { +public class AttrColumn extends AbstractColumn { private static final long serialVersionUID = 2624734332447371372L; @@ -52,19 +52,17 @@ public void populateItem( List values = new ArrayList<>(); switch (schemaType) { - case PLAIN: + case PLAIN -> rowModel.getObject().getPlainAttr(name).ifPresent(attr -> values.addAll(attr.getValues())); - break; - case DERIVED: + case DERIVED -> rowModel.getObject().getDerAttr(name).ifPresent(attr -> values.addAll(attr.getValues())); - break; - case VIRTUAL: + case VIRTUAL -> rowModel.getObject().getVirAttr(name).ifPresent(attr -> values.addAll(attr.getValues())); - break; - default: + default -> { + } } if (values.isEmpty()) { diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java index 8a8412e05cc..ada7c05b6ed 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java @@ -28,6 +28,7 @@ import org.apache.syncope.client.ui.commons.wizards.AjaxWizard; import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper; import org.apache.syncope.common.lib.Attr; +import org.apache.syncope.common.lib.to.AnyTO; import org.apache.syncope.common.lib.to.AnyTypeClassTO; import org.apache.syncope.common.lib.to.GroupTO; import org.apache.syncope.common.lib.to.MembershipTO; @@ -67,29 +68,34 @@ public AbstractAttrs( @SuppressWarnings("unchecked") private List loadMemberships() { - membershipSchemas.clear(); - - List membs = new ArrayList<>(); - try { - ((List) PropertyResolver.getPropertyField("memberships", anyTO).get(anyTO)).forEach(memb -> { - setSchemas(memb.getGroupKey(), - anyTypeClassRestClient.list(getMembershipAuxClasses(memb, anyTO.getType())). - stream().map(AnyTypeClassTO::getKey).collect(Collectors.toList())); - setAttrs(memb); - - if (this instanceof PlainAttrs && !memb.getPlainAttrs().isEmpty()) { - membs.add(memb); - } else if (this instanceof DerAttrs && !memb.getDerAttrs().isEmpty()) { - membs.add(memb); - } else if (this instanceof VirAttrs && !memb.getVirAttrs().isEmpty()) { - membs.add(memb); - } - }); - } catch (WicketRuntimeException | IllegalArgumentException | IllegalAccessException ex) { - // ignore + if (attributable instanceof AnyTO anyTO) { + membershipSchemas.clear(); + + List membs = new ArrayList<>(); + try { + ((Iterable) PropertyResolver.getPropertyField("memberships", anyTO).get(anyTO)). + forEach(memb -> { + setSchemas(memb.getGroupKey(), + anyTypeClassRestClient.list(getMembershipAuxClasses(memb, anyTO.getType())). + stream().map(AnyTypeClassTO::getKey).collect(Collectors.toList())); + setAttrs(memb); + + if (this instanceof PlainAttrs && !memb.getPlainAttrs().isEmpty()) { + membs.add(memb); + } else if (this instanceof DerAttrs && !memb.getDerAttrs().isEmpty()) { + membs.add(memb); + } else if (this instanceof VirAttrs && !memb.getVirAttrs().isEmpty()) { + membs.add(memb); + } + }); + } catch (WicketRuntimeException | IllegalArgumentException | IllegalAccessException ex) { + // ignore + } + + return membs; } - return membs; + return List.of(); } private void setSchemas(final String membership, final List anyTypeClasses) { @@ -109,7 +115,7 @@ protected List getMembershipAuxClasses(final MembershipTO membershipTO, GroupTO groupTO = groupRestClient.read(membershipTO.getGroupKey()); return groupTO.getTypeExtension(anyType). map(TypeExtensionTO::getAuxClasses). - orElseGet(List::of); + orElseGet(List::of); } catch (Exception e) { return List.of(); } diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java index beb19b7b834..74c17e628ab 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrsWizardStep.java @@ -52,7 +52,9 @@ import org.apache.syncope.common.lib.SyncopeConstants; import org.apache.syncope.common.lib.to.AnyTO; import org.apache.syncope.common.lib.to.AnyTypeClassTO; +import org.apache.syncope.common.lib.to.AttributableTO; import org.apache.syncope.common.lib.to.PlainSchemaTO; +import org.apache.syncope.common.lib.to.RealmTO; import org.apache.syncope.common.lib.to.SchemaTO; import org.apache.syncope.common.lib.types.AttrSchemaType; import org.apache.syncope.common.lib.types.SchemaType; @@ -83,9 +85,9 @@ public abstract class AbstractAttrsWizardStep extends Wizard protected final Comparator attrComparator = new AttrComparator(); - protected final AnyTO anyTO; + protected final AttributableTO attributable; - protected AnyTO previousObject; + protected AttributableTO previousObject; protected final List whichAttrs; @@ -100,7 +102,7 @@ public abstract class AbstractAttrsWizardStep extends Wizard protected final AjaxWizard.Mode mode; public AbstractAttrsWizardStep( - final AnyTO anyTO, + final AttributableTO attributable, final AjaxWizard.Mode mode, final List anyTypeClasses, final List whichAttrs) { @@ -112,14 +114,18 @@ public AbstractAttrsWizardStep( this.setOutputMarkupId(true); this.mode = mode; - this.anyTO = anyTO; + this.attributable = attributable; this.whichAttrs = whichAttrs; } protected List loadAttrs() { List classes = new ArrayList<>(anyTypeClasses); - classes.addAll(anyTypeClassRestClient.list(anyTO.getAuxClasses()).stream(). - map(AnyTypeClassTO::getKey).toList()); + if (attributable instanceof AnyTO anyTO) { + classes.addAll(anyTypeClassRestClient.list(anyTO.getAuxClasses()).stream(). + map(AnyTypeClassTO::getKey).toList()); + } else if (attributable instanceof RealmTO realmTO && realmTO.getAnyTypeClass() != null) { + classes.add(realmTO.getAnyTypeClass()); + } setSchemas(classes); setAttrs(); return getAttrsFromTO(); @@ -268,7 +274,11 @@ public String getObject( break; case Dropdown: - List dropdownValues = schemaRestClient.getDropdownValues(plainSchema.getKey(), anyTO); + List dropdownValues = attributable instanceof AnyTO anyTO + ? schemaRestClient.getDropdownValues(plainSchema.getKey(), anyTO) + : attributable instanceof RealmTO realmTO + ? schemaRestClient.getDropdownValues(plainSchema.getKey(), realmTO) + : List.of(); if (plainSchema.isMultivalue()) { panel = new AjaxPalettePanel.Builder(). setName(plainSchema.getLabel(SyncopeConsoleSession.get().getLocale())). diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java index 9b5cb6e466f..0f8295c8a88 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/DerAttrs.java @@ -31,7 +31,7 @@ import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper; import org.apache.syncope.common.lib.Attr; import org.apache.syncope.common.lib.EntityTOUtils; -import org.apache.syncope.common.lib.to.AnyTO; +import org.apache.syncope.common.lib.to.AttributableTO; import org.apache.syncope.common.lib.to.DerSchemaTO; import org.apache.syncope.common.lib.to.GroupableRelatableTO; import org.apache.syncope.common.lib.to.MembershipTO; @@ -52,7 +52,7 @@ public class DerAttrs extends AbstractAttrs { private static final long serialVersionUID = -5387344116983102292L; - public DerAttrs( + public DerAttrs( final AnyWrapper modelObject, final List anyTypeClasses, final List whichDerAttrs) { @@ -105,7 +105,7 @@ protected SchemaType getSchemaType() { @Override protected List getAttrsFromTO() { - return anyTO.getDerAttrs().stream().sorted(attrComparator).collect(Collectors.toList()); + return attributable.getDerAttrs().stream().sorted(attrComparator).collect(Collectors.toList()); } @Override @@ -117,7 +117,7 @@ protected List getAttrsFromTO(final MembershipTO membershipTO) { protected void setAttrs() { List derAttrs = new ArrayList<>(); - Map attrMap = EntityTOUtils.buildAttrMap(anyTO.getDerAttrs()); + Map attrMap = EntityTOUtils.buildAttrMap(attributable.getDerAttrs()); schemas.values().forEach(schema -> { Attr attrTO = new Attr(); @@ -129,13 +129,14 @@ protected void setAttrs() { derAttrs.add(attrTO); }); - anyTO.getDerAttrs().clear(); - anyTO.getDerAttrs().addAll(derAttrs); + attributable.getDerAttrs().clear(); + attributable.getDerAttrs().addAll(derAttrs); } @Override protected void setAttrs(final MembershipTO membershipTO) { - Map attrMap = GroupableRelatableTO.class.cast(anyTO).getMembership(membershipTO.getGroupKey()). + Map attrMap = GroupableRelatableTO.class.cast(attributable). + getMembership(membershipTO.getGroupKey()). map(gr -> EntityTOUtils.buildAttrMap(gr.getDerAttrs())). orElseGet(HashMap::new); diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java index 063a40e25e9..75d78133dcd 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java @@ -28,10 +28,9 @@ import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper; import org.apache.syncope.client.ui.commons.wizards.any.UserWrapper; import org.apache.syncope.common.lib.Attr; -import org.apache.syncope.common.lib.Attributable; import org.apache.syncope.common.lib.EntityTOUtils; import org.apache.syncope.common.lib.to.AnyObjectTO; -import org.apache.syncope.common.lib.to.AnyTO; +import org.apache.syncope.common.lib.to.AttributableTO; import org.apache.syncope.common.lib.to.GroupTO; import org.apache.syncope.common.lib.to.GroupableRelatableTO; import org.apache.syncope.common.lib.to.MembershipTO; @@ -53,7 +52,7 @@ public class PlainAttrs extends AbstractAttrs { private static final long serialVersionUID = 552437609667518888L; - public PlainAttrs( + public PlainAttrs( final AnyWrapper modelObject, final AjaxWizard.Mode mode, final List anyTypeClasses, @@ -108,12 +107,12 @@ public WebMarkupContainer getPanel(final String panelId) { return new PlainSchemasMemberships( panelId, membershipSchemas.get(membershipTO.getGroupKey()), - new LoadableDetachableModel<>() { // SYNCOPE-1439 + new LoadableDetachableModel<>() { private static final long serialVersionUID = 526768546610546553L; @Override - protected Attributable load() { + protected AttributableTO load() { return membershipTO; } }); @@ -135,7 +134,7 @@ protected boolean reoderSchemas() { @Override protected List getAttrsFromTO() { - return anyTO.getPlainAttrs().stream().sorted(attrComparator).collect(Collectors.toList()); + return attributable.getPlainAttrs().stream().sorted(attrComparator).collect(Collectors.toList()); } @Override @@ -145,7 +144,7 @@ protected List getAttrsFromTO(final MembershipTO membershipTO) { @Override protected void setAttrs() { - Map attrMap = EntityTOUtils.buildAttrMap(anyTO.getPlainAttrs()); + Map attrMap = EntityTOUtils.buildAttrMap(attributable.getPlainAttrs()); List plainAttrs = schemas.values().stream().map(schema -> { Attr attr = new Attr(); @@ -158,13 +157,14 @@ protected void setAttrs() { return attr; }).toList(); - anyTO.getPlainAttrs().clear(); - anyTO.getPlainAttrs().addAll(plainAttrs); + attributable.getPlainAttrs().clear(); + attributable.getPlainAttrs().addAll(plainAttrs); } @Override protected void setAttrs(final MembershipTO membershipTO) { - Map attrMap = GroupableRelatableTO.class.cast(anyTO).getMembership(membershipTO.getGroupKey()). + Map attrMap = GroupableRelatableTO.class.cast(attributable). + getMembership(membershipTO.getGroupKey()). map(gr -> EntityTOUtils.buildAttrMap(gr.getPlainAttrs())). orElseGet(HashMap::new); @@ -207,14 +207,14 @@ protected void populateItem(final ListItem item) { } } - protected class PlainSchemasMemberships extends PlainSchemas { + protected class PlainSchemasMemberships extends PlainSchemas { private static final long serialVersionUID = 456754923340249215L; public PlainSchemasMemberships( final String id, final Map schemas, - final IModel attributableTO) { + final IModel attributableTO) { super(id); diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java index a04054e42f4..13df8494e2d 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java @@ -93,7 +93,7 @@ public class Relationships extends WizardStep implements ICondition { protected final PageReference pageRef; - public Relationships(final AnyWrapper modelObject, final PageReference pageRef) { + public Relationships(final AnyWrapper modelObject, final PageReference pageRef) { super(); add(new Label("title", new ResourceModel("any.relationships"))); diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/VirAttrs.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/VirAttrs.java index 01ae1dcd938..44c65e5a4ac 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/VirAttrs.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/VirAttrs.java @@ -87,16 +87,16 @@ public WebMarkupContainer getPanel(final String panelId) { protected void populateItem(final ListItem item) { MembershipTO membTO = item.getModelObject(); item.add(new Accordion("membershipVirSchemas", List.of(new AbstractTab( - new StringResourceModel("attributes.membership.accordion", VirAttrs.this, Model.of(membTO))) { + new StringResourceModel("attributes.membership.accordion", VirAttrs.this, Model.of(membTO))) { private static final long serialVersionUID = 1037272333056449378L; @Override public WebMarkupContainer getPanel(final String panelId) { return new VirAttrs.VirSchemas( - panelId, - membershipSchemas.get(membTO.getGroupKey()), - new ListModel<>(getAttrsFromTO(membTO))); + panelId, + membershipSchemas.get(membTO.getGroupKey()), + new ListModel<>(getAttrsFromTO(membTO))); } }), Model.of(-1)).setOutputMarkupId(true)); } @@ -110,7 +110,7 @@ protected SchemaType getSchemaType() { @Override protected List getAttrsFromTO() { - return anyTO.getVirAttrs().stream().sorted(attrComparator).collect(Collectors.toList()); + return attributable.getVirAttrs().stream().sorted(attrComparator).collect(Collectors.toList()); } @Override @@ -122,7 +122,7 @@ protected List getAttrsFromTO(final MembershipTO membershipTO) { protected void setAttrs() { List virAttrs = new ArrayList<>(); - Map attrMap = EntityTOUtils.buildAttrMap(anyTO.getVirAttrs()); + Map attrMap = EntityTOUtils.buildAttrMap(attributable.getVirAttrs()); virAttrs.addAll(schemas.values().stream().map(schema -> { Attr attrTO = new Attr(); @@ -135,13 +135,14 @@ protected void setAttrs() { return attrTO; }).toList()); - anyTO.getVirAttrs().clear(); - anyTO.getVirAttrs().addAll(virAttrs); + attributable.getVirAttrs().clear(); + attributable.getVirAttrs().addAll(virAttrs); } @Override protected void setAttrs(final MembershipTO membershipTO) { - Map attrMap = GroupableRelatableTO.class.cast(anyTO).getMembership(membershipTO.getGroupKey()). + Map attrMap = GroupableRelatableTO.class.cast(attributable). + getMembership(membershipTO.getGroupKey()). map(gr -> EntityTOUtils.buildAttrMap(gr.getVirAttrs())). orElseGet(HashMap::new); @@ -181,27 +182,27 @@ protected void populateItem(final ListItem item) { VirSchemaTO virSchemaTO = schemas.get(attrTO.getSchema()); AbstractFieldPanel panel = new AjaxTextFieldPanel( - "panel", - virSchemaTO.getLabel(SyncopeConsoleSession.get().getLocale()), - new Model<>(), - false); + "panel", + virSchemaTO.getLabel(SyncopeConsoleSession.get().getLocale()), + new Model<>(), + false); if (mode == AjaxWizard.Mode.TEMPLATE) { AjaxTextFieldPanel.class.cast(panel).enableJexlHelp().setEnabled(!virSchemaTO.isReadonly()); } else { panel = new MultiFieldPanel.Builder<>( - new PropertyModel>(attrTO, "values")).build( - "panel", - virSchemaTO.getLabel(SyncopeConsoleSession.get().getLocale()), - AjaxTextFieldPanel.class.cast(panel)); + new PropertyModel>(attrTO, "values")).build( + "panel", + virSchemaTO.getLabel(SyncopeConsoleSession.get().getLocale()), + AjaxTextFieldPanel.class.cast(panel)); panel.setEnabled(!virSchemaTO.isReadonly()); } item.add(panel); if (!attrTO.getValues().isEmpty() - && VirAttrs.this.modelObject instanceof UserWrapper - && UserWrapper.class.cast(VirAttrs.this.modelObject).getPreviousUserTO() != null) { + && VirAttrs.this.modelObject instanceof UserWrapper + && UserWrapper.class.cast(VirAttrs.this.modelObject).getPreviousUserTO() != null) { panel.showExternAction(new LabelInfo("externalAction", StringUtils.EMPTY)); } diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyDropdownValueProvider.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyDropdownValueProvider.groovy index fdd6f7e1de9..f162b8e9f7a 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyDropdownValueProvider.groovy +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyDropdownValueProvider.groovy @@ -18,12 +18,12 @@ */ import groovy.transform.CompileStatic import java.util.List -import org.apache.syncope.common.lib.to.AnyTO +import org.apache.syncope.common.lib.to.AttributableTO import org.apache.syncope.core.persistence.api.attrvalue.DropdownValueProvider @CompileStatic class MyDropdownValueProvider implements DropdownValueProvider { - List getChoices(AnyTO anyTO) { + List getChoices(AttributableTO attributableTO) { return [] } } diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails.html index 13c074fc28e..dbcd850f91c 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails.html +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails.html @@ -26,6 +26,12 @@
[fullPath]
+
+ [anyTypeClass] +
+
+
+
[policies] @@ -38,7 +44,7 @@
- + diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails.properties index 96cd961bcf1..499b0dcb344 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails.properties @@ -23,3 +23,5 @@ authPolicy=Authentication Policy accessPolicy=Access Policy attrReleasePolicy=Attribute Release Policy ticketExpirationPolicy=Ticket Expiration Policy +anyTypeClass=AnyTypeClass +plainAttrs=Attributes diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_fr_CA.properties index 67f58c653a5..ae1bc48bdd0 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_fr_CA.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_fr_CA.properties @@ -23,3 +23,5 @@ authPolicy=Authentication Policy accessPolicy=Access Policy attrReleasePolicy=Attribute Release Policy ticketExpirationPolicy=Ticket Expiration Policy +anyTypeClass=AnyTypeClass +plainAttrs=Attributs diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_it.properties index 6fe3561459b..2edd63e2f90 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_it.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_it.properties @@ -23,3 +23,5 @@ authPolicy=Politica Autenticazione accessPolicy=Politica Accesso attrReleasePolicy=Politica Rilascio Attributi ticketExpirationPolicy=Politica Ticket Expiration +anyTypeClass=AnyTypeClass +plainAttrs=Attributi diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_ja.properties index 5c96552b726..531b1b16856 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_ja.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_ja.properties @@ -23,3 +23,5 @@ authPolicy=Authentication Policy accessPolicy=Access Policy attrReleasePolicy=Attribute Release Policy ticketExpirationPolicy=Ticket Expiration Policy +anyTypeClass=AnyTypeClass +plainAttrs=Attributes diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_pt_BR.properties index e9a09dbc90e..8cbaee26878 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_pt_BR.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_pt_BR.properties @@ -23,3 +23,5 @@ authPolicy=Authentication Policy accessPolicy=Access Policy attrReleasePolicy=Attribute Release Policy ticketExpirationPolicy=Ticket Expiration Policy +anyTypeClass=AnyTypeClass +plainAttrs=Attributes diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_ru.properties index dd2b0208f73..4b6f2b47dd3 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_ru.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_ru.properties @@ -24,3 +24,5 @@ authPolicy=Authentication Policy accessPolicy=Access Policy attrReleasePolicy=Attribute Release Policy ticketExpirationPolicy=Ticket Expiration Policy +anyTypeClass=AnyTypeClass +plainAttrs=Attributes diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/RealmMember.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/RealmMember.java index b0aa831e8b5..87f6c77e9c8 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/RealmMember.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/RealmMember.java @@ -19,8 +19,9 @@ package org.apache.syncope.common.lib; import java.util.Set; +import org.apache.syncope.common.lib.to.AttributableTO; -public interface RealmMember extends Attributable { +public interface RealmMember extends AttributableTO { String getRealm(); diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/Attributable.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AttributableTO.java similarity index 90% rename from common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/Attributable.java rename to common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AttributableTO.java index d1bfdaacaf2..1e029f9eefa 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/Attributable.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AttributableTO.java @@ -16,12 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.syncope.common.lib; +package org.apache.syncope.common.lib.to; import java.util.Optional; import java.util.Set; +import org.apache.syncope.common.lib.Attr; -public interface Attributable { +public interface AttributableTO { Set getPlainAttrs(); diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/MembershipTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/MembershipTO.java index c47cb7c2889..79c8305c749 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/MembershipTO.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/MembershipTO.java @@ -31,10 +31,9 @@ import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.syncope.common.lib.Attr; -import org.apache.syncope.common.lib.Attributable; import org.apache.syncope.common.lib.BaseBean; -public class MembershipTO implements BaseBean, Attributable { +public class MembershipTO implements BaseBean, AttributableTO { private static final long serialVersionUID = 5992828670273935861L; diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/RealmTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/RealmTO.java index f3769928c10..fa8951d13ea 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/RealmTO.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/RealmTO.java @@ -18,6 +18,7 @@ */ package org.apache.syncope.common.lib.to; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; import jakarta.ws.rs.PathParam; @@ -25,10 +26,14 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.TreeSet; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.syncope.common.lib.Attr; -public class RealmTO implements NamedEntityTO, TemplatableTO { +public class RealmTO implements NamedEntityTO, TemplatableTO, AttributableTO { private static final long serialVersionUID = 516330662956254391L; @@ -40,6 +45,8 @@ public class RealmTO implements NamedEntityTO, TemplatableTO { private String fullPath; + private String anyTypeClass; + private String accountPolicy; private String passwordPolicy; @@ -52,6 +59,12 @@ public class RealmTO implements NamedEntityTO, TemplatableTO { private String ticketExpirationPolicy; + private final Set plainAttrs = new TreeSet<>(); + + private final Set derAttrs = new TreeSet<>(); + + private final Set virAttrs = Set.of(); + private final List actions = new ArrayList<>(); private final Map templates = new HashMap<>(); @@ -95,6 +108,14 @@ public void setFullPath(final String fullPath) { this.fullPath = fullPath; } + public String getAnyTypeClass() { + return anyTypeClass; + } + + public void setAnyTypeClass(final String anyTypeClass) { + this.anyTypeClass = anyTypeClass; + } + public String getAccountPolicy() { return accountPolicy; } @@ -143,6 +164,45 @@ public void setTicketExpirationPolicy(final String ticketExpirationPolicy) { this.ticketExpirationPolicy = ticketExpirationPolicy; } + @JacksonXmlElementWrapper(localName = "plainAttrs") + @JacksonXmlProperty(localName = "plainAttr") + @Override + public Set getPlainAttrs() { + return plainAttrs; + } + + @JsonIgnore + @Override + public Optional getPlainAttr(final String schema) { + return plainAttrs.stream().filter(attr -> attr.getSchema().equals(schema)).findFirst(); + } + + @JacksonXmlElementWrapper(localName = "derAttrs") + @JacksonXmlProperty(localName = "derAttr") + @Override + public Set getDerAttrs() { + return derAttrs; + } + + @JsonIgnore + @Override + public Optional getDerAttr(final String schema) { + return derAttrs.stream().filter(attr -> attr.getSchema().equals(schema)).findFirst(); + } + + @JacksonXmlElementWrapper(localName = "virAttrs") + @JacksonXmlProperty(localName = "virAttr") + @Override + public Set getVirAttrs() { + return virAttrs; + } + + @JsonIgnore + @Override + public Optional getVirAttr(final String schema) { + return Optional.empty(); + } + @JacksonXmlElementWrapper(localName = "actions") @JacksonXmlProperty(localName = "action") public List getActions() { @@ -177,12 +237,15 @@ public boolean equals(final Object obj) { append(name, other.name). append(parent, other.parent). append(fullPath, other.fullPath). + append(anyTypeClass, other.anyTypeClass). append(accountPolicy, other.accountPolicy). append(passwordPolicy, other.passwordPolicy). append(authPolicy, other.authPolicy). append(accessPolicy, other.accessPolicy). append(attrReleasePolicy, other.attrReleasePolicy). append(ticketExpirationPolicy, other.ticketExpirationPolicy). + append(plainAttrs, other.plainAttrs). + append(derAttrs, other.derAttrs). append(actions, other.actions). append(templates, other.templates). append(resources, other.resources). @@ -196,12 +259,15 @@ public int hashCode() { append(name). append(parent). append(fullPath). + append(anyTypeClass). append(accountPolicy). append(passwordPolicy). append(authPolicy). append(accessPolicy). append(attrReleasePolicy). append(ticketExpirationPolicy). + append(plainAttrs). + append(derAttrs). append(actions). append(templates). append(resources). diff --git a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SchemaService.java b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SchemaService.java index 7b188a29362..3459c27c732 100644 --- a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SchemaService.java +++ b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SchemaService.java @@ -43,6 +43,7 @@ import java.util.List; import org.apache.syncope.common.lib.Attr; import org.apache.syncope.common.lib.to.AnyTO; +import org.apache.syncope.common.lib.to.RealmTO; import org.apache.syncope.common.lib.to.SchemaTO; import org.apache.syncope.common.lib.types.SchemaType; import org.apache.syncope.common.rest.api.RESTHeaders; @@ -137,8 +138,14 @@ T read( void delete(@NotNull @PathParam("type") SchemaType type, @NotNull @PathParam("key") String key); @POST - @Path("PLAIN/{key}/dropdownValues") + @Path("PLAIN/any/{key}/dropdownValues") @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) Attr getDropdownValues(@NotNull @PathParam("key") String key, @NotNull AnyTO anyTO); + + @POST + @Path("PLAIN/realm/{key}/dropdownValues") + @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) + Attr getDropdownValues(@NotNull @PathParam("key") String key, @NotNull RealmTO realmTO); } diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RealmLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RealmLogic.java index e2f6822cfa3..1d38e6f6253 100644 --- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RealmLogic.java +++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/RealmLogic.java @@ -47,6 +47,7 @@ import org.apache.syncope.core.persistence.api.dao.search.AnyCond; import org.apache.syncope.core.persistence.api.dao.search.AttrCond; import org.apache.syncope.core.persistence.api.dao.search.SearchCond; +import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.persistence.api.search.SyncopePage; @@ -178,7 +179,9 @@ public ProvisioningResult create(final String parentPath, final RealmTO Realm realm = realmDAO.save(binder.create(parent, realmTO)); PropagationByResource propByRes = new PropagationByResource<>(); - propByRes.addAll(ResourceOperation.CREATE, realm.getResourceKeys()); + propByRes.addAll( + ResourceOperation.CREATE, + realm.getResources().stream().map(ExternalResource::getKey).toList()); List taskInfos = propagationManager.createTasks(realm, propByRes, null); PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, false, AuthContextUtils.getUsername()); @@ -249,7 +252,9 @@ public ProvisioningResult delete(final String fullPath) { } PropagationByResource propByRes = new PropagationByResource<>(); - propByRes.addAll(ResourceOperation.DELETE, realm.getResourceKeys()); + propByRes.addAll( + ResourceOperation.DELETE, + realm.getResources().stream().map(ExternalResource::getKey).toList()); List taskInfos = propagationManager.createTasks(realm, propByRes, null); PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, false, AuthContextUtils.getUsername()); diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java index f6cbc67caaf..569cdcab67f 100644 --- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java +++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java @@ -28,7 +28,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.syncope.common.lib.Attr; import org.apache.syncope.common.lib.SyncopeClientException; -import org.apache.syncope.common.lib.to.AnyTO; +import org.apache.syncope.common.lib.to.AttributableTO; import org.apache.syncope.common.lib.to.DerSchemaTO; import org.apache.syncope.common.lib.to.PlainSchemaTO; import org.apache.syncope.common.lib.to.SchemaTO; @@ -254,7 +254,7 @@ public void update(final SchemaType schemaType, final T sch } @PreAuthorize("isAuthenticated()") - public Attr getDropdownValues(final String key, final AnyTO anyTO) { + public Attr getDropdownValues(final String key, final AttributableTO attributableTO) { PlainSchema schema = plainSchemaDAO.findById(key). filter(s -> s.getType() == AttrSchemaType.Dropdown). orElseThrow(() -> new NotFoundException(AttrSchemaType.Dropdown.name() + " PlainSchema " + key)); @@ -265,7 +265,7 @@ public Attr getDropdownValues(final String key, final AnyTO anyTO) { () -> perContextDropdownValueProviders.get(schema.getDropdownValueProvider().getKey()), instance -> perContextDropdownValueProviders.put( schema.getDropdownValueProvider().getKey(), instance)); - return new Attr.Builder(schema.getKey()).values(provider.getChoices(anyTO)).build(); + return new Attr.Builder(schema.getKey()).values(provider.getChoices(attributableTO)).build(); } catch (Exception e) { LOG.error("While getting dropdown values for {}", key, e); diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SchemaServiceImpl.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SchemaServiceImpl.java index 0fa02c1ab37..bdf75d9ba87 100644 --- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SchemaServiceImpl.java +++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SchemaServiceImpl.java @@ -23,6 +23,7 @@ import java.util.List; import org.apache.syncope.common.lib.Attr; import org.apache.syncope.common.lib.to.AnyTO; +import org.apache.syncope.common.lib.to.RealmTO; import org.apache.syncope.common.lib.to.SchemaTO; import org.apache.syncope.common.lib.types.SchemaType; import org.apache.syncope.common.rest.api.RESTHeaders; @@ -74,4 +75,9 @@ public void update(final SchemaType schemaType, final SchemaTO schemaTO) { public Attr getDropdownValues(final String key, final AnyTO anyTO) { return logic.getDropdownValues(key, anyTO); } + + @Override + public Attr getDropdownValues(final String key, final RealmTO realmTO) { + return logic.getDropdownValues(key, realmTO); + } } diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/attrvalue/DropdownValueProvider.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/attrvalue/DropdownValueProvider.java index 069dd04a441..76fe7976d0f 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/attrvalue/DropdownValueProvider.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/attrvalue/DropdownValueProvider.java @@ -19,10 +19,10 @@ package org.apache.syncope.core.persistence.api.attrvalue; import java.util.List; -import org.apache.syncope.common.lib.to.AnyTO; +import org.apache.syncope.common.lib.to.AttributableTO; @FunctionalInterface public interface DropdownValueProvider { - List getChoices(AnyTO anyTO); + List getChoices(AttributableTO attributableTO); } diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainSchemaDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainSchemaDAO.java index 3663e451eb9..4be25dd5756 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainSchemaDAO.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainSchemaDAO.java @@ -28,6 +28,8 @@ public interface PlainSchemaDAO extends SchemaDAO { boolean hasAttrs(PlainSchema schema); + boolean existsPlainAttrUniqueValue(String realmKey, PlainSchema schema, PlainAttrValue attrValue); + boolean existsPlainAttrUniqueValue(AnyUtils anyUtils, String anyKey, PlainSchema schema, PlainAttrValue attrValue); List findByValidator(Implementation validator); diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/EntityFactory.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/EntityFactory.java index e1ceac796e8..f44c9547dab 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/EntityFactory.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/EntityFactory.java @@ -33,5 +33,7 @@ public interface EntityFactory { Class anyObjectClass(); + Class realmClass(); + Class anySearchDAOClass(); } diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Realm.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Realm.java index d513688fd1a..c512c8b2a85 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Realm.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Realm.java @@ -27,7 +27,7 @@ import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy; import org.apache.syncope.core.persistence.api.entity.policy.TicketExpirationPolicy; -public interface Realm extends Entity { +public interface Realm extends Attributable { String getName(); @@ -39,6 +39,10 @@ public interface Realm extends Entity { String getFullPath(); + AnyTypeClass getAnyTypeClass(); + + void setAnyTypeClass(AnyTypeClass anyTypeClass); + AccountPolicy getAccountPolicy(); void setAccountPolicy(AccountPolicy accountPolicy); @@ -75,8 +79,6 @@ public interface Realm extends Entity { boolean add(ExternalResource resource); - List getResourceKeys(); - List getResources(); } diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/utils/RealmUtils.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/utils/RealmUtils.java index fe5f8913546..5eefc9d2235 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/utils/RealmUtils.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/utils/RealmUtils.java @@ -18,16 +18,23 @@ */ package org.apache.syncope.core.persistence.api.utils; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; +import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; +import org.apache.commons.lang3.ClassUtils; import org.apache.commons.lang3.tuple.Pair; import org.apache.syncope.common.lib.SyncopeConstants; +import org.apache.syncope.core.persistence.api.entity.EntityFactory; -public final class RealmUtils { +public class RealmUtils { public static String getGroupOwnerRealm(final String realmPath, final String groupKey) { return realmPath + '@' + groupKey; @@ -113,7 +120,32 @@ public static Set getEffective(final Set allowedRealms, final St return effective; } - private RealmUtils() { - // empty constructor for static utility class + protected static void initFieldNames(final Class entityClass, final Map fields) { + List> classes = ClassUtils.getAllSuperclasses(entityClass); + classes.add(entityClass); + classes.forEach(clazz -> { + for (Field field : clazz.getDeclaredFields()) { + if (!Modifier.isStatic(field.getModifiers()) + && !field.getName().startsWith("pc") + && !Collection.class.isAssignableFrom(field.getType()) + && !Map.class.isAssignableFrom(field.getType())) { + + fields.put(field.getName(), field); + if ("id".equals(field.getName())) { + fields.put("key", field); + } + } + } + }); + } + + protected final Map fields = new HashMap<>(); + + public RealmUtils(final EntityFactory entityFactory) { + initFieldNames(entityFactory.realmClass(), fields); + } + + public Optional getField(final String name) { + return Optional.ofNullable(fields.get(name)); } } diff --git a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/CommonPersistenceContext.java b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/CommonPersistenceContext.java index 19635c5220b..5c697266861 100644 --- a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/CommonPersistenceContext.java +++ b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/CommonPersistenceContext.java @@ -32,6 +32,7 @@ import org.apache.syncope.core.persistence.api.entity.am.ClientAppUtilsFactory; import org.apache.syncope.core.persistence.api.entity.policy.PolicyUtilsFactory; import org.apache.syncope.core.persistence.api.search.SearchCondVisitor; +import org.apache.syncope.core.persistence.api.utils.RealmUtils; import org.apache.syncope.core.persistence.common.attrvalue.DefaultPlainAttrValidationManager; import org.apache.syncope.core.persistence.common.content.KeymasterConfParamLoader; import org.apache.syncope.core.persistence.common.entity.DefaultAnyUtils; @@ -138,6 +139,12 @@ public AnyUtilsFactory anyUtilsFactory( return new AnyUtilsFactory(userAnyUtils, groupAnyUtils, anyObjectAnyUtils); } + @ConditionalOnMissingBean + @Bean + public RealmUtils realmUtils(final @Lazy EntityFactory entityFactory) { + return new RealmUtils(entityFactory); + } + @ConditionalOnMissingBean @Bean public KeymasterConfParamLoader keymasterConfParamLoader(final ConfParamOps confParamOps) { diff --git a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/RealmValidator.java b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/RealmValidator.java index 212d5df5609..ffeec056250 100644 --- a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/RealmValidator.java +++ b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/RealmValidator.java @@ -19,9 +19,13 @@ package org.apache.syncope.core.persistence.common.validation; import jakarta.validation.ConstraintValidatorContext; +import java.util.List; +import java.util.Optional; import org.apache.syncope.common.lib.SyncopeConstants; import org.apache.syncope.common.lib.types.EntityViolationType; import org.apache.syncope.core.persistence.api.dao.RealmDAO; +import org.apache.syncope.core.persistence.api.entity.PlainAttr; +import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.Realm; public class RealmValidator extends AbstractValidator { @@ -58,6 +62,23 @@ public boolean isValid(final Realm realm, final ConstraintValidatorContext conte } } + if (realm.getAnyTypeClass() != null) { + List allowedPlainSchemas = Optional.ofNullable(realm.getAnyTypeClass()). + map(atc -> atc.getPlainSchemas().stream().map(PlainSchema::getKey).toList()). + orElseGet(() -> List.of()); + for (PlainAttr attr : realm.getPlainAttrs()) { + String plainSchema = Optional.ofNullable(attr).map(PlainAttr::getSchema).orElse(null); + if (plainSchema != null && !allowedPlainSchemas.contains(plainSchema)) { + isValid = false; + + context.buildConstraintViolationWithTemplate( + getTemplate(EntityViolationType.InvalidPlainAttr, + plainSchema + " not allowed for this instance")). + addPropertyNode("plainAttrs").addConstraintViolation(); + } + } + } + return isValid; } } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java index 9e6fa5239dc..be7dce4965e 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java @@ -792,10 +792,11 @@ public PolicyDAO policyDAO( public RealmDAO realmDAO( final @Lazy RoleDAO roleDAO, final RealmSearchDAO realmSearchDAO, + final PlainSchemaDAO plainSchemaDAO, final ApplicationEventPublisher publisher, final EntityManager entityManager) { - return new JPARealmDAO(roleDAO, realmSearchDAO, publisher, entityManager); + return new JPARealmDAO(roleDAO, realmSearchDAO, plainSchemaDAO, publisher, entityManager); } @ConditionalOnMissingBean diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java index a1662fb4830..8350091cd3f 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java @@ -27,6 +27,9 @@ import java.util.Optional; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.common.lib.SyncopeConstants; +import org.apache.syncope.core.persistence.api.dao.DuplicateException; +import org.apache.syncope.core.persistence.api.dao.NotFoundException; +import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.dao.RealmDAO; import org.apache.syncope.core.persistence.api.dao.RealmSearchDAO; import org.apache.syncope.core.persistence.api.dao.RoleDAO; @@ -62,6 +65,8 @@ public class JPARealmDAO implements RealmDAO { protected final RealmSearchDAO realmSearchDAO; + protected final PlainSchemaDAO plainSchemaDAO; + protected final ApplicationEventPublisher publisher; protected final EntityManager entityManager; @@ -69,11 +74,13 @@ public class JPARealmDAO implements RealmDAO { public JPARealmDAO( final RoleDAO roleDAO, final RealmSearchDAO realmSearchDAO, + final PlainSchemaDAO plainSchemaDAO, final ApplicationEventPublisher publisher, final EntityManager entityManager) { this.roleDAO = roleDAO; this.realmSearchDAO = realmSearchDAO; + this.plainSchemaDAO = plainSchemaDAO; this.publisher = publisher; this.entityManager = entityManager; } @@ -203,6 +210,24 @@ public Page findAll(final Pageable pageable) { @Override public S save(final S realm) { + // check UNIQUE constraints + new ArrayList<>(((JPARealm) realm).getPlainAttrsList()).stream(). + filter(attr -> attr.getUniqueValue() != null). + forEach(attr -> { + if (plainSchemaDAO.existsPlainAttrUniqueValue( + realm.getKey(), + plainSchemaDAO.findById(attr.getSchema()). + orElseThrow(() -> new NotFoundException("PlainSchema " + attr.getSchema())), + attr.getUniqueValue())) { + + throw new DuplicateException("Duplicate value found for " + + attr.getSchema() + "=" + attr.getUniqueValue().getValueAsString()); + } else { + LOG.debug("No duplicate value found for {}={}", + attr.getSchema(), attr.getUniqueValue().getValueAsString()); + } + }); + String fullPathBefore = realm.getFullPath(); String fullPathAfter = realm.getParent() == null ? SyncopeConstants.ROOT_REALM @@ -213,6 +238,9 @@ public S save(final S realm) { S merged = entityManager.merge(realm); + // ensure that entity listeners are invoked at this point + entityManager.flush(); + if (!fullPathAfter.equals(fullPathBefore)) { realmSearchDAO.findChildren(realm).forEach(this::save); } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AbstractPlainSchemaRepoExt.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AbstractPlainSchemaRepoExt.java index bb42a2b7c43..fab37b2ab86 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AbstractPlainSchemaRepoExt.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AbstractPlainSchemaRepoExt.java @@ -28,6 +28,7 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.jpa.entity.AbstractSchema; import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema; +import org.apache.syncope.core.persistence.jpa.entity.JPARealm; import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject; import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup; import org.apache.syncope.core.persistence.jpa.entity.user.JPALinkedAccount; @@ -36,7 +37,7 @@ abstract class AbstractPlainSchemaRepoExt extends AbstractSchemaRepoExt implements PlainSchemaRepoExt { protected static final List TABLES = List.of( - JPAUser.TABLE, JPAGroup.TABLE, JPAAnyObject.TABLE, JPALinkedAccount.TABLE); + JPAUser.TABLE, JPAGroup.TABLE, JPAAnyObject.TABLE, JPALinkedAccount.TABLE, JPARealm.TABLE); protected final AnyUtilsFactory anyUtilsFactory; diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/MariaDBPlainSchemaRepoExtImpl.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/MariaDBPlainSchemaRepoExtImpl.java index 3441f58c109..cd8cb605ba1 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/MariaDBPlainSchemaRepoExtImpl.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/MariaDBPlainSchemaRepoExtImpl.java @@ -29,6 +29,7 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.jpa.dao.SearchSupport; +import org.apache.syncope.core.persistence.jpa.entity.JPARealm; import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; public class MariaDBPlainSchemaRepoExtImpl extends AbstractPlainSchemaRepoExt { @@ -55,6 +56,25 @@ public boolean hasAttrs(final PlainSchema schema) { return ((Number) query.getSingleResult()).intValue() > 0; } + @Override + public boolean existsPlainAttrUniqueValue( + final String realmKey, + final PlainSchema schema, + final PlainAttrValue attrValue) { + + PlainAttr attr = new PlainAttr(); + attr.setSchema(schema.getKey()); + attr.setUniqueValue(attrValue); + + Query query = entityManager.createNativeQuery( + "SELECT COUNT(id) FROM " + JPARealm.TABLE + + " WHERE JSON_CONTAINS(plainAttrs, '" + POJOHelper.serialize(List.of(attr)).replace("'", "''") + "')" + + " AND id <> ?1"); + query.setParameter(1, realmKey); + + return ((Number) query.getSingleResult()).intValue() > 0; + } + @Override public boolean existsPlainAttrUniqueValue( final AnyUtils anyUtils, diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/MySQLPlainSchemaRepoExtImpl.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/MySQLPlainSchemaRepoExtImpl.java index 25c09fe95f1..610d494b9de 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/MySQLPlainSchemaRepoExtImpl.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/MySQLPlainSchemaRepoExtImpl.java @@ -29,6 +29,7 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.jpa.dao.SearchSupport; +import org.apache.syncope.core.persistence.jpa.entity.JPARealm; import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; public class MySQLPlainSchemaRepoExtImpl extends AbstractPlainSchemaRepoExt { @@ -55,6 +56,25 @@ public boolean hasAttrs(final PlainSchema schema) { return ((Number) query.getSingleResult()).intValue() > 0; } + @Override + public boolean existsPlainAttrUniqueValue( + final String realmKey, + final PlainSchema schema, + final PlainAttrValue attrValue) { + + PlainAttr attr = new PlainAttr(); + attr.setSchema(schema.getKey()); + attr.setUniqueValue(attrValue); + + Query query = entityManager.createNativeQuery( + "SELECT COUNT(id) FROM " + JPARealm.TABLE + + " WHERE JSON_CONTAINS(plainAttrs, '" + POJOHelper.serialize(List.of(attr)).replace("'", "''") + "')" + + " AND id <> ?1"); + query.setParameter(1, realmKey); + + return ((Number) query.getSingleResult()).intValue() > 0; + } + @Override public boolean existsPlainAttrUniqueValue( final AnyUtils anyUtils, diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java index b15fa90c6fb..20c6c53bed6 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java @@ -30,6 +30,7 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.jpa.dao.OracleJPAAnySearchDAO; import org.apache.syncope.core.persistence.jpa.dao.SearchSupport; +import org.apache.syncope.core.persistence.jpa.entity.JPARealm; public class OraclePlainSchemaRepoExtImpl extends AbstractPlainSchemaRepoExt { @@ -59,6 +60,24 @@ public boolean hasAttrs(final PlainSchema schema) { return ((Number) query.getSingleResult()).intValue() > 0; } + @Override + public boolean existsPlainAttrUniqueValue( + final String realmKey, + final PlainSchema schema, + final PlainAttrValue attrValue) { + + Query query = entityManager.createNativeQuery( + "SELECT COUNT(id) FROM " + + JPARealm.TABLE + "," + + OracleJPAAnySearchDAO.from(plainSchemaDAO.findById(schema.getKey()). + orElseThrow(() -> new NotFoundException("PlainSchema " + schema.getKey()))) + + " WHERE " + schema.getKey() + ".uniqueValue=?1 AND id <> ?2"); + query.setParameter(1, attrValue.getValue()); + query.setParameter(2, realmKey); + + return ((Number) query.getSingleResult()).intValue() > 0; + } + @Override public boolean existsPlainAttrUniqueValue( final AnyUtils anyUtils, diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PGPlainSchemaRepoExtImpl.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PGPlainSchemaRepoExtImpl.java index ff0968ef5f5..3198c31431a 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PGPlainSchemaRepoExtImpl.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PGPlainSchemaRepoExtImpl.java @@ -29,6 +29,7 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.jpa.dao.SearchSupport; +import org.apache.syncope.core.persistence.jpa.entity.JPARealm; import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; public class PGPlainSchemaRepoExtImpl extends AbstractPlainSchemaRepoExt { @@ -55,6 +56,25 @@ public boolean hasAttrs(final PlainSchema schema) { return ((Number) query.getSingleResult()).intValue() > 0; } + @Override + public boolean existsPlainAttrUniqueValue( + final String realmKey, + final PlainSchema schema, + final PlainAttrValue attrValue) { + + PlainAttr attr = new PlainAttr(); + attr.setSchema(schema.getKey()); + attr.setUniqueValue(attrValue); + + Query query = entityManager.createNativeQuery( + "SELECT COUNT(id) FROM " + JPARealm.TABLE + + " WHERE plainAttrs::jsonb @> '" + POJOHelper.serialize(List.of(attr)).replace("'", "''") + "'::jsonb" + + " AND id <> ?1"); + query.setParameter(1, realmKey); + + return ((Number) query.getSingleResult()).intValue() > 0; + } + @Override public boolean existsPlainAttrUniqueValue( final AnyUtils anyUtils, diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PlainSchemaRepoExt.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PlainSchemaRepoExt.java index 0a04edf3173..e2bcb19a5ed 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PlainSchemaRepoExt.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PlainSchemaRepoExt.java @@ -31,6 +31,8 @@ public interface PlainSchemaRepoExt { boolean hasAttrs(PlainSchema schema); + boolean existsPlainAttrUniqueValue(String realmKey, PlainSchema schema, PlainAttrValue attrValue); + boolean existsPlainAttrUniqueValue(AnyUtils anyUtils, String anyKey, PlainSchema schema, PlainAttrValue attrValue); PlainSchema save(PlainSchema schema); diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntityFactory.java index bac6730fe45..2a293bd46ae 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntityFactory.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntityFactory.java @@ -326,4 +326,9 @@ public Class groupClass() { public Class anyObjectClass() { return JPAAnyObject.class; } + + @Override + public Class realmClass() { + return JPARealm.class; + } } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java index 0f4c84758b6..8d55a6ca63c 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java @@ -22,6 +22,7 @@ import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.EntityListeners; import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; import jakarta.persistence.JoinTable; @@ -29,6 +30,7 @@ import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; import jakarta.persistence.Table; +import jakarta.persistence.Transient; import jakarta.persistence.UniqueConstraint; import jakarta.validation.constraints.Size; import java.util.ArrayList; @@ -37,8 +39,10 @@ import org.apache.syncope.common.lib.types.IdRepoImplementationType; import org.apache.syncope.core.persistence.api.entity.AnyTemplateRealm; import org.apache.syncope.core.persistence.api.entity.AnyType; +import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.Implementation; +import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy; import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy; @@ -57,9 +61,10 @@ @Entity @Table(name = JPARealm.TABLE, uniqueConstraints = @UniqueConstraint(columnNames = { "name", "parent_id" })) +@EntityListeners({ JSONRealmListener.class }) @Cacheable @RealmCheck -public class JPARealm extends AbstractGeneratedKeyEntity implements Realm { +public class JPARealm extends AbstractAttributable implements Realm { private static final long serialVersionUID = 5533247460239909964L; @@ -74,6 +79,14 @@ public class JPARealm extends AbstractGeneratedKeyEntity implements Realm { @Column(nullable = false, unique = true) private String fullPath; + private String plainAttrs; + + @Transient + private final List plainAttrsList = new ArrayList<>(); + + @ManyToOne(fetch = FetchType.EAGER) + private JPAAnyTypeClass anyTypeClass; + @ManyToOne(fetch = FetchType.EAGER) private JPAPasswordPolicy passwordPolicy; @@ -119,39 +132,82 @@ public String getName() { return name; } + @Override + public void setName(final String name) { + this.name = name; + } + @Override public Realm getParent() { return parent; } + @Override + public void setParent(final Realm parent) { + checkType(parent, JPARealm.class); + this.parent = (JPARealm) parent; + } + @Override public String getFullPath() { return fullPath; } + public void setFullPath(final String fullPath) { + this.fullPath = fullPath; + } + @Override - public AccountPolicy getAccountPolicy() { - return accountPolicy == null && getParent() != null ? getParent().getAccountPolicy() : accountPolicy; + public List getPlainAttrsList() { + return plainAttrsList; } @Override - public PasswordPolicy getPasswordPolicy() { - return passwordPolicy == null && getParent() != null ? getParent().getPasswordPolicy() : passwordPolicy; + public String getPlainAttrsJSON() { + return plainAttrs; } @Override - public void setName(final String name) { - this.name = name; + public void setPlainAttrsJSON(final String plainAttrs) { + this.plainAttrs = plainAttrs; } @Override - public void setParent(final Realm parent) { - checkType(parent, JPARealm.class); - this.parent = (JPARealm) parent; + public boolean add(final PlainAttr attr) { + return plainAttrsList.add(attr); } - public void setFullPath(final String fullPath) { - this.fullPath = fullPath; + @Override + public boolean remove(final PlainAttr attr) { + return plainAttrsList.removeIf(a -> a.getSchema().equals(attr.getSchema())); + } + + @Override + public Optional getPlainAttr(final String plainSchema) { + return plainAttrsList.stream(). + filter(attr -> plainSchema.equals(attr.getSchema())). + findFirst(); + } + + @Override + public List getPlainAttrs() { + return plainAttrsList.stream().toList(); + } + + @Override + public AnyTypeClass getAnyTypeClass() { + return anyTypeClass; + } + + @Override + public void setAnyTypeClass(final AnyTypeClass anyTypeClass) { + checkType(anyTypeClass, JPAAnyTypeClass.class); + this.anyTypeClass = (JPAAnyTypeClass) anyTypeClass; + } + + @Override + public AccountPolicy getAccountPolicy() { + return accountPolicy == null && getParent() != null ? getParent().getAccountPolicy() : accountPolicy; } @Override @@ -160,6 +216,11 @@ public void setAccountPolicy(final AccountPolicy accountPolicy) { this.accountPolicy = (JPAAccountPolicy) accountPolicy; } + @Override + public PasswordPolicy getPasswordPolicy() { + return passwordPolicy == null && getParent() != null ? getParent().getPasswordPolicy() : passwordPolicy; + } + @Override public void setPasswordPolicy(final PasswordPolicy passwordPolicy) { checkType(passwordPolicy, JPAPasswordPolicy.class); @@ -188,6 +249,28 @@ public void setAccessPolicy(final AccessPolicy accessPolicy) { this.accessPolicy = (JPAAccessPolicy) accessPolicy; } + @Override + public AttrReleasePolicy getAttrReleasePolicy() { + return this.attrReleasePolicy; + } + + @Override + public void setAttrReleasePolicy(final AttrReleasePolicy policy) { + checkType(policy, JPAAttrReleasePolicy.class); + this.attrReleasePolicy = (JPAAttrReleasePolicy) policy; + } + + @Override + public TicketExpirationPolicy getTicketExpirationPolicy() { + return this.ticketExpirationPolicy; + } + + @Override + public void setTicketExpirationPolicy(final TicketExpirationPolicy policy) { + checkType(policy, JPATicketExpirationPolicy.class); + this.ticketExpirationPolicy = (JPATicketExpirationPolicy) policy; + } + @Override public boolean add(final Implementation action) { checkType(action, JPAImplementation.class); @@ -218,39 +301,12 @@ public List getTemplates() { return templates; } - @Override - public void setAttrReleasePolicy(final AttrReleasePolicy policy) { - checkType(policy, JPAAttrReleasePolicy.class); - this.attrReleasePolicy = (JPAAttrReleasePolicy) policy; - } - - @Override - public AttrReleasePolicy getAttrReleasePolicy() { - return this.attrReleasePolicy; - } - - @Override - public TicketExpirationPolicy getTicketExpirationPolicy() { - return this.ticketExpirationPolicy; - } - - @Override - public void setTicketExpirationPolicy(final TicketExpirationPolicy policy) { - checkType(policy, JPATicketExpirationPolicy.class); - this.ticketExpirationPolicy = (JPATicketExpirationPolicy) policy; - } - @Override public boolean add(final ExternalResource resource) { checkType(resource, JPAExternalResource.class); return resources.contains((JPAExternalResource) resource) || resources.add((JPAExternalResource) resource); } - @Override - public List getResourceKeys() { - return getResources().stream().map(ExternalResource::getKey).toList(); - } - @Override public List getResources() { return resources; diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JSONEntityListener.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JSONEntityListener.java index 67febd92b38..e3b980405de 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JSONEntityListener.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JSONEntityListener.java @@ -21,11 +21,11 @@ import com.fasterxml.jackson.core.type.TypeReference; import java.util.List; import java.util.Optional; -import org.apache.syncope.core.persistence.api.entity.Any; +import org.apache.syncope.core.persistence.api.entity.Attributable; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; -public abstract class JSONEntityListener { +public abstract class JSONEntityListener { protected static final TypeReference> TYPEREF = new TypeReference>() { }; diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JSONRealmListener.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JSONRealmListener.java new file mode 100644 index 00000000000..5afda772f44 --- /dev/null +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JSONRealmListener.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.persistence.jpa.entity; + +import jakarta.persistence.PostLoad; +import jakarta.persistence.PostPersist; +import jakarta.persistence.PostUpdate; +import jakarta.persistence.PrePersist; +import jakarta.persistence.PreUpdate; +import org.apache.syncope.core.persistence.api.entity.Realm; + +public class JSONRealmListener extends JSONEntityListener { + + @PostLoad + public void read(final JPARealm realm) { + super.json2list(realm, false); + } + + @PrePersist + @PreUpdate + public void save(final JPARealm realm) { + realm.list2json(); + } + + @PostPersist + @PostUpdate + public void readAfterSave(final JPARealm realm) { + super.json2list(realm, true); + } +} diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java index 73428bb16d0..47057eede69 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java @@ -24,6 +24,7 @@ import io.zonky.test.db.postgres.embedded.EmbeddedPostgres; import jakarta.persistence.EntityManager; import java.io.InputStream; +import java.time.Duration; import java.util.Map; import java.util.Properties; import java.util.function.Supplier; @@ -179,13 +180,13 @@ private static boolean classExists(final String name) { OracleContainer masterDomain = new OracleContainer("gvenzl/oracle-free:" + dockerOracleVersion). withDatabaseName("syncope").withPassword("syncope").withUsername("syncope"). - withReuse(true); + withReuse(true).withStartupTimeout(Duration.ofMinutes(4)); masterDomain.start(); JDBC_URL_SUPPLIER = masterDomain::getJdbcUrl; OracleContainer twoDomain = new OracleContainer("gvenzl/oracle-free:" + dockerOracleVersion). withDatabaseName("syncope").withPassword("syncope").withUsername("syncope"). - withReuse(true); + withReuse(true).withStartupTimeout(Duration.ofMinutes(4)); twoDomain.start(); JDBC2_URL_SUPPLIER = twoDomain::getJdbcUrl; } diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java index d93d0badd24..fbf58712d5b 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java @@ -234,7 +234,7 @@ public void delete() { * signature: required for avoiding creating of a new transaction - good for general use case but bad for the way * how this test class is architected. */ - public List findDynGroups(final User user) { + private List findDynGroups(final User user) { Query query = entityManager.createNativeQuery( "SELECT group_id FROM " + GroupRepoExt.UDYNMEMB_TABLE + " WHERE any_id=?"); query.setParameter(1, user.getKey()); @@ -325,7 +325,7 @@ public void udynMembership() { * signature: required for avoiding creating of a new transaction - good for general use case but bad for the way * how this test class is architected. */ - public List findDynGroups(final AnyObject anyObject) { + private List findDynGroups(final AnyObject anyObject) { Query query = entityManager.createNativeQuery( "SELECT group_id FROM " + GroupRepoExt.ADYNMEMB_TABLE + " WHERE any_id=?"); query.setParameter(1, anyObject.getKey()); diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RealmTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RealmTest.java index 2fa10d3e1eb..fac6a2d8296 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RealmTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RealmTest.java @@ -19,12 +19,16 @@ package org.apache.syncope.core.persistence.jpa.outer; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValidationManager; +import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; import org.apache.syncope.core.persistence.api.dao.RealmDAO; import org.apache.syncope.core.persistence.api.dao.RealmSearchDAO; import org.apache.syncope.core.persistence.api.dao.RoleDAO; +import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.Role; import org.apache.syncope.core.persistence.api.entity.group.Group; @@ -36,6 +40,9 @@ @Transactional public class RealmTest extends AbstractTest { + @Autowired + private AnyTypeClassDAO anyTypeClassDAO; + @Autowired private RealmDAO realmDAO; @@ -48,8 +55,38 @@ public class RealmTest extends AbstractTest { @Autowired private GroupDAO groupDAO; + @Autowired + private PlainAttrValidationManager validator; + + @Test + public void plainAttrs() { + Realm realm = realmSearchDAO.findByFullPath("/odd").orElseThrow(); + assertNull(realm.getAnyTypeClass()); + assertTrue(realm.getPlainAttrs().isEmpty()); + + realm.setAnyTypeClass(anyTypeClassDAO.findById("other").orElseThrow()); + realm = realmDAO.save(realm); + entityManager.flush(); + + realm = realmDAO.findById(realm.getKey()).orElseThrow(); + assertEquals(anyTypeClassDAO.findById("other").orElseThrow(), realm.getAnyTypeClass()); + + PlainAttr aLong = new PlainAttr(); + aLong.setSchema("aLong"); + aLong.add(validator, "9"); + realm.add(aLong); + + realm = realmDAO.save(realm); + entityManager.flush(); + + realm = realmDAO.findById(realm.getKey()).orElseThrow(); + assertEquals(anyTypeClassDAO.findById("other").orElseThrow(), realm.getAnyTypeClass()); + assertEquals(1, realm.getPlainAttrs().size()); + assertEquals(9, realm.getPlainAttr("aLong").orElseThrow().getValues().get(0).getLongValue()); + } + @Test - public void test() { + public void delete() { Realm realm = realmSearchDAO.findByFullPath("/odd").orElseThrow(); // need to remove this group in order to remove the realm, which is otherwise empty diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml index 392493b0cf4..9dcd769b172 100644 --- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml +++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml @@ -165,7 +165,7 @@ under the License. mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0" enumValues='{"M":"Male","F":"Female"}'/> + body='import groovy.transform.CompileStatic import java.util.List import org.apache.syncope.common.lib.to.AttributableTO import org.apache.syncope.core.persistence.api.attrvalue.DropdownValueProvider @CompileStatic class TestDropdownValueProvider implements DropdownValueProvider { List<String> getChoices(AttributableTO attributableTO) { return ["A", "B"] } }'/> + orgUnit='{"objectClass":"organizationalUnit","syncToken":null,"ignoreCaseMatch":false,"connObjectLink":"syncope:fullPath2Dn(fullPath, 'ou') + ',${testds.rootDn}'","items":[{"intAttrName":"fullPath","extAttrName":"l","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"name","extAttrName":"ou","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"ctype","extAttrName":"description","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"fullpath","extAttrName":"l","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}'/> 0; } + @Override + public boolean existsPlainAttrUniqueValue( + final String realmKey, + final PlainSchema schema, + final PlainAttrValue attrValue) { + + String value = Optional.ofNullable(attrValue.getDateValue()). + map(DateTimeFormatter.ISO_OFFSET_DATE_TIME::format). + orElseGet(attrValue::getValueAsString); + + return neo4jTemplate.count( + "MATCH (n:" + Neo4jRealm.NODE + ") " + + "WITH n.id AS id, " + + "apoc.convert.getJsonProperty(n, 'plainAttrs." + schema.getKey() + "', '$.uniqueValue') " + + "AS " + schema.getKey() + " " + + "WHERE (EXISTS { MATCH (n) " + + "WHERE " + schema.getKey() + "." + Neo4jAnySearchDAO.key(schema.getType()) + + " = $value } " + + "AND EXISTS { MATCH (n) WHERE NOT (n.id = $realmKey) }) " + + "RETURN COUNT(id)", + Map.of("value", value, "realmKey", realmKey)) > 0; + } + @Override public boolean existsPlainAttrUniqueValue( final AnyUtils anyUtils, @@ -119,7 +143,7 @@ public boolean existsPlainAttrUniqueValue( String value = Optional.ofNullable(attrValue.getDateValue()). map(DateTimeFormatter.ISO_OFFSET_DATE_TIME::format). - orElseGet(attrValue::getValueAsString); + orElseGet(attrValue::getValueAsString); return neo4jTemplate.count( "MATCH (n:" + label + ") " diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractAny.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractAny.java index b5c7afe53de..2dc47fb1794 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractAny.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractAny.java @@ -20,17 +20,13 @@ import jakarta.validation.constraints.NotNull; import java.time.OffsetDateTime; -import java.util.Map; -import java.util.Optional; import org.apache.syncope.core.persistence.api.entity.Any; -import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.common.validation.AnyCheck; -import org.springframework.data.neo4j.core.schema.PostLoad; import org.springframework.data.neo4j.core.schema.Relationship; @AnyCheck -public abstract class AbstractAny extends AbstractGeneratedKeyNode implements Any { +public abstract class AbstractAny extends AbstractAttributable implements Any { private static final long serialVersionUID = -2666540708092702810L; @@ -153,32 +149,4 @@ public String getStatus() { public void setStatus(final String status) { this.status = status; } - - protected abstract Map plainAttrs(); - - @Override - public Optional getPlainAttr(final String plainSchema) { - return Optional.ofNullable(plainAttrs().get(plainSchema)); - } - - @SuppressWarnings("unchecked") - protected void doComplete(final Map plainAttrs) { - for (var itor = plainAttrs.entrySet().iterator(); itor.hasNext();) { - var entry = itor.next(); - Optional.ofNullable(entry.getValue()).ifPresent(attr -> { - attr.setSchema(entry.getKey()); - if (attr.getSchema() == null) { - itor.remove(); - } else { - attr.getValues().forEach(value -> value.setAttr(attr)); - Optional.ofNullable(attr.getUniqueValue()).ifPresent(value -> value.setAttr(attr)); - } - }); - } - } - - @PostLoad - public void completePlainAttrs() { - doComplete(plainAttrs()); - } } diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractAttributable.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractAttributable.java new file mode 100644 index 00000000000..9da6da7ecc8 --- /dev/null +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractAttributable.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.persistence.neo4j.entity; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.apache.syncope.core.persistence.api.entity.Attributable; +import org.apache.syncope.core.persistence.api.entity.PlainAttr; +import org.apache.syncope.core.persistence.common.validation.AttributableCheck; +import org.springframework.data.neo4j.core.schema.PostLoad; + +@AttributableCheck +public abstract class AbstractAttributable extends AbstractGeneratedKeyNode implements Attributable { + + private static final long serialVersionUID = 5653313070976526466L; + + protected abstract Map plainAttrs(); + + @Override + public boolean add(final PlainAttr attr) { + return plainAttrs().put(attr.getSchema(), attr) != null; + } + + @Override + public boolean remove(final PlainAttr attr) { + return plainAttrs().put(attr.getSchema(), null) != null; + } + + @Override + public List getPlainAttrs() { + return plainAttrs().entrySet().stream(). + filter(e -> e.getValue() != null). + sorted(Comparator.comparing(Map.Entry::getKey)). + map(Map.Entry::getValue).toList(); + } + + @Override + public Optional getPlainAttr(final String plainSchema) { + return Optional.ofNullable(plainAttrs().get(plainSchema)); + } + + protected void doComplete(final Map plainAttrs) { + for (var itor = plainAttrs.entrySet().iterator(); itor.hasNext();) { + var entry = itor.next(); + Optional.ofNullable(entry.getValue()).ifPresent(attr -> { + attr.setSchema(entry.getKey()); + if (attr.getSchema() == null) { + itor.remove(); + } else { + attr.getValues().forEach(value -> value.setAttr(attr)); + Optional.ofNullable(attr.getUniqueValue()).ifPresent(value -> value.setAttr(attr)); + } + }); + } + } + + @PostLoad + public void completePlainAttrs() { + doComplete(plainAttrs()); + } +} diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractGroupableRelatable.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractGroupableRelatable.java index bb0f95f07cb..8fbc5d9c03f 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractGroupableRelatable.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractGroupableRelatable.java @@ -19,9 +19,7 @@ package org.apache.syncope.core.persistence.neo4j.entity; import java.util.Collection; -import java.util.Comparator; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.stream.Stream; import org.apache.syncope.core.persistence.api.entity.Any; @@ -58,20 +56,10 @@ public Optional getPlainAttr(final String plainSchema, final Membersh flatMap(m -> m.getPlainAttr(plainSchema)); } - @SuppressWarnings("unchecked") - @Override - public List getPlainAttrs() { - return plainAttrs().entrySet().stream(). - filter(e -> e.getValue() != null). - sorted(Comparator.comparing(Map.Entry::getKey)). - map(Map.Entry::getValue).toList(); - } - @Override public Collection getPlainAttrs(final String plainSchema) { return Stream.concat(getPlainAttr(plainSchema).map(Stream::of).orElseGet(Stream::empty), - memberships().stream().map(m -> m.getPlainAttr(plainSchema)). - flatMap(Optional::stream)). + memberships().stream().map(m -> m.getPlainAttr(plainSchema)).flatMap(Optional::stream)). toList(); } diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jEntityFactory.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jEntityFactory.java index c589e8701db..88267f646c7 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jEntityFactory.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jEntityFactory.java @@ -328,6 +328,11 @@ public Class anyObjectClass() { return Neo4jAnyObject.class; } + @Override + public Class realmClass() { + return Neo4jRealm.class; + } + @Override public Class anySearchDAOClass() { return null; diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jRealm.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jRealm.java index 5fa19b1b5c3..67db399bedc 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jRealm.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jRealm.java @@ -21,15 +21,19 @@ import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.SortedSet; import java.util.TreeSet; import org.apache.syncope.common.lib.types.IdRepoImplementationType; import org.apache.syncope.core.persistence.api.entity.AnyTemplateRealm; import org.apache.syncope.core.persistence.api.entity.AnyType; +import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.Implementation; +import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy; import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy; @@ -45,13 +49,14 @@ import org.apache.syncope.core.persistence.neo4j.entity.policy.Neo4jPasswordPolicy; import org.apache.syncope.core.persistence.neo4j.entity.policy.Neo4jTicketExpirationPolicy; import org.springframework.data.annotation.Transient; +import org.springframework.data.neo4j.core.schema.CompositeProperty; import org.springframework.data.neo4j.core.schema.Node; import org.springframework.data.neo4j.core.schema.PostLoad; import org.springframework.data.neo4j.core.schema.Relationship; @Node(Neo4jRealm.NODE) @RealmCheck -public class Neo4jRealm extends AbstractGeneratedKeyNode implements Realm { +public class Neo4jRealm extends AbstractAttributable implements Realm { private static final long serialVersionUID = 1807304075247552949L; @@ -59,6 +64,8 @@ public class Neo4jRealm extends AbstractGeneratedKeyNode implements Realm { public static final String PARENT_REL = "PARENT"; + public static final String REALM_ANYTYPECLASS_REL = "REALM_ANYTYPECLASS"; + public static final String REALM_PASSWORD_POLICY_REL = "REALM_PASSWORD_POLICY"; public static final String REALM_ACCOUNT_POLICY_REL = "REALM_ACCOUNT_POLICY"; @@ -84,6 +91,12 @@ public class Neo4jRealm extends AbstractGeneratedKeyNode implements Realm { @NotNull private String fullPath; + @CompositeProperty(converterRef = "plainAttrsConverter") + protected Map plainAttrs = new HashMap<>(); + + @Relationship(type = REALM_ANYTYPECLASS_REL, direction = Relationship.Direction.OUTGOING) + private Neo4jAnyTypeClass anyTypeClass; + @Relationship(type = REALM_PASSWORD_POLICY_REL, direction = Relationship.Direction.OUTGOING) private Neo4jPasswordPolicy passwordPolicy; @@ -115,44 +128,55 @@ public class Neo4jRealm extends AbstractGeneratedKeyNode implements Realm { @Relationship(type = REALM_RESOURCE_REL, direction = Relationship.Direction.OUTGOING) private List resources = new ArrayList<>(); + @Override + protected Map plainAttrs() { + return plainAttrs; + } + @Override public String getName() { return name; } + @Override + public void setName(final String name) { + this.name = name; + } + @Override public Realm getParent() { return parent; } @Override - public String getFullPath() { - return fullPath; + public void setParent(final Realm parent) { + checkType(parent, Neo4jRealm.class); + this.parent = (Neo4jRealm) parent; } @Override - public AccountPolicy getAccountPolicy() { - return accountPolicy == null && getParent() != null ? getParent().getAccountPolicy() : accountPolicy; + public String getFullPath() { + return fullPath; } - @Override - public PasswordPolicy getPasswordPolicy() { - return passwordPolicy == null && getParent() != null ? getParent().getPasswordPolicy() : passwordPolicy; + public void setFullPath(final String fullPath) { + this.fullPath = fullPath; } @Override - public void setName(final String name) { - this.name = name; + public AnyTypeClass getAnyTypeClass() { + return anyTypeClass; } @Override - public void setParent(final Realm parent) { - checkType(parent, Neo4jRealm.class); - this.parent = (Neo4jRealm) parent; + public void setAnyTypeClass(final AnyTypeClass anyTypeClass) { + checkType(anyTypeClass, Neo4jAnyTypeClass.class); + this.anyTypeClass = (Neo4jAnyTypeClass) anyTypeClass; } - public void setFullPath(final String fullPath) { - this.fullPath = fullPath; + @Override + public AccountPolicy getAccountPolicy() { + return accountPolicy == null && getParent() != null ? getParent().getAccountPolicy() : accountPolicy; } @Override @@ -161,6 +185,11 @@ public void setAccountPolicy(final AccountPolicy accountPolicy) { this.accountPolicy = (Neo4jAccountPolicy) accountPolicy; } + @Override + public PasswordPolicy getPasswordPolicy() { + return passwordPolicy == null && getParent() != null ? getParent().getPasswordPolicy() : passwordPolicy; + } + @Override public void setPasswordPolicy(final PasswordPolicy passwordPolicy) { checkType(passwordPolicy, Neo4jPasswordPolicy.class); @@ -190,10 +219,8 @@ public void setAccessPolicy(final AccessPolicy accessPolicy) { } @Override - public boolean add(final Implementation action) { - checkType(action, Neo4jImplementation.class); - checkImplementationType(action, IdRepoImplementationType.LOGIC_ACTIONS); - return sortedActions.contains((Neo4jImplementation) action) || sortedActions.add((Neo4jImplementation) action); + public AttrReleasePolicy getAttrReleasePolicy() { + return this.attrReleasePolicy; } @Override @@ -202,11 +229,6 @@ public void setAttrReleasePolicy(final AttrReleasePolicy policy) { this.attrReleasePolicy = (Neo4jAttrReleasePolicy) policy; } - @Override - public AttrReleasePolicy getAttrReleasePolicy() { - return this.attrReleasePolicy; - } - @Override public TicketExpirationPolicy getTicketExpirationPolicy() { return this.ticketExpirationPolicy; @@ -218,6 +240,13 @@ public void setTicketExpirationPolicy(final TicketExpirationPolicy policy) { this.ticketExpirationPolicy = (Neo4jTicketExpirationPolicy) policy; } + @Override + public boolean add(final Implementation action) { + checkType(action, Neo4jImplementation.class); + checkImplementationType(action, IdRepoImplementationType.LOGIC_ACTIONS); + return sortedActions.contains((Neo4jImplementation) action) || sortedActions.add((Neo4jImplementation) action); + } + @Override public List getActions() { return sortedActions; @@ -247,11 +276,6 @@ public boolean add(final ExternalResource resource) { return resources.contains((Neo4jExternalResource) resource) || resources.add((Neo4jExternalResource) resource); } - @Override - public List getResourceKeys() { - return getResources().stream().map(ExternalResource::getKey).toList(); - } - @Override public List getResources() { return resources; diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGroup.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGroup.java index a013cbc608a..836654b39a1 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGroup.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGroup.java @@ -20,7 +20,6 @@ import jakarta.validation.constraints.NotNull; import java.util.ArrayList; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -162,24 +161,6 @@ public void setGroupOwner(final Group group) { this.groupOwner = (Neo4jGroup) group; } - @Override - public boolean add(final PlainAttr attr) { - return plainAttrs.put(attr.getSchema(), attr) != null; - } - - @Override - public boolean remove(final PlainAttr attr) { - return plainAttrs.put(attr.getSchema(), null) != null; - } - - @Override - public List getPlainAttrs() { - return plainAttrs.entrySet().stream(). - filter(e -> e.getValue() != null). - sorted(Comparator.comparing(Map.Entry::getKey)). - map(Map.Entry::getValue).toList(); - } - @Override public UDynGroupMembership getUDynMembership() { return uDynMembership; diff --git a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/outer/RealmTest.java b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/outer/RealmTest.java index 80ece40db03..acea10970ad 100644 --- a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/outer/RealmTest.java +++ b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/outer/RealmTest.java @@ -19,18 +19,21 @@ package org.apache.syncope.core.persistence.neo4j.outer; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.UUID; import org.apache.syncope.common.lib.types.IdRepoImplementationType; import org.apache.syncope.common.lib.types.ImplementationEngine; -import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; +import org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValidationManager; +import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; import org.apache.syncope.core.persistence.api.dao.ImplementationDAO; import org.apache.syncope.core.persistence.api.dao.RealmDAO; import org.apache.syncope.core.persistence.api.dao.RealmSearchDAO; import org.apache.syncope.core.persistence.api.dao.RoleDAO; import org.apache.syncope.core.persistence.api.entity.Implementation; +import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.Role; import org.apache.syncope.core.persistence.api.entity.group.Group; @@ -43,13 +46,13 @@ public class RealmTest extends AbstractTest { @Autowired - private RealmDAO realmDAO; + private AnyTypeClassDAO anyTypeClassDAO; @Autowired - private RealmSearchDAO realmSearchDAO; + private RealmDAO realmDAO; @Autowired - private ExternalResourceDAO resourceDAO; + private RealmSearchDAO realmSearchDAO; @Autowired private RoleDAO roleDAO; @@ -60,8 +63,36 @@ public class RealmTest extends AbstractTest { @Autowired private ImplementationDAO implementationDAO; + @Autowired + private PlainAttrValidationManager validator; + + @Test + public void plainAttrs() { + Realm realm = realmSearchDAO.findByFullPath("/odd").orElseThrow(); + assertNull(realm.getAnyTypeClass()); + assertTrue(realm.getPlainAttrs().isEmpty()); + + realm.setAnyTypeClass(anyTypeClassDAO.findById("other").orElseThrow()); + realm = realmDAO.save(realm); + + realm = realmDAO.findById(realm.getKey()).orElseThrow(); + assertEquals(anyTypeClassDAO.findById("other").orElseThrow(), realm.getAnyTypeClass()); + + PlainAttr aLong = new PlainAttr(); + aLong.setSchema("aLong"); + aLong.add(validator, "9"); + realm.add(aLong); + + realm = realmDAO.save(realm); + + realm = realmDAO.findById(realm.getKey()).orElseThrow(); + assertEquals(anyTypeClassDAO.findById("other").orElseThrow(), realm.getAnyTypeClass()); + assertEquals(1, realm.getPlainAttrs().size()); + assertEquals(9, realm.getPlainAttr("aLong").orElseThrow().getValues().get(0).getLongValue()); + } + @Test - public void test() { + public void delete() { Realm realm = realmSearchDAO.findByFullPath("/odd").orElseThrow(); // need to remove this group in order to remove the realm, which is otherwise empty diff --git a/core/persistence-neo4j/src/test/resources/domains/MasterContent.xml b/core/persistence-neo4j/src/test/resources/domains/MasterContent.xml index d3042c92b07..c5465463a38 100644 --- a/core/persistence-neo4j/src/test/resources/domains/MasterContent.xml +++ b/core/persistence-neo4j/src/test/resources/domains/MasterContent.xml @@ -159,7 +159,7 @@ under the License. enumValues='{"M":"Male","F":"Female"}'/> + body='import groovy.transform.CompileStatic import java.util.List import org.apache.syncope.common.lib.to.AttributableTO import org.apache.syncope.core.persistence.api.attrvalue.DropdownValueProvider @CompileStatic class TestDropdownValueProvider implements DropdownValueProvider { List<String> getChoices(AttributableTO attributableTO) { return ["A", "B"] } }'/> @@ -644,7 +644,7 @@ under the License. propagationPriority="1" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL" jsonConf='[{"schema":{"name":"uidAttribute","displayName":"Uid Attribute","helpMessage":"The name of the LDAP attribute which is mapped to the Uid attribute. Default is \"entryUUID\".","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":["entryUUID"]},"overridable":true,"values":["l"]},{"schema":{"name":"baseContexts","displayName":"Base Contexts","helpMessage":"One or more starting points in the LDAP tree that will be used when searching the tree. Searches are performed when discovering users from the LDAP server or when looking for the groups of which a user is a member.","type":"[Ljava.lang.String;","required":true,"order":7,"confidential":false,"defaultValues":[]},"overridable":true,"values":["${testds.rootDn}"]}]' - orgUnit='{"objectClass":"organizationalUnit","syncToken":null,"ignoreCaseMatch":false,"connObjectLink":"syncope:fullPath2Dn(fullPath, 'ou') + ',${testds.rootDn}'","items":[{"intAttrName":"fullpath","extAttrName":"l","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"name","extAttrName":"ou","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"fullpath","extAttrName":"l","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}'/> + orgUnit='{"objectClass":"organizationalUnit","syncToken":null,"ignoreCaseMatch":false,"connObjectLink":"syncope:fullPath2Dn(fullPath, 'ou') + ',${testds.rootDn}'","items":[{"intAttrName":"fullPath","extAttrName":"l","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"name","extAttrName":"ou","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"ctype","extAttrName":"description","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"fullpath","extAttrName":"l","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}'/> getValues(Realm realm); + /** * Calculates derived attributes values associated to the given any. * diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/IntAttrNameParser.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/IntAttrNameParser.java index 6b796d18311..8fef7a1cf9f 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/IntAttrNameParser.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/IntAttrNameParser.java @@ -31,6 +31,7 @@ import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.Entity; import org.apache.syncope.core.persistence.api.entity.Schema; +import org.apache.syncope.core.persistence.api.utils.RealmUtils; import org.springframework.transaction.annotation.Transactional; @SuppressWarnings({ "squid:S4784", "squid:S3776" }) @@ -62,16 +63,20 @@ public class IntAttrNameParser { protected final AnyUtilsFactory anyUtilsFactory; + protected final RealmUtils realmUtils; + public IntAttrNameParser( final PlainSchemaDAO plainSchemaDAO, final DerSchemaDAO derSchemaDAO, final VirSchemaDAO virSchemaDAO, - final AnyUtilsFactory anyUtilsFactory) { + final AnyUtilsFactory anyUtilsFactory, + final RealmUtils realmUtils) { this.plainSchemaDAO = plainSchemaDAO; this.derSchemaDAO = derSchemaDAO; this.virSchemaDAO = virSchemaDAO; this.anyUtilsFactory = anyUtilsFactory; + this.realmUtils = realmUtils; } protected Pair find(final String key) { @@ -82,15 +87,12 @@ protected Pair find(final String key) { schema = virSchemaDAO.findById(key).orElse(null); if (schema == null) { return null; - } else { - return Pair.of(schema, SchemaType.VIRTUAL); } - } else { - return Pair.of(schema, SchemaType.DERIVED); + return Pair.of(schema, SchemaType.VIRTUAL); } - } else { - return Pair.of(schema, SchemaType.PLAIN); + return Pair.of(schema, SchemaType.DERIVED); } + return Pair.of(schema, SchemaType.PLAIN); } protected void setFieldOrSchemaName( @@ -110,12 +112,11 @@ protected void setFieldOrSchemaName( public IntAttrName parse(final String intAttrName, final AnyTypeKind provisionAnyTypeKind) throws ParseException { IntAttrName result = new IntAttrName(); - Matcher matcher; if (intAttrName.indexOf('.') == -1) { result.setAnyTypeKind(provisionAnyTypeKind); setFieldOrSchemaName(intAttrName, result.getAnyTypeKind(), result); } else { - matcher = ENCLOSING_GROUP_PATTERN.matcher(intAttrName); + Matcher matcher = ENCLOSING_GROUP_PATTERN.matcher(intAttrName); if (matcher.matches()) { result.setAnyTypeKind(AnyTypeKind.GROUP); result.setEnclosingGroup(matcher.group(1)); @@ -156,4 +157,26 @@ public IntAttrName parse(final String intAttrName, final AnyTypeKind provisionAn return result; } + + protected void setFieldOrSchemaName(final String fieldOrSchemaName, final IntAttrName result) { + realmUtils.getField(fieldOrSchemaName).ifPresentOrElse( + field -> result.setField(fieldOrSchemaName), + () -> Optional.ofNullable(find(fieldOrSchemaName)).ifPresent(schemaInfo -> { + result.setSchemaType(schemaInfo.getRight()); + result.setSchema(schemaInfo.getLeft()); + })); + } + + @Transactional(readOnly = true) + public IntAttrName parse(final String intAttrName) throws ParseException { + IntAttrName result = new IntAttrName(); + + if (intAttrName.indexOf('.') == -1) { + setFieldOrSchemaName(intAttrName, result); + } else { + throw new ParseException("Unparsable expression: " + intAttrName, 0); + } + + return result; + } } diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java index b693cfa5762..e9c9d8221d0 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/MappingManager.java @@ -24,7 +24,6 @@ import org.apache.commons.lang3.tuple.Pair; import org.apache.syncope.common.lib.to.AnyTO; import org.apache.syncope.common.lib.to.Item; -import org.apache.syncope.common.lib.to.OrgUnit; import org.apache.syncope.common.lib.to.Provision; import org.apache.syncope.common.lib.to.RealmTO; import org.apache.syncope.common.lib.types.AttrSchemaType; @@ -52,17 +51,17 @@ public interface MappingManager { * Get connObjectKey internal value. * * @param realm realm - * @param orgUnit orgUnit information + * @param resource resource information * @return connObjectKey internal value */ - Optional getConnObjectKeyValue(Realm realm, OrgUnit orgUnit); + Optional getConnObjectKeyValue(Realm realm, ExternalResource resource); /** * Get attribute values for the given {@link Item} and any object. * * @param resource resource information * @param provision provision information - * @param mapItem mapping item + * @param item mapping item * @param intAttrName int attr name * @param schemaType schema type * @param any any object @@ -73,13 +72,30 @@ public interface MappingManager { Pair> getIntValues( ExternalResource resource, Provision provision, - Item mapItem, + Item item, IntAttrName intAttrName, AttrSchemaType schemaType, Any any, AccountGetter usernameAccountGetter, PlainAttrGetter plainAttrGetter); + /** + * Get attribute values for the given {@link Item} and realm. + * + * @param resource resource information + * @param item mapping item + * @param intAttrName int attr name + * @param schemaType schema type + * @param realm realm + * @return attribute values and their type + */ + Pair> getIntValues( + ExternalResource resource, + Item item, + IntAttrName intAttrName, + AttrSchemaType schemaType, + Realm realm); + /** * Prepare attribute for sending to a connector instance. * @@ -103,6 +119,16 @@ Pair prepareAttr( AccountGetter passwordAccountGetter, PlainAttrGetter plainAttrGetter); + /** + * Prepare attribute for sending to a connector instance. + * + * @param resource resource information + * @param item mapping item + * @param realm given realm + * @return connObjectLink (if it is the case) + prepared attribute + */ + Pair prepareAttr(ExternalResource resource, Item item, Realm realm); + /** * Prepare attributes for sending to a connector instance. * @@ -139,31 +165,31 @@ Set prepareAttrsFromLinkedAccount( * Prepare attributes for sending to a connector instance. * * @param realm Realm - * @param orgUnit provision information + * @param resource resource information * @return connObjectLink + prepared attributes */ - Pair> prepareAttrsFromRealm(Realm realm, OrgUnit orgUnit); + Pair> prepareAttrsFromRealm(Realm realm, ExternalResource resource); /** * Set attribute values, according to the given {@link Item}, to any object from attribute received from * connector. * * @param any object - * @param mapItem mapping item + * @param item mapping item * @param attr attribute received from connector * @param anyTO any object */ - void setIntValues(Item mapItem, Attribute attr, T anyTO); + void setIntValues(Item item, Attribute attr, T anyTO); /** * Set attribute values, according to the given {@link Item}, to realm from attribute received from * connector. * - * @param orgUnitItem mapping item + * @param item mapping item * @param attr attribute received from connector * @param realmTO realm */ - void setIntValues(Item orgUnitItem, Attribute attr, RealmTO realmTO); + void setIntValues(Item item, Attribute attr, RealmTO realmTO); /** * Checks if there is a mapping item in the given {@link Provision} for {@code mustChangePassword}. diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ItemTransformer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ItemTransformer.java index 2fc307fcddf..cb31ab94dd1 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ItemTransformer.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ItemTransformer.java @@ -25,6 +25,7 @@ import org.apache.syncope.common.lib.types.AttrSchemaType; import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; +import org.apache.syncope.core.persistence.api.entity.Realm; /** * Transforms values to be propagated to (or pulling from) external resources right before they leave (or enter) @@ -34,6 +35,24 @@ */ public interface ItemTransformer { + /** + * Invoked while preparing attribute values to be sent out to external resource during propagation. + * + * @param item mapping item + * @param realm realm + * @param schemaType schema type + * @param values original values + * @return transformed values + */ + default Pair> beforePropagation( + Item item, + Realm realm, + AttrSchemaType schemaType, + List values) { + + return Pair.of(schemaType, values); + } + /** * Invoked while preparing attribute values to be sent out to external resource during propagation. * diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/jexl/JexlUtils.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/jexl/JexlUtils.java index 3bf0c218d97..d11a0cc30c9 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/jexl/JexlUtils.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/jexl/JexlUtils.java @@ -48,6 +48,7 @@ import org.apache.syncope.common.lib.to.AnyTO; import org.apache.syncope.common.lib.to.RealmTO; import org.apache.syncope.core.persistence.api.entity.Any; +import org.apache.syncope.core.persistence.api.entity.Attributable; import org.apache.syncope.core.persistence.api.entity.DerSchema; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.Realm; @@ -264,23 +265,27 @@ public static void addPlainAttrsToContext(final Collection attrs, fin } public static void addDerAttrsToContext( - final Any any, + final Attributable attributable, final DerAttrHandler derAttrHandler, final JexlContext jexlContext) { - Map derAttrs = derAttrHandler.getValues(any); + Map derAttrs = attributable instanceof Realm realm + ? derAttrHandler.getValues(realm) + : attributable instanceof Any any + ? derAttrHandler.getValues(any) + : Map.of(); derAttrs.forEach((schema, value) -> jexlContext.set(schema.getKey(), value)); } public static boolean evaluateMandatoryCondition( final String mandatoryCondition, - final Any any, + final Attributable attributable, final DerAttrHandler derAttrHandler) { JexlContext jexlContext = new MapContext(); - addPlainAttrsToContext(any.getPlainAttrs(), jexlContext); - addDerAttrsToContext(any, derAttrHandler, jexlContext); + addPlainAttrsToContext(attributable.getPlainAttrs(), jexlContext); + addDerAttrsToContext(attributable, derAttrHandler, jexlContext); return Boolean.parseBoolean(evaluateExpr(mandatoryCondition, jexlContext).toString()); } diff --git a/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/IntAttrNameParserTest.java b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/IntAttrNameParserTest.java index 3f349e386bc..412135797e0 100644 --- a/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/IntAttrNameParserTest.java +++ b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/IntAttrNameParserTest.java @@ -32,7 +32,6 @@ import java.lang.reflect.Field; import java.text.ParseException; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -48,19 +47,19 @@ import org.apache.syncope.core.persistence.api.entity.DerSchema; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.VirSchema; +import org.apache.syncope.core.persistence.api.utils.RealmUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mock; public class IntAttrNameParserTest extends AbstractTest { - private static final Map> FIELDS = new HashMap<>(); + private static final Map> ANY_FIELDS = Map.of( + AnyTypeKind.USER, List.of("key", "username"), + AnyTypeKind.GROUP, List.of("key", "name", "userOwner"), + AnyTypeKind.ANY_OBJECT, List.of("key", "name")); - static { - FIELDS.put(AnyTypeKind.USER, List.of("key", "username")); - FIELDS.put(AnyTypeKind.GROUP, List.of("key", "name", "userOwner")); - FIELDS.put(AnyTypeKind.ANY_OBJECT, List.of("key", "name")); - } + private static final List REALM_FIELDS = List.of("key", "name"); @Mock private PlainSchemaDAO plainSchemaDAO; @@ -77,6 +76,9 @@ public class IntAttrNameParserTest extends AbstractTest { @Mock private AnyUtils anyUtils; + @Mock + private RealmUtils realmUtils; + private IntAttrNameParser intAttrNameParser; @BeforeEach @@ -87,7 +89,17 @@ public void initMocks() throws NoSuchFieldException { }); lenient().when(anyUtils.getField(anyString())).thenAnswer(ic -> { String fieldName = ic.getArgument(0); - if (FIELDS.get(anyUtils.anyTypeKind()).contains(fieldName)) { + if (ANY_FIELDS.get(anyUtils.anyTypeKind()).contains(fieldName)) { + Field field = mock(Field.class); + when(field.getName()).thenReturn(fieldName); + when(field.getType()).thenAnswer(ic2 -> String.class); + return Optional.of(field); + } + return Optional.empty(); + }); + lenient().when(realmUtils.getField(anyString())).thenAnswer(ic -> { + String fieldName = ic.getArgument(0); + if (REALM_FIELDS.contains(fieldName)) { Field field = mock(Field.class); when(field.getName()).thenReturn(fieldName); when(field.getType()).thenAnswer(ic2 -> String.class); @@ -98,7 +110,7 @@ public void initMocks() throws NoSuchFieldException { lenient().when(plainSchemaDAO.findById(anyString())).thenAnswer(ic -> { String schemaName = ic.getArgument(0); switch (schemaName) { - case "email", "firstname", "location" -> { + case "email", "firstname", "location", "index" -> { PlainSchema schema = mock(PlainSchema.class); lenient().when(schema.getKey()).thenReturn(schemaName); lenient().when(schema.getType()).thenReturn(AttrSchemaType.String); @@ -138,7 +150,8 @@ public void initMocks() throws NoSuchFieldException { } }); - intAttrNameParser = new IntAttrNameParser(plainSchemaDAO, derSchemaDAO, virSchemaDAO, anyUtilsFactory); + intAttrNameParser = new IntAttrNameParser( + plainSchemaDAO, derSchemaDAO, virSchemaDAO, anyUtilsFactory, realmUtils); } @Test @@ -343,4 +356,56 @@ public void invalid() { assertNotNull(e); } } + + @Test + public void realm() throws ParseException { + IntAttrName intAttrName = intAttrNameParser.parse("key"); + assertNotNull(intAttrName); + assertNull(intAttrName.getAnyTypeKind()); + assertNotNull(intAttrName.getField()); + assertEquals("key", intAttrName.getField()); + assertNull(intAttrName.getSchema()); + assertNull(intAttrName.getSchemaType()); + assertNull(intAttrName.getEnclosingGroup()); + assertNull(intAttrName.getMembershipOfGroup()); + assertNull(intAttrName.getRelatedAnyObject()); + assertNull(intAttrName.getRelationshipAnyType()); + assertNull(intAttrName.getRelationshipType()); + assertNull(intAttrName.getRelatedUser()); + + intAttrName = intAttrNameParser.parse("name"); + assertNotNull(intAttrName); + assertNull(intAttrName.getAnyTypeKind()); + assertNotNull(intAttrName.getField()); + assertEquals("name", intAttrName.getField()); + assertNull(intAttrName.getSchema()); + assertNull(intAttrName.getSchemaType()); + assertNull(intAttrName.getEnclosingGroup()); + assertNull(intAttrName.getMembershipOfGroup()); + assertNull(intAttrName.getRelatedAnyObject()); + assertNull(intAttrName.getRelationshipAnyType()); + assertNull(intAttrName.getRelationshipType()); + assertNull(intAttrName.getRelatedUser()); + + intAttrName = intAttrNameParser.parse("index"); + assertNotNull(intAttrName); + assertNull(intAttrName.getAnyTypeKind()); + assertNull(intAttrName.getField()); + assertEquals("index", intAttrName.getSchema().getKey()); + assertEquals(SchemaType.PLAIN, intAttrName.getSchemaType()); + assertTrue(intAttrName.getSchema() instanceof PlainSchema); + assertNull(intAttrName.getEnclosingGroup()); + assertNull(intAttrName.getMembershipOfGroup()); + assertNull(intAttrName.getRelatedAnyObject()); + assertNull(intAttrName.getRelationshipAnyType()); + assertNull(intAttrName.getRelationshipType()); + assertNull(intAttrName.getRelatedUser()); + + try { + intAttrNameParser.parse("groups[readers].cn"); + fail("This should not happen"); + } catch (ParseException e) { + assertNotNull(e); + } + } } diff --git a/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/jexl/JexlUtilsTest.java b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/jexl/JexlUtilsTest.java index 0bfc505169f..c9540277730 100644 --- a/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/jexl/JexlUtilsTest.java +++ b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/jexl/JexlUtilsTest.java @@ -138,7 +138,7 @@ public void addDerAttrsToContext( Map derAttrs = new HashMap<>(); derAttrs.put(derSchema, expression); - when(derAttrHandler.getValues(any())).thenReturn(derAttrs); + when(derAttrHandler.getValues(any(Any.class))).thenReturn(derAttrs); JexlUtils.addDerAttrsToContext(any, derAttrHandler, context); verify(context).set(derAttrs.get(derSchema), expression); } @@ -156,7 +156,7 @@ public void evaluateMandatoryCondition( derAttrs.put(derSchema, expression); when(any.getPlainAttrs()).thenReturn(new ArrayList<>()); - when(derAttrHandler.getValues(any())).thenReturn(derAttrs); + when(derAttrHandler.getValues(any(Any.class))).thenReturn(derAttrs); assertTrue(JexlUtils.evaluateMandatoryCondition("true", any, derAttrHandler)); assertFalse(JexlUtils.evaluateMandatoryCondition("false", any, derAttrHandler)); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultDerAttrHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultDerAttrHandler.java index 88bb21de7d8..3233e6abe22 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultDerAttrHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultDerAttrHandler.java @@ -18,6 +18,7 @@ */ package org.apache.syncope.core.provisioning.java; +import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -25,9 +26,11 @@ import org.apache.commons.jexl3.MapContext; import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; +import org.apache.syncope.core.persistence.api.entity.Attributable; import org.apache.syncope.core.persistence.api.entity.DerSchema; import org.apache.syncope.core.persistence.api.entity.Groupable; import org.apache.syncope.core.persistence.api.entity.Membership; +import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.provisioning.api.DerAttrHandler; import org.apache.syncope.core.provisioning.api.jexl.JexlUtils; import org.slf4j.Logger; @@ -39,13 +42,16 @@ public class DefaultDerAttrHandler implements DerAttrHandler { protected static final Logger LOG = LoggerFactory.getLogger(DerAttrHandler.class); - protected static Map getValues(final Any any, final Set schemas) { + protected static Map getValues( + final Attributable attributable, + final Collection schemas) { + Map result = new HashMap<>(schemas.size()); schemas.forEach(schema -> { JexlContext jexlContext = new MapContext(); - JexlUtils.addPlainAttrsToContext(any.getPlainAttrs(), jexlContext); - JexlUtils.addFieldsToContext(any, jexlContext); + JexlUtils.addPlainAttrsToContext(attributable.getPlainAttrs(), jexlContext); + JexlUtils.addFieldsToContext(attributable, jexlContext); result.put(schema, JexlUtils.evaluateExpr(schema.getExpression(), jexlContext).toString()); }); @@ -59,6 +65,16 @@ public DefaultDerAttrHandler(final AnyUtilsFactory anyUtilsFactory) { this.anyUtilsFactory = anyUtilsFactory; } + @Override + public String getValue(final Realm realm, final DerSchema schema) { + if (realm.getAnyTypeClass() == null || !realm.getAnyTypeClass().getDerSchemas().contains(schema)) { + LOG.debug("{} not allowed for {}", schema, realm); + return null; + } + + return getValues(realm, Set.of(schema)).get(schema); + } + @Override public String getValue(final Any any, final DerSchema schema) { if (!anyUtilsFactory.getInstance(any).dao().findAllowedSchemas(any, DerSchema.class).forSelfContains(schema)) { @@ -81,6 +97,17 @@ public String getValue(final Any any, final Membership membership, final DerS return getValues(any, Set.of(schema)).get(schema); } + @Override + public Map getValues(final Realm realm) { + if (realm.getAnyTypeClass() == null || !realm.getAnyTypeClass().getDerSchemas().isEmpty()) { + return Map.of(); + } + + return getValues( + realm, + realm.getAnyTypeClass().getDerSchemas()); + } + @Override public Map getValues(final Any any) { return getValues( @@ -112,5 +139,4 @@ public Map getValues(final Groupable any, final M anyUtilsFactory.getInstance(any).dao(). findAllowedSchemas(any, DerSchema.class).getForMembership(membership.getRightEnd())); } - } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java index 001ecce60c5..6384e346252 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java @@ -163,27 +163,6 @@ protected static Name getName(final String evalConnObjectLink, final String conn return name; } - protected static String getIntValue(final Realm realm, final Item orgUnitItem) { - String value = null; - switch (orgUnitItem.getIntAttrName()) { - case "key": - value = realm.getKey(); - break; - - case "name": - value = realm.getName(); - break; - - case "fullpath": - value = realm.getFullPath(); - break; - - default: - } - - return value; - } - protected static PlainAttrValue clonePlainAttrValue(final PlainAttrValue src) { PlainAttrValue dst = new PlainAttrValue(); @@ -332,15 +311,15 @@ public Pair> prepareAttrsFromAny( Set attributes = new HashSet<>(); Mutable connObjectKeyValue = new MutableObject<>(); - MappingUtils.getPropagationItems(provision.getMapping().getItems().stream()).forEach(mapItem -> { - LOG.debug("Processing expression '{}'", mapItem.getIntAttrName()); + MappingUtils.getPropagationItems(provision.getMapping().getItems().stream()).forEach(item -> { + LOG.debug("Processing expression '{}'", item.getIntAttrName()); try { processPreparedAttr( prepareAttr( resource, provision, - mapItem, + item, any, password, AccountGetter.DEFAULT, @@ -348,7 +327,7 @@ public Pair> prepareAttrsFromAny( PlainAttrGetter.DEFAULT), attributes).ifPresent(connObjectKeyValue::setValue); } catch (Exception e) { - LOG.error("Expression '{}' processing failed", mapItem.getIntAttrName(), e); + LOG.error("Expression '{}' processing failed", item.getIntAttrName(), e); } }); @@ -392,15 +371,15 @@ public Set prepareAttrsFromLinkedAccount( Set attributes = new HashSet<>(); - MappingUtils.getPropagationItems(provision.getMapping().getItems().stream()).forEach(mapItem -> { - LOG.debug("Processing expression '{}'", mapItem.getIntAttrName()); + MappingUtils.getPropagationItems(provision.getMapping().getItems().stream()).forEach(item -> { + LOG.debug("Processing expression '{}'", item.getIntAttrName()); try { processPreparedAttr( prepareAttr( account.getResource(), provision, - mapItem, + item, user, password, acct -> account.getUsername() == null ? AccountGetter.DEFAULT.apply(acct) : account, @@ -417,7 +396,7 @@ public Set prepareAttrsFromLinkedAccount( }), attributes); } catch (Exception e) { - LOG.error("Expression '{}' processing failed", mapItem.getIntAttrName(), e); + LOG.error("Expression '{}' processing failed", item.getIntAttrName(), e); } }); @@ -449,48 +428,45 @@ public Set prepareAttrsFromLinkedAccount( } @Override - public Pair> prepareAttrsFromRealm(final Realm realm, final OrgUnit orgUnit) { - LOG.debug("Preparing resource attributes for {} with orgUnit {}", realm, orgUnit); + public Pair> prepareAttrsFromRealm(final Realm realm, final ExternalResource resource) { + if (resource.getOrgUnit() == null) { + LOG.error("No mapping configured for Realms"); + return Pair.of(null, Set.of()); + } + + LOG.debug("Preparing resource attributes for {} with orgUnit {}", realm, resource.getOrgUnit()); Set attributes = new HashSet<>(); Mutable connObjectKeyValue = new MutableObject<>(); - MappingUtils.getPropagationItems(orgUnit.getItems().stream()).forEach(orgUnitItem -> { - LOG.debug("Processing expression '{}'", orgUnitItem.getIntAttrName()); - - String value = getIntValue(realm, orgUnitItem); + MappingUtils.getPropagationItems(resource.getOrgUnit().getItems().stream()).forEach(item -> { + LOG.debug("Processing expression '{}'", item.getIntAttrName()); - if (orgUnitItem.isConnObjectKey()) { - connObjectKeyValue.setValue(value); + try { + processPreparedAttr( + prepareAttr( + resource, + item, + realm), + attributes).ifPresent(connObjectKeyValue::setValue); + } catch (Exception e) { + LOG.error("Expression '{}' processing failed", item.getIntAttrName(), e); } - - Optional.ofNullable(AttributeUtil.find(orgUnitItem.getExtAttrName(), attributes)).ifPresentOrElse( - alreadyAdded -> { - attributes.remove(alreadyAdded); - - Set values = new HashSet<>(); - if (!CollectionUtils.isEmpty(alreadyAdded.getValue())) { - values.addAll(alreadyAdded.getValue()); - } - values.add(value); - - attributes.add(AttributeBuilder.build(orgUnitItem.getExtAttrName(), values)); - }, - () -> { - if (value == null) { - attributes.add(AttributeBuilder.build(orgUnitItem.getExtAttrName())); - } else { - attributes.add(AttributeBuilder.build(orgUnitItem.getExtAttrName(), value)); - } - }); }); - orgUnit.getConnObjectKeyItem().ifPresent(item -> { - Optional.ofNullable(AttributeUtil.find(item.getExtAttrName(), attributes)).ifPresent(attr -> { - attributes.remove(attr); + resource.getOrgUnit().getConnObjectKeyItem().ifPresent(item -> { + Attribute connObjectKeyAttr = AttributeUtil.find(item.getExtAttrName(), attributes); + if (connObjectKeyAttr != null) { + attributes.remove(connObjectKeyAttr); attributes.add(AttributeBuilder.build(item.getExtAttrName(), connObjectKeyValue.getValue())); - }); - attributes.add(evaluateNAME(realm, orgUnit, connObjectKeyValue.getValue())); + } + + Name name = evaluateNAME(realm, resource.getOrgUnit(), connObjectKeyValue.getValue()); + attributes.add(name); + + Optional.ofNullable(connObjectKeyValue.getValue()). + filter(cokv -> connObjectKeyAttr == null && !cokv.equals(name.getNameValue())). + ifPresent(cokv -> attributes.add(AttributeBuilder.build(item.getExtAttrName(), cokv))); }); return Pair.of(connObjectKeyValue.getValue(), attributes); @@ -604,20 +580,88 @@ public Pair prepareAttr( return result; } + @Override + public Pair prepareAttr( + final ExternalResource resource, + final Item item, + final Realm realm) { + + IntAttrName intAttrName; + try { + intAttrName = intAttrNameParser.parse(item.getIntAttrName()); + } catch (ParseException e) { + LOG.error("Invalid intAttrName '{}' specified, ignoring", item.getIntAttrName(), e); + return null; + } + + AttrSchemaType schemaType = intAttrName.getSchema() instanceof PlainSchema + ? intAttrName.getSchema().getType() + : AttrSchemaType.String; + boolean readOnlyVirSchema = intAttrName.getSchema() instanceof VirSchema + ? intAttrName.getSchema().isReadonly() + : false; + + Pair> intValues = getIntValues( + resource, item, intAttrName, schemaType, realm); + schemaType = intValues.getLeft(); + List values = intValues.getRight(); + + LOG.debug( + """ + Define mapping for: + * Item {} + * Schema {} + * ClassType {} + * AttrSchemaType {} + * Values {}""", + item, intAttrName.getSchema(), schemaType.getType().getName(), schemaType, values); + + Pair result; + if (readOnlyVirSchema) { + result = null; + } else { + List objValues = new ArrayList<>(); + + for (PlainAttrValue value : values) { + if (FrameworkUtil.isSupportedAttributeType(schemaType.getType())) { + objValues.add(value.getValue()); + } else { + PlainSchema plainSchema = intAttrName.getSchema() instanceof final PlainSchema schema + ? schema + : null; + if (plainSchema == null || plainSchema.getType() != schemaType) { + objValues.add(value.getValueAsString(schemaType)); + } else { + objValues.add(value.getValueAsString(plainSchema)); + } + } + } + + if (item.isConnObjectKey()) { + result = Pair.of(objValues.isEmpty() ? null : objValues.getFirst().toString(), null); + } else { + result = Pair.of(null, objValues.isEmpty() + ? AttributeBuilder.build(item.getExtAttrName()) + : AttributeBuilder.build(item.getExtAttrName(), objValues)); + } + } + + return result; + } + @Transactional(readOnly = true) - @SuppressWarnings("unchecked") @Override public Pair> getIntValues( final ExternalResource resource, final Provision provision, - final Item mapItem, + final Item item, final IntAttrName intAttrName, final AttrSchemaType schemaType, final Any any, final AccountGetter usernameAccountGetter, final PlainAttrGetter plainAttrGetter) { - LOG.debug("Get internal values for {} as '{}' on {}", any, mapItem.getIntAttrName(), resource); + LOG.debug("Get internal values for {} as '{}' on {}", any, item.getIntAttrName(), resource); List references = new ArrayList<>(); if (intAttrName.getEnclosingGroup() == null @@ -681,7 +725,7 @@ public Pair> getIntValues( orElse(null); } if (references.isEmpty()) { - LOG.warn("Could not determine the reference instance for {}", mapItem.getIntAttrName()); + LOG.warn("Could not determine the reference instance for {}", item.getIntAttrName()); return Pair.of(schemaType, List.of()); } @@ -775,13 +819,10 @@ public Pair> getIntValues( } else if (intAttrName.getSchemaType() != null) { switch (intAttrName.getSchemaType()) { case PLAIN -> { - PlainAttr attr; - if (membership == null) { - attr = plainAttrGetter.apply(ref, intAttrName.getSchema().getKey()); - } else { - attr = ((Groupable) ref).getPlainAttr( - intAttrName.getSchema().getKey(), membership).orElse(null); - } + PlainAttr attr = membership == null + ? plainAttrGetter.apply(ref, intAttrName.getSchema().getKey()) + : ((Groupable) ref).getPlainAttr( + intAttrName.getSchema().getKey(), membership).orElse(null); if (attr != null) { if (attr.getUniqueValue() != null) { values.add(clonePlainAttrValue(attr.getUniqueValue())); @@ -833,9 +874,87 @@ public Pair> getIntValues( Pair> transformed = Pair.of(schemaType, values); if (transform) { - for (ItemTransformer transformer : MappingUtils.getItemTransformers(mapItem, getTransformers(mapItem))) { + for (ItemTransformer transformer : MappingUtils.getItemTransformers(item, getTransformers(item))) { transformed = transformer.beforePropagation( - mapItem, any, transformed.getLeft(), transformed.getRight()); + item, any, transformed.getLeft(), transformed.getRight()); + } + LOG.debug("Transformed values: {}", values); + } else { + LOG.debug("No transformation occurred"); + } + + return transformed; + } + + @Transactional(readOnly = true) + @Override + public Pair> getIntValues( + final ExternalResource resource, + final Item item, + final IntAttrName intAttrName, + final AttrSchemaType schemaType, + final Realm realm) { + + LOG.debug("Get internal values for {} as '{}' on {}", realm, item.getIntAttrName(), resource); + + List values = new ArrayList<>(); + boolean transform = true; + + if (intAttrName.getField() != null) { + PlainAttrValue attrValue = new PlainAttrValue(); + + switch (intAttrName.getField()) { + case "key" -> { + attrValue.setStringValue(realm.getKey()); + values.add(attrValue); + } + + case "name" -> { + attrValue.setStringValue(realm.getName()); + values.add(attrValue); + } + + case "fullPath" -> { + attrValue.setStringValue(realm.getFullPath()); + values.add(attrValue); + } + + default -> { + } + } + } else if (intAttrName.getSchemaType() != null) { + switch (intAttrName.getSchemaType()) { + case PLAIN -> { + realm.getPlainAttr(intAttrName.getSchema().getKey()).ifPresent(attr -> { + if (attr.getUniqueValue() != null) { + values.add(clonePlainAttrValue(attr.getUniqueValue())); + } else if (attr.getValues() != null) { + attr.getValues().forEach(value -> values.add(clonePlainAttrValue(value))); + } + }); + } + + case DERIVED -> { + Optional.ofNullable(derAttrHandler.getValue(realm, (DerSchema) intAttrName.getSchema())). + ifPresent(derValue -> { + PlainAttrValue attrValue = new PlainAttrValue(); + attrValue.setStringValue(derValue); + values.add(attrValue); + }); + } + + default -> { + } + } + } + + LOG.debug("Internal values: {}", values); + + Pair> transformed = Pair.of(schemaType, values); + if (transform) { + for (ItemTransformer transformer : MappingUtils.getItemTransformers(item, getTransformers(item))) { + transformed = transformer.beforePropagation( + item, realm, transformed.getLeft(), transformed.getRight()); } LOG.debug("Transformed values: {}", values); } else { @@ -881,55 +1000,77 @@ public Optional getConnObjectKeyValue( LOG.error("Unable to locate conn object key item for {}", any.getType().getKey()); return Optional.empty(); } - Item mapItem = connObjectKeyItem.get(); + + Item item = connObjectKeyItem.get(); Pair> intValues; try { intValues = getIntValues( resource, provision, - mapItem, - intAttrNameParser.parse(mapItem.getIntAttrName(), any.getType().getKind()), + item, + intAttrNameParser.parse(item.getIntAttrName(), any.getType().getKind()), AttrSchemaType.String, any, AccountGetter.DEFAULT, PlainAttrGetter.DEFAULT); } catch (ParseException e) { - LOG.error("Invalid intAttrName '{}' specified, ignoring", mapItem.getIntAttrName(), e); + LOG.error("Invalid intAttrName '{}' specified, ignoring", item.getIntAttrName(), e); intValues = Pair.of(AttrSchemaType.String, List.of()); } - return Optional.ofNullable(intValues.getRight().isEmpty() - ? null - : intValues.getRight().getFirst().getValueAsString()); + return intValues.getRight().isEmpty() + ? Optional.empty() + : Optional.of(intValues.getRight().getFirst().getValueAsString()); } @Transactional(readOnly = true) @Override - public Optional getConnObjectKeyValue(final Realm realm, final OrgUnit orgUnit) { - Optional connObjectKeyItem = orgUnit.getConnObjectKeyItem(); + public Optional getConnObjectKeyValue(final Realm realm, final ExternalResource resource) { + if (resource.getOrgUnit() == null) { + LOG.error("No mapping configured for Realms"); + return Optional.empty(); + } + + Optional connObjectKeyItem = resource.getOrgUnit().getConnObjectKeyItem(); if (connObjectKeyItem.isEmpty()) { LOG.error("Unable to locate conn object key item for Realms"); return Optional.empty(); } - return Optional.ofNullable(getIntValue(realm, connObjectKeyItem.get())); + + Item item = connObjectKeyItem.get(); + Pair> intValues; + try { + intValues = getIntValues( + resource, + item, + intAttrNameParser.parse(item.getIntAttrName()), + AttrSchemaType.String, + realm); + } catch (ParseException e) { + LOG.error("Invalid intAttrName '{}' specified, ignoring", item.getIntAttrName(), e); + intValues = Pair.of(AttrSchemaType.String, List.of()); + } + return intValues.getRight().isEmpty() + ? Optional.empty() + : Optional.of(intValues.getRight().getFirst().getValueAsString()); } @Transactional(readOnly = true) @Override - public void setIntValues(final Item mapItem, final Attribute attr, final AnyTO anyTO) { + public void setIntValues(final Item item, final Attribute attr, final AnyTO anyTO) { List values = null; if (attr != null) { values = attr.getValue(); - for (ItemTransformer transformer : MappingUtils.getItemTransformers(mapItem, getTransformers(mapItem))) { - values = transformer.beforePull(mapItem, anyTO, values); + for (ItemTransformer transformer : MappingUtils.getItemTransformers(item, getTransformers(item))) { + values = transformer.beforePull(item, anyTO, values); } } values = Optional.ofNullable(values).orElseGet(List::of); IntAttrName intAttrName; try { - intAttrName = intAttrNameParser.parse(mapItem.getIntAttrName(), AnyTypeKind.fromTOClass(anyTO.getClass())); + intAttrName = intAttrNameParser.parse(item.getIntAttrName(), AnyTypeKind.fromTOClass(anyTO.getClass())); } catch (ParseException e) { - LOG.error("Invalid intAttrName '{}' specified, ignoring", mapItem.getIntAttrName(), e); + LOG.error("Invalid intAttrName '{}' specified, ignoring", item.getIntAttrName(), e); return; } @@ -1081,11 +1222,23 @@ public void setIntValues(final Item item, final Attribute attr, final RealmTO re values = transformer.beforePull(item, realmTO, values); } } + values = Optional.ofNullable(values).orElseGet(List::of); - if (values != null && !values.isEmpty() && values.getFirst() != null) { - switch (item.getIntAttrName()) { - case "name" -> - realmTO.setName(values.getFirst().toString()); + IntAttrName intAttrName; + try { + intAttrName = intAttrNameParser.parse(item.getIntAttrName()); + } catch (ParseException e) { + LOG.error("Invalid intAttrName '{}' specified, ignoring", item.getIntAttrName(), e); + return; + } + + if (intAttrName.getField() != null) { + switch (intAttrName.getField()) { + case "name" -> { + realmTO.setName(values.isEmpty() || values.getFirst() == null + ? null + : values.getFirst().toString()); + } case "fullpath" -> { String parentFullPath = StringUtils.substringBeforeLast(values.getFirst().toString(), "/"); @@ -1094,6 +1247,37 @@ public void setIntValues(final Item item, final Attribute attr, final RealmTO re () -> LOG.warn("Could not find Realm with path {}, ignoring", parentFullPath)); } + default -> { + } + } + } else if (intAttrName.getSchemaType() != null && attr != null) { + switch (intAttrName.getSchemaType()) { + case PLAIN -> { + Attr attrTO = new Attr(); + attrTO.setSchema(intAttrName.getSchema().getKey()); + + PlainSchema schema = (PlainSchema) intAttrName.getSchema(); + + for (Object value : values) { + AttrSchemaType schemaType = schema == null ? AttrSchemaType.String : schema.getType(); + if (value != null) { + if (schemaType == AttrSchemaType.Binary) { + attrTO.getValues().add(Base64.getEncoder().encodeToString((byte[]) value)); + } else { + attrTO.getValues().add(value.toString()); + } + } + } + + realmTO.getPlainAttrs().add(attrTO); + } + + case DERIVED -> { + Attr attrTO = new Attr(); + attrTO.setSchema(intAttrName.getSchema().getKey()); + realmTO.getDerAttrs().add(attrTO); + } + default -> { } } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultVirAttrHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultVirAttrHandler.java index 332af137af2..c5bde775f2e 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultVirAttrHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultVirAttrHandler.java @@ -86,15 +86,16 @@ public void setValues(final Any any, final ConnectorObject connObj) { VirAttrCacheKey cacheKey = VirAttrCacheKey.of(any.getType().getKey(), any.getKey(), schema.getKey()); - Attribute attr = connObj.getAttributeByName(schema.getExtAttrName()); - if (attr == null) { - virAttrCache.remove(cacheKey); - LOG.debug("Evicted from cache: {}", cacheKey); - } else { - VirAttrCacheValue cacheValue = VirAttrCacheValue.of(attr.getValue()); - virAttrCache.put(cacheKey, cacheValue); - LOG.debug("Set in cache: {}={}", cacheKey, cacheValue); - } + Optional.ofNullable(connObj.getAttributeByName(schema.getExtAttrName())).ifPresentOrElse( + attr -> { + VirAttrCacheValue cacheValue = VirAttrCacheValue.of(attr.getValue()); + virAttrCache.put(cacheKey, cacheValue); + LOG.debug("Set in cache: {}={}", cacheKey, cacheValue); + }, + () -> { + virAttrCache.remove(cacheKey); + LOG.debug("Evicted from cache: {}", cacheKey); + }); }); } @@ -113,14 +114,9 @@ protected Map> getValues(final Any any, final Set { - Set schemasToRead = toRead.get(Pair.of(schema.getResource(), provision)); - if (schemasToRead == null) { - schemasToRead = new HashSet<>(); - toRead.put(Pair.of(schema.getResource(), provision), schemasToRead); - } - schemasToRead.add(schema); - }); + schema.getResource().getProvisionByAnyType(any.getType().getKey()). + ifPresent(provision -> toRead.computeIfAbsent( + Pair.of(schema.getResource(), provision), k -> new HashSet<>()).add(schema)); } }); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java index 36949fe2017..4aaed30505d 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java @@ -66,6 +66,7 @@ import org.apache.syncope.core.persistence.api.entity.EntityFactory; import org.apache.syncope.core.persistence.api.entity.task.TaskUtilsFactory; import org.apache.syncope.core.persistence.api.search.SearchCondVisitor; +import org.apache.syncope.core.persistence.api.utils.RealmUtils; import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager; import org.apache.syncope.core.provisioning.api.AuditEventProcessor; import org.apache.syncope.core.provisioning.api.AuditManager; @@ -482,11 +483,12 @@ public ConnIdBundleManager connIdBundleManager(final ProvisioningProperties prop @Bean public IntAttrNameParser intAttrNameParser( final AnyUtilsFactory anyUtilsFactory, + final RealmUtils realmUtils, final PlainSchemaDAO plainSchemaDAO, final DerSchemaDAO derSchemaDAO, final VirSchemaDAO virSchemaDAO) { - return new IntAttrNameParser(plainSchemaDAO, derSchemaDAO, virSchemaDAO, anyUtilsFactory); + return new IntAttrNameParser(plainSchemaDAO, derSchemaDAO, virSchemaDAO, anyUtilsFactory, realmUtils); } @ConditionalOnMissingBean @@ -967,20 +969,32 @@ public PolicyDataBinder policyDataBinder( @ConditionalOnMissingBean @Bean public RealmDataBinder realmDataBinder( - final EntityFactory entityFactory, final AnyTypeDAO anyTypeDAO, + final AnyTypeClassDAO anyTypeClassDAO, final ImplementationDAO implementationDAO, final RealmDAO realmDAO, final PolicyDAO policyDAO, - final ExternalResourceDAO resourceDAO) { + final ExternalResourceDAO resourceDAO, + final PlainSchemaDAO plainSchemaDAO, + final EntityFactory entityFactory, + final DerAttrHandler derAttrHandler, + final PlainAttrValidationManager validator, + final MappingManager mappingManager, + final IntAttrNameParser intAttrNameParser) { return new RealmDataBinderImpl( anyTypeDAO, + anyTypeClassDAO, implementationDAO, realmDAO, policyDAO, resourceDAO, - entityFactory); + plainSchemaDAO, + entityFactory, + derAttrHandler, + validator, + mappingManager, + intAttrNameParser); } @ConditionalOnMissingBean diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyDataBinder.java similarity index 79% rename from core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java rename to core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyDataBinder.java index 4714eadfc34..ff1140aee13 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyDataBinder.java @@ -26,7 +26,6 @@ import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; @@ -46,8 +45,6 @@ import org.apache.syncope.common.lib.types.ClientExceptionType; import org.apache.syncope.common.lib.types.PatchOperation; import org.apache.syncope.common.lib.types.ResourceOperation; -import org.apache.syncope.core.persistence.api.attrvalue.DropdownValueProvider; -import org.apache.syncope.core.persistence.api.attrvalue.InvalidPlainAttrValueException; import org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValidationManager; import org.apache.syncope.core.persistence.api.dao.AllowedSchemas; import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; @@ -73,6 +70,7 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; +import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.provisioning.api.AccountGetter; import org.apache.syncope.core.provisioning.api.DerAttrHandler; @@ -86,18 +84,13 @@ import org.apache.syncope.core.provisioning.java.pushpull.OutboundMatcher; import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils; import org.apache.syncope.core.provisioning.java.utils.MappingUtils; -import org.apache.syncope.core.spring.implementation.ImplementationManager; import org.identityconnectors.framework.common.objects.Attribute; import org.identityconnectors.framework.common.objects.AttributeBuilder; import org.identityconnectors.framework.common.objects.ConnectorObject; import org.identityconnectors.framework.common.objects.ConnectorObjectBuilder; import org.identityconnectors.framework.common.objects.Uid; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -abstract class AbstractAnyDataBinder { - - protected static final Logger LOG = LoggerFactory.getLogger(AbstractAnyDataBinder.class); +abstract class AnyDataBinder extends AttributableDataBinder { protected static void fillTO( final AnyTO anyTO, @@ -134,7 +127,9 @@ protected static RelationshipTO getRelationshipTO( otherEnd.getKey(), otherEnd instanceof User user ? user.getUsername() - : ((AnyObject) otherEnd).getName()). + : otherEnd instanceof Group group + ? group.getName() + : ((AnyObject) otherEnd).getName()). build(); } @@ -171,8 +166,6 @@ protected static MembershipTO getMembershipTO( protected final GroupDAO groupDAO; - protected final PlainSchemaDAO plainSchemaDAO; - protected final ExternalResourceDAO resourceDAO; protected final RelationshipTypeDAO relationshipTypeDAO; @@ -181,21 +174,11 @@ protected static MembershipTO getMembershipTO( protected final AnyUtilsFactory anyUtilsFactory; - protected final DerAttrHandler derAttrHandler; - protected final VirAttrHandler virAttrHandler; - protected final MappingManager mappingManager; - - protected final IntAttrNameParser intAttrNameParser; - protected final OutboundMatcher outboundMatcher; - protected final PlainAttrValidationManager validator; - - protected final Map dropdownValueProviders = new ConcurrentHashMap<>(); - - protected AbstractAnyDataBinder( + protected AnyDataBinder( final AnyTypeDAO anyTypeDAO, final RealmSearchDAO realmSearchDAO, final AnyTypeClassDAO anyTypeClassDAO, @@ -214,29 +197,25 @@ protected AbstractAnyDataBinder( final OutboundMatcher outboundMatcher, final PlainAttrValidationManager validator) { + super(plainSchemaDAO, validator, derAttrHandler, mappingManager, intAttrNameParser); this.anyTypeDAO = anyTypeDAO; this.realmSearchDAO = realmSearchDAO; this.anyTypeClassDAO = anyTypeClassDAO; this.anyObjectDAO = anyObjectDAO; this.userDAO = userDAO; this.groupDAO = groupDAO; - this.plainSchemaDAO = plainSchemaDAO; this.resourceDAO = resourceDAO; this.relationshipTypeDAO = relationshipTypeDAO; this.entityFactory = entityFactory; this.anyUtilsFactory = anyUtilsFactory; - this.derAttrHandler = derAttrHandler; this.virAttrHandler = virAttrHandler; - this.mappingManager = mappingManager; - this.intAttrNameParser = intAttrNameParser; this.outboundMatcher = outboundMatcher; - this.validator = validator; } protected void setRealm(final Any any, final AnyUR anyUR) { if (anyUR.getRealm() != null && StringUtils.isNotBlank(anyUR.getRealm().getValue())) { realmSearchDAO.findByFullPath(anyUR.getRealm().getValue()).ifPresentOrElse( - any::setRealm, + any::setRealm, () -> LOG.debug("Invalid realm specified: {}, ignoring", anyUR.getRealm().getValue())); } } @@ -277,97 +256,17 @@ protected Map onResources( return onResources; } - protected Optional getPlainSchema(final String schemaName) { - PlainSchema schema = null; - if (StringUtils.isNotBlank(schemaName)) { - schema = plainSchemaDAO.findById(schemaName).orElse(null); - - // safely ignore invalid schemas from Attr - if (schema == null) { - LOG.debug("Ignoring invalid schema {}", schemaName); - } else if (schema.isReadonly()) { - schema = null; - LOG.debug("Ignoring readonly schema {}", schemaName); - } - } - - return Optional.ofNullable(schema); - } - - protected void fillAttr( - final AnyTO anyTO, - final List values, - final PlainSchema schema, - final PlainAttr attr, - final SyncopeClientException invalidValues) { - - // if schema is multivalue, all values are considered for addition; - // otherwise only the fist one - if provided - is considered - List valuesProvided = schema.isMultivalue() - ? values - : (values.isEmpty() || values.getFirst() == null - ? List.of() - : List.of(values.getFirst())); - - valuesProvided.forEach(value -> { - if (StringUtils.isBlank(value)) { - LOG.debug("Null value for {}, ignoring", schema.getKey()); - } else { - try { - switch (schema.getType()) { - case Enum -> { - if (!schema.getEnumValues().containsKey(value)) { - throw new InvalidPlainAttrValueException( - '\'' + value + "' is not one of: " + schema.getEnumValues().keySet()); - } - } - - case Dropdown -> { - List dropdownValues = List.of(); - try { - DropdownValueProvider provider = ImplementationManager.build( - schema.getDropdownValueProvider(), - () -> dropdownValueProviders.get( - schema.getDropdownValueProvider().getKey()), - instance -> dropdownValueProviders.put( - schema.getDropdownValueProvider().getKey(), instance)); - dropdownValues = provider.getChoices(anyTO); - } catch (Exception e) { - LOG.error("While getting dropdown values for {}", schema.getKey(), e); - } - - if (!dropdownValues.contains(value)) { - throw new InvalidPlainAttrValueException( - '\'' + value + "' is not one of: " + dropdownValues); - } - } - - default -> { - } - } - - attr.add(validator, value); - } catch (InvalidPlainAttrValueException e) { - LOG.warn("Invalid value for attribute {}: {}", - schema.getKey(), StringUtils.abbreviate(value, 20), e); - - invalidValues.getElements().add(schema.getKey() + ": " + value + " - " + e.getMessage()); - } - } - }); - } - protected List evaluateMandatoryCondition( final ExternalResource resource, final Provision provision, final Any any) { List missingAttrNames = new ArrayList<>(); - MappingUtils.getPropagationItems(provision.getMapping().getItems().stream()).forEach(mapItem -> { + MappingUtils.getPropagationItems(provision.getMapping().getItems().stream()).forEach(item -> { IntAttrName intAttrName = null; try { - intAttrName = intAttrNameParser.parse(mapItem.getIntAttrName(), any.getType().getKind()); + intAttrName = intAttrNameParser.parse(item.getIntAttrName(), any.getType().getKind()); } catch (ParseException e) { - LOG.error("Invalid intAttrName '{}', ignoring", mapItem.getIntAttrName(), e); + LOG.error("Invalid intAttrName '{}', ignoring", item.getIntAttrName(), e); } if (intAttrName != null && intAttrName.getSchema() != null) { AttrSchemaType schemaType = intAttrName.getSchema() instanceof PlainSchema @@ -377,16 +276,16 @@ protected List evaluateMandatoryCondition( Pair> intValues = mappingManager.getIntValues( resource, provision, - mapItem, + item, intAttrName, schemaType, any, AccountGetter.DEFAULT, PlainAttrGetter.DEFAULT); if (intValues.getRight().isEmpty() - && JexlUtils.evaluateMandatoryCondition(mapItem.getMandatoryCondition(), any, derAttrHandler)) { + && JexlUtils.evaluateMandatoryCondition(item.getMandatoryCondition(), any, derAttrHandler)) { - missingAttrNames.add(mapItem.getIntAttrName()); + missingAttrNames.add(item.getIntAttrName()); } } }); @@ -394,7 +293,7 @@ protected List evaluateMandatoryCondition( return missingAttrNames; } - private SyncopeClientException checkMandatoryOnResources( + protected SyncopeClientException checkMandatoryOnResources( final Any any, final Collection resources) { SyncopeClientException reqValMissing = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing); @@ -413,23 +312,7 @@ private SyncopeClientException checkMandatoryOnResources( return reqValMissing; } - private void checkMandatory( - final PlainSchema schema, - final PlainAttr attr, - final Any any, - final SyncopeClientException reqValMissing) { - - if (attr == null - && !schema.isReadonly() - && JexlUtils.evaluateMandatoryCondition(schema.getMandatoryCondition(), any, derAttrHandler)) { - - LOG.error("Mandatory schema {} not provided with values", schema.getKey()); - - reqValMissing.getElements().add(schema.getKey()); - } - } - - private SyncopeClientException checkMandatory(final Any any, final AnyUtils anyUtils) { + protected SyncopeClientException checkMandatory(final Any any, final AnyUtils anyUtils) { SyncopeClientException reqValMissing = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing); // Check if there is some mandatory schema defined for which no value has been provided @@ -466,7 +349,7 @@ protected void processAttrPatch( if (attr.getUniqueValue() != null && !patch.getAttr().getValues().isEmpty() && !patch.getAttr().getValues().getFirst().equals( - attr.getUniqueValue().getValueAsString())) { + attr.getUniqueValue().getValueAsString())) { attr.setUniqueValue(null); } @@ -566,13 +449,13 @@ protected void fill( scce.addException(invalidValues); } - SyncopeClientException requiredValuesMissing = checkMandatory(any, anyUtils); - if (!requiredValuesMissing.isEmpty()) { - scce.addException(requiredValuesMissing); + SyncopeClientException reqValMissing = checkMandatory(any, anyUtils); + if (!reqValMissing.isEmpty()) { + scce.addException(reqValMissing); } - requiredValuesMissing = checkMandatoryOnResources(any, resources); - if (!requiredValuesMissing.isEmpty()) { - scce.addException(requiredValuesMissing); + reqValMissing = checkMandatoryOnResources(any, resources); + if (!reqValMissing.isEmpty()) { + scce.addException(reqValMissing); } } @@ -602,7 +485,6 @@ protected PropagationByResource propByRes( return propByRes; } - @SuppressWarnings({ "unchecked", "rawtypes" }) protected void fill( final AnyTO anyTO, final Any any, diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java index b621dd1b290..5b43c184862 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java @@ -18,9 +18,7 @@ */ package org.apache.syncope.core.provisioning.java.data; -import java.util.Collections; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang3.StringUtils; @@ -58,7 +56,6 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.RelationshipType; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership; import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; @@ -73,7 +70,7 @@ import org.springframework.transaction.annotation.Transactional; @Transactional(rollbackFor = { Throwable.class }) -public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements AnyObjectDataBinder { +public class AnyObjectDataBinderImpl extends AnyDataBinder implements AnyObjectDataBinder { public AnyObjectDataBinderImpl( final AnyTypeDAO anyTypeDAO, @@ -136,15 +133,12 @@ public AnyObjectTO getAnyObjectTO(final AnyObject anyObject, final boolean detai anyObjectTO.setLastChangeDate(anyObject.getLastChangeDate()); anyObjectTO.setLastChangeContext(anyObject.getLastChangeContext()); - Map> virAttrValues = details - ? virAttrHandler.getValues(anyObject) - : Collections.emptyMap(); fillTO(anyObjectTO, anyObject.getRealm().getFullPath(), anyObject.getAuxClasses(), anyObject.getPlainAttrs(), derAttrHandler.getValues(anyObject), - virAttrValues, + details ? virAttrHandler.getValues(anyObject) : Map.of(), anyObjectDAO.findAllResources(anyObject)); // dynamic realms @@ -154,14 +148,14 @@ public AnyObjectTO getAnyObjectTO(final AnyObject anyObject, final boolean detai // relationships anyObjectTO.getRelationships().addAll( anyObjectDAO.findAllRelationships(anyObject).stream(). - map(relationship -> getRelationshipTO( - relationship.getType().getKey(), - relationship.getLeftEnd().getKey().equals(anyObject.getKey()) + map(r -> getRelationshipTO( + r.getType().getKey(), + r.getLeftEnd().getKey().equals(anyObject.getKey()) ? RelationshipTO.End.LEFT : RelationshipTO.End.RIGHT, - relationship.getLeftEnd().getKey().equals(anyObject.getKey()) - ? relationship.getRightEnd() - : relationship.getLeftEnd())). + r.getLeftEnd().getKey().equals(anyObject.getKey()) + ? r.getRightEnd() + : r.getLeftEnd())). toList()); // memberships diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AttributableDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AttributableDataBinder.java new file mode 100644 index 00000000000..63527412a08 --- /dev/null +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AttributableDataBinder.java @@ -0,0 +1,168 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.provisioning.java.data; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import org.apache.commons.lang3.StringUtils; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.to.AttributableTO; +import org.apache.syncope.core.persistence.api.attrvalue.DropdownValueProvider; +import org.apache.syncope.core.persistence.api.attrvalue.InvalidPlainAttrValueException; +import org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValidationManager; +import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; +import org.apache.syncope.core.persistence.api.entity.Attributable; +import org.apache.syncope.core.persistence.api.entity.PlainAttr; +import org.apache.syncope.core.persistence.api.entity.PlainSchema; +import org.apache.syncope.core.provisioning.api.DerAttrHandler; +import org.apache.syncope.core.provisioning.api.IntAttrNameParser; +import org.apache.syncope.core.provisioning.api.MappingManager; +import org.apache.syncope.core.provisioning.api.jexl.JexlUtils; +import org.apache.syncope.core.spring.implementation.ImplementationManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +abstract class AttributableDataBinder { + + protected static final Logger LOG = LoggerFactory.getLogger(AttributableDataBinder.class); + + protected final PlainSchemaDAO plainSchemaDAO; + + protected final PlainAttrValidationManager validator; + + protected final DerAttrHandler derAttrHandler; + + protected final MappingManager mappingManager; + + protected final IntAttrNameParser intAttrNameParser; + + private final Map dropdownValueProviders = new ConcurrentHashMap<>(); + + protected AttributableDataBinder( + final PlainSchemaDAO plainSchemaDAO, + final PlainAttrValidationManager validator, + final DerAttrHandler derAttrHandler, + final MappingManager mappingManager, + final IntAttrNameParser intAttrNameParser) { + + this.plainSchemaDAO = plainSchemaDAO; + this.validator = validator; + this.derAttrHandler = derAttrHandler; + this.mappingManager = mappingManager; + this.intAttrNameParser = intAttrNameParser; + } + + protected Optional getPlainSchema(final String schemaName) { + PlainSchema schema = null; + if (StringUtils.isNotBlank(schemaName)) { + schema = plainSchemaDAO.findById(schemaName).orElse(null); + + // safely ignore invalid schemas from Attr + if (schema == null) { + LOG.debug("Ignoring invalid schema {}", schemaName); + } else if (schema.isReadonly()) { + schema = null; + LOG.debug("Ignoring readonly schema {}", schemaName); + } + } + + return Optional.ofNullable(schema); + } + + protected void checkMandatory( + final PlainSchema schema, + final PlainAttr attr, + final Attributable attributable, + final SyncopeClientException reqValMissing) { + + if (attr == null + && !schema.isReadonly() + && JexlUtils.evaluateMandatoryCondition(schema.getMandatoryCondition(), attributable, derAttrHandler)) { + + LOG.error("Mandatory schema {} not provided with values", schema.getKey()); + + reqValMissing.getElements().add(schema.getKey()); + } + } + + protected void fillAttr( + final AttributableTO attributableTO, + final List values, + final PlainSchema schema, + final PlainAttr attr, + final SyncopeClientException invalidValues) { + + // if schema is multivalue, all values are considered for addition; + // otherwise only the fist one - if provided - is considered + List valuesProvided = schema.isMultivalue() + ? values + : (values.isEmpty() || values.getFirst() == null + ? List.of() + : List.of(values.getFirst())); + + valuesProvided.forEach(value -> { + if (StringUtils.isBlank(value)) { + LOG.debug("Null value for {}, ignoring", schema.getKey()); + } else { + try { + switch (schema.getType()) { + case Enum -> { + if (!schema.getEnumValues().containsKey(value)) { + throw new InvalidPlainAttrValueException( + '\'' + value + "' is not one of: " + schema.getEnumValues().keySet()); + } + } + + case Dropdown -> { + List dropdownValues = List.of(); + try { + DropdownValueProvider provider = ImplementationManager.build( + schema.getDropdownValueProvider(), + () -> dropdownValueProviders.get( + schema.getDropdownValueProvider().getKey()), + instance -> dropdownValueProviders.put( + schema.getDropdownValueProvider().getKey(), instance)); + dropdownValues = provider.getChoices(attributableTO); + } catch (Exception e) { + LOG.error("While getting dropdown values for {}", schema.getKey(), e); + } + + if (!dropdownValues.contains(value)) { + throw new InvalidPlainAttrValueException( + '\'' + value + "' is not one of: " + dropdownValues); + } + } + + default -> { + } + } + + attr.add(validator, value); + } catch (InvalidPlainAttrValueException e) { + LOG.warn("Invalid value for attribute {}: {}", + schema.getKey(), StringUtils.abbreviate(value, 20), e); + + invalidValues.getElements().add(schema.getKey() + ": " + value + " - " + e.getMessage()); + } + } + }); + } +} diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java index 2f85e4a9391..0e144e7f9fe 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java @@ -18,12 +18,11 @@ */ package org.apache.syncope.core.provisioning.java.data; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; @@ -56,13 +55,11 @@ import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; -import org.apache.syncope.core.persistence.api.entity.DerSchema; import org.apache.syncope.core.persistence.api.entity.DynGroupMembership; import org.apache.syncope.core.persistence.api.entity.EntityFactory; import org.apache.syncope.core.persistence.api.entity.Groupable; import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.RelationshipType; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.group.GRelationship; @@ -82,7 +79,7 @@ import org.springframework.transaction.annotation.Transactional; @Transactional(rollbackFor = { Throwable.class }) -public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupDataBinder { +public class GroupDataBinderImpl extends AnyDataBinder implements GroupDataBinder { protected final SearchCondVisitor searchCondVisitor; @@ -500,23 +497,15 @@ public GroupTO getGroupTO(final Group group, final boolean details) { groupTO.setLastChangeDate(group.getLastChangeDate()); groupTO.setLastChangeContext(group.getLastChangeContext()); - if (group.getUserOwner() != null) { - groupTO.setUserOwner(group.getUserOwner().getKey()); - } - if (group.getGroupOwner() != null) { - groupTO.setGroupOwner(group.getGroupOwner().getKey()); - } + Optional.ofNullable(group.getUserOwner()).map(User::getKey).ifPresent(groupTO::setUserOwner); + Optional.ofNullable(group.getGroupOwner()).map(Group::getKey).ifPresent(groupTO::setGroupOwner); - Map derAttrValues = derAttrHandler.getValues(group); - Map> virAttrValues = details - ? virAttrHandler.getValues(group) - : Collections.emptyMap(); fillTO(groupTO, group.getRealm().getFullPath(), group.getAuxClasses(), group.getPlainAttrs(), - derAttrValues, - virAttrValues, + derAttrHandler.getValues(group), + details ? virAttrHandler.getValues(group) : Map.of(), group.getResources()); // dynamic realms @@ -530,20 +519,18 @@ public GroupTO getGroupTO(final Group group, final boolean details) { groupTO.setDynamicUserMembershipCount(groupDAO.countUDynMembers(group)); groupTO.setDynamicAnyObjectMembershipCount(groupDAO.countADynMembers(group)); - if (group.getUDynMembership() != null) { - groupTO.setUDynMembershipCond(group.getUDynMembership().getFIQLCond()); - } + Optional.ofNullable(group.getUDynMembership()). + map(UDynGroupMembership::getFIQLCond). + ifPresent(groupTO::setUDynMembershipCond); group.getADynMemberships(). forEach(memb -> groupTO.getADynMembershipConds().put(memb.getAnyType().getKey(), memb.getFIQLCond())); - group.getTypeExtensions(). - forEach(typeExt -> groupTO.getTypeExtensions().add(getTypeExtensionTO(typeExt))); + group.getTypeExtensions().forEach(typeExt -> groupTO.getTypeExtensions().add(getTypeExtensionTO(typeExt))); if (details) { // relationships - groupTO.getRelationships().addAll(group.getRelationships().stream().map(relationship -> getRelationshipTO( - relationship.getType().getKey(), RelationshipTO.End.LEFT, relationship.getRightEnd())). - toList()); + groupTO.getRelationships().addAll(group.getRelationships().stream().map(r -> getRelationshipTO( + r.getType().getKey(), RelationshipTO.End.LEFT, r.getRightEnd())).toList()); } return groupTO; diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java index 03c60307202..6e7e4097e5a 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java @@ -18,19 +18,34 @@ */ package org.apache.syncope.core.provisioning.java.data; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.syncope.common.lib.Attr; +import org.apache.syncope.common.lib.SyncopeClientCompositeException; +import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.to.RealmTO; +import org.apache.syncope.common.lib.types.AttrSchemaType; import org.apache.syncope.common.lib.types.ClientExceptionType; import org.apache.syncope.common.lib.types.ResourceOperation; +import org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValidationManager; +import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO; import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO; import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; import org.apache.syncope.core.persistence.api.dao.ImplementationDAO; +import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.dao.PolicyDAO; import org.apache.syncope.core.persistence.api.dao.RealmDAO; import org.apache.syncope.core.persistence.api.entity.AnyTemplateRealm; +import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.EntityFactory; import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.Implementation; +import org.apache.syncope.core.persistence.api.entity.PlainAttr; +import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; +import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy; import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy; @@ -38,18 +53,22 @@ import org.apache.syncope.core.persistence.api.entity.policy.AuthPolicy; import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy; import org.apache.syncope.core.persistence.api.entity.policy.TicketExpirationPolicy; +import org.apache.syncope.core.provisioning.api.DerAttrHandler; +import org.apache.syncope.core.provisioning.api.IntAttrName; +import org.apache.syncope.core.provisioning.api.IntAttrNameParser; +import org.apache.syncope.core.provisioning.api.MappingManager; import org.apache.syncope.core.provisioning.api.PropagationByResource; import org.apache.syncope.core.provisioning.api.data.RealmDataBinder; +import org.apache.syncope.core.provisioning.api.jexl.JexlUtils; +import org.apache.syncope.core.provisioning.java.utils.MappingUtils; import org.apache.syncope.core.provisioning.java.utils.TemplateUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -public class RealmDataBinderImpl implements RealmDataBinder { - - protected static final Logger LOG = LoggerFactory.getLogger(RealmDataBinder.class); +public class RealmDataBinderImpl extends AttributableDataBinder implements RealmDataBinder { protected final AnyTypeDAO anyTypeDAO; + protected final AnyTypeClassDAO anyTypeClassDAO; + protected final ImplementationDAO implementationDAO; protected final RealmDAO realmDAO; @@ -62,13 +81,21 @@ public class RealmDataBinderImpl implements RealmDataBinder { public RealmDataBinderImpl( final AnyTypeDAO anyTypeDAO, + final AnyTypeClassDAO anyTypeClassDAO, final ImplementationDAO implementationDAO, final RealmDAO realmDAO, final PolicyDAO policyDAO, final ExternalResourceDAO resourceDAO, - final EntityFactory entityFactory) { - + final PlainSchemaDAO plainSchemaDAO, + final EntityFactory entityFactory, + final DerAttrHandler derAttrHandler, + final PlainAttrValidationManager validator, + final MappingManager mappingManager, + final IntAttrNameParser intAttrNameParser) { + + super(plainSchemaDAO, validator, derAttrHandler, mappingManager, intAttrNameParser); this.anyTypeDAO = anyTypeDAO; + this.anyTypeClassDAO = anyTypeClassDAO; this.implementationDAO = implementationDAO; this.realmDAO = realmDAO; this.policyDAO = policyDAO; @@ -76,7 +103,79 @@ public RealmDataBinderImpl( this.entityFactory = entityFactory; } - protected void setTemplates(final RealmTO realmTO, final Realm realm) { + protected void fill( + final RealmTO realmTO, + final Realm realm, + final SyncopeClientCompositeException scce) { + + realm.getPlainAttrs().forEach(realm::remove); + + SyncopeClientException invalidValues = SyncopeClientException.build(ClientExceptionType.InvalidValues); + + realmTO.getPlainAttrs().stream(). + filter(attrTO -> !attrTO.getValues().isEmpty()). + forEach(attrTO -> getPlainSchema(attrTO.getSchema()).ifPresent(schema -> { + + PlainAttr attr = realm.getPlainAttr(schema.getKey()).orElseGet(() -> { + PlainAttr newAttr = new PlainAttr(); + newAttr.setPlainSchema(schema); + return newAttr; + }); + fillAttr(realmTO, attrTO.getValues(), schema, attr, invalidValues); + + if (!attr.getValuesAsStrings().isEmpty()) { + realm.add(attr); + } + })); + + if (!invalidValues.isEmpty()) { + scce.addException(invalidValues); + } + + SyncopeClientException reqValMissing = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing); + // Check if there is some mandatory schema defined for which no value has been provided + realm.getAnyTypeClass().getPlainSchemas().forEach(schema -> checkMandatory( + schema, realm.getPlainAttr(schema.getKey()).orElse(null), realm, reqValMissing)); + if (!reqValMissing.isEmpty()) { + scce.addException(reqValMissing); + } + } + + protected void bind(final Realm realm, final RealmTO realmTO, final SyncopeClientCompositeException scce) { + realm.setName(realmTO.getName()); + + if (realmTO.getAnyTypeClass() == null) { + realm.setAnyTypeClass(null); + } else { + anyTypeClassDAO.findById(realmTO.getAnyTypeClass()).ifPresentOrElse( + realm::setAnyTypeClass, + () -> LOG.debug("Invalid {} {}, ignoring...", + AnyTypeClass.class.getSimpleName(), realmTO.getAnyTypeClass())); + } + if (realm.getAnyTypeClass() != null) { + fill(realmTO, realm, scce); + } + + realm.setAccessPolicy(Optional.ofNullable(realmTO.getAccessPolicy()). + flatMap(p -> policyDAO.findById(p, AccessPolicy.class)).orElse(null)); + realm.setAccountPolicy(Optional.ofNullable(realmTO.getAccountPolicy()). + flatMap(p -> policyDAO.findById(p, AccountPolicy.class)).orElse(null)); + realm.setAttrReleasePolicy(Optional.ofNullable(realmTO.getAttrReleasePolicy()). + flatMap(p -> policyDAO.findById(p, AttrReleasePolicy.class)).orElse(null)); + realm.setAuthPolicy(Optional.ofNullable(realmTO.getAuthPolicy()). + flatMap(p -> policyDAO.findById(p, AuthPolicy.class)).orElse(null)); + realm.setPasswordPolicy(Optional.ofNullable(realmTO.getPasswordPolicy()). + flatMap(p -> policyDAO.findById(p, PasswordPolicy.class)).orElse(null)); + realm.setTicketExpirationPolicy(Optional.ofNullable(realmTO.getTicketExpirationPolicy()). + flatMap(p -> policyDAO.findById(p, TicketExpirationPolicy.class)).orElse(null)); + + realmTO.getActions().forEach(key -> implementationDAO.findById(key).ifPresentOrElse( + realm::add, + () -> LOG.debug("Invalid {} {}, ignoring...", Implementation.class.getSimpleName(), key))); + // remove all implementations not contained in the TO + realm.getActions(). + removeIf(implementation -> !realmTO.getActions().contains(implementation.getKey())); + // validate JEXL expressions from templates and proceed if fine TemplateUtils.check(realmTO.getTemplates(), ClientExceptionType.InvalidRealm); realmTO.getTemplates().forEach((key, template) -> anyTypeDAO.findById(key).ifPresentOrElse( @@ -95,79 +194,93 @@ protected void setTemplates(final RealmTO realmTO, final Realm realm) { // remove all templates not contained in the TO realm.getTemplates(). removeIf(template -> !realmTO.getTemplates().containsKey(template.getAnyType().getKey())); + + // Throw composite exception if there is at least one element set in the composing exceptions + if (scce.hasExceptions()) { + throw scce; + } } - @Override - public Realm create(final Realm parent, final RealmTO realmTO) { - Realm realm = entityFactory.newEntity(Realm.class); + protected List evaluateMandatoryCondition(final ExternalResource resource, final Realm realm) { + if (resource.getOrgUnit() == null) { + return List.of(); + } - realm.setName(realmTO.getName()); - realm.setParent(parent); + List missingAttrNames = new ArrayList<>(); - realm.setPasswordPolicy(realmTO.getPasswordPolicy() == null - ? null : policyDAO.findById(realmTO.getPasswordPolicy(), PasswordPolicy.class).orElse(null)); + MappingUtils.getPropagationItems(resource.getOrgUnit().getItems().stream()).forEach(item -> { + IntAttrName intAttrName = null; + try { + intAttrName = intAttrNameParser.parse(item.getIntAttrName()); + } catch (ParseException e) { + LOG.error("Invalid intAttrName '{}', ignoring", item.getIntAttrName(), e); + } + if (intAttrName != null && intAttrName.getSchema() != null) { + AttrSchemaType schemaType = intAttrName.getSchema() instanceof PlainSchema + ? intAttrName.getSchema().getType() + : AttrSchemaType.String; + + Pair> intValues = mappingManager.getIntValues( + resource, + item, + intAttrName, + schemaType, + realm); + if (intValues.getRight().isEmpty() + && JexlUtils.evaluateMandatoryCondition(item.getMandatoryCondition(), realm, derAttrHandler)) { + + missingAttrNames.add(item.getIntAttrName()); + } + } + }); - realm.setAccountPolicy(realmTO.getAccountPolicy() == null - ? null : policyDAO.findById(realmTO.getAccountPolicy(), AccountPolicy.class).orElse(null)); + return missingAttrNames; + } - realm.setAuthPolicy(realmTO.getAuthPolicy() == null - ? null : policyDAO.findById(realmTO.getAuthPolicy(), AuthPolicy.class).orElse(null)); + protected SyncopeClientException checkMandatoryOnResources(final Realm realm) { + SyncopeClientException reqValMissing = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing); - realm.setAccessPolicy(realmTO.getAccessPolicy() == null - ? null : policyDAO.findById(realmTO.getAccessPolicy(), AccessPolicy.class).orElse(null)); + realm.getResources().stream().filter(ExternalResource::isEnforceMandatoryCondition). + forEach(resource -> { + List missingAttrNames = evaluateMandatoryCondition(resource, realm); + if (!missingAttrNames.isEmpty()) { + LOG.error("Mandatory schemas {} not provided with values", missingAttrNames); - realm.setAttrReleasePolicy(realmTO.getAttrReleasePolicy() == null - ? null : policyDAO.findById(realmTO.getAttrReleasePolicy(), AttrReleasePolicy.class).orElse(null)); + reqValMissing.getElements().addAll(missingAttrNames); + } + }); - realm.setTicketExpirationPolicy(realmTO.getTicketExpirationPolicy() == null - ? null - : policyDAO.findById(realmTO.getTicketExpirationPolicy(), TicketExpirationPolicy.class).orElse(null)); + return reqValMissing; + } - realmTO.getActions().forEach(key -> implementationDAO.findById(key).ifPresentOrElse( - realm::add, - () -> LOG.debug("Invalid {} {}, ignoring...", Implementation.class.getSimpleName(), key))); + @Override + public Realm create(final Realm parent, final RealmTO realmTO) { + Realm realm = entityFactory.newEntity(Realm.class); + realm.setParent(parent); + + SyncopeClientCompositeException scce = SyncopeClientException.buildComposite(); - setTemplates(realmTO, realm); + bind(realm, realmTO, scce); realmTO.getResources().forEach(key -> resourceDAO.findById(key).ifPresentOrElse( realm::add, () -> LOG.debug("Invalid {} {}, ignoring...", ExternalResource.class.getSimpleName(), key))); + SyncopeClientException requiredValuesMissing = checkMandatoryOnResources(realm); + if (!requiredValuesMissing.isEmpty()) { + scce.addException(requiredValuesMissing); + } + return realm; } @Override public PropagationByResource update(final Realm realm, final RealmTO realmTO) { - realm.setName(realmTO.getName()); - realm.setParent(realmTO.getParent() == null ? null : realmDAO.findById(realmTO.getParent()).orElse(null)); - - realm.setPasswordPolicy(realmTO.getPasswordPolicy() == null - ? null : policyDAO.findById(realmTO.getPasswordPolicy(), PasswordPolicy.class).orElse(null)); - - realm.setAccountPolicy(realmTO.getAccountPolicy() == null - ? null : policyDAO.findById(realmTO.getAccountPolicy(), AccountPolicy.class).orElse(null)); - - realm.setAuthPolicy(realmTO.getAuthPolicy() == null - ? null : policyDAO.findById(realmTO.getAuthPolicy(), AuthPolicy.class).orElse(null)); - - realm.setAccessPolicy(realmTO.getAccessPolicy() == null - ? null : policyDAO.findById(realmTO.getAccessPolicy(), AccessPolicy.class).orElse(null)); + realm.setParent(Optional.ofNullable(realmTO.getParent()).flatMap(realmDAO::findById).orElse(null)); - realm.setAttrReleasePolicy(realmTO.getAttrReleasePolicy() == null - ? null : policyDAO.findById(realmTO.getAttrReleasePolicy(), AttrReleasePolicy.class).orElse(null)); + SyncopeClientCompositeException scce = SyncopeClientException.buildComposite(); - realm.setTicketExpirationPolicy(realmTO.getTicketExpirationPolicy() == null - ? null - : policyDAO.findById(realmTO.getTicketExpirationPolicy(), TicketExpirationPolicy.class).orElse(null)); - - realmTO.getActions().forEach(key -> implementationDAO.findById(key).ifPresentOrElse( - realm::add, - () -> LOG.debug("Invalid {} {}, ignoring...", Implementation.class.getSimpleName(), key))); - // remove all implementations not contained in the TO - realm.getActions(). - removeIf(implementation -> !realmTO.getActions().contains(implementation.getKey())); - - setTemplates(realmTO, realm); + bind(realm, realmTO, scce); PropagationByResource propByRes = new PropagationByResource<>(); realmTO.getResources().forEach(key -> resourceDAO.findById(key).ifPresentOrElse( @@ -185,6 +298,11 @@ public PropagationByResource update(final Realm realm, final RealmTO rea return !contained; }); + SyncopeClientException requiredValuesMissing = checkMandatoryOnResources(realm); + if (!requiredValuesMissing.isEmpty()) { + scce.addException(requiredValuesMissing); + } + return propByRes; } @@ -196,27 +314,34 @@ public RealmTO getRealmTO(final Realm realm, final boolean admin) { realmTO.setName(realm.getName()); Optional.ofNullable(realm.getParent()).ifPresent(parent -> realmTO.setParent(parent.getKey())); realmTO.setFullPath(realm.getFullPath()); + Optional.ofNullable(realm.getAnyTypeClass()).map(AnyTypeClass::getKey).ifPresent(realmTO::setAnyTypeClass); + + realm.getPlainAttrs().forEach(plainAttr -> realmTO.getPlainAttrs(). + add(new Attr.Builder(plainAttr.getSchema()).values(plainAttr.getValuesAsStrings()).build())); + + derAttrHandler.getValues(realm).forEach((schema, value) -> realmTO.getDerAttrs(). + add(new Attr.Builder(schema.getKey()).value(value).build())); if (admin) { - Optional.ofNullable(realm.getAccountPolicy()). - ifPresent(policy -> realmTO.setAccountPolicy(policy.getKey())); - Optional.ofNullable(realm.getPasswordPolicy()). - ifPresent(policy -> realmTO.setPasswordPolicy(policy.getKey())); - Optional.ofNullable(realm.getAuthPolicy()). - ifPresent(policy -> realmTO.setAuthPolicy(policy.getKey())); - Optional.ofNullable(realm.getAccessPolicy()). - ifPresent(policy -> realmTO.setAccessPolicy(policy.getKey())); - Optional.ofNullable(realm.getAttrReleasePolicy()). - ifPresent(policy -> realmTO.setAttrReleasePolicy(policy.getKey())); - Optional.ofNullable(realm.getTicketExpirationPolicy()). - ifPresent(policy -> realmTO.setTicketExpirationPolicy(policy.getKey())); - - realm.getActions().forEach(action -> realmTO.getActions().add(action.getKey())); + Optional.ofNullable(realm.getAccountPolicy()).map(AccountPolicy::getKey). + ifPresent(realmTO::setAccountPolicy); + Optional.ofNullable(realm.getPasswordPolicy()).map(PasswordPolicy::getKey). + ifPresent(realmTO::setPasswordPolicy); + Optional.ofNullable(realm.getAuthPolicy()).map(AuthPolicy::getKey). + ifPresent(realmTO::setAuthPolicy); + Optional.ofNullable(realm.getAccessPolicy()).map(AccessPolicy::getKey). + ifPresent(realmTO::setAccessPolicy); + Optional.ofNullable(realm.getAttrReleasePolicy()).map(AttrReleasePolicy::getKey). + ifPresent(realmTO::setAttrReleasePolicy); + Optional.ofNullable(realm.getTicketExpirationPolicy()).map(TicketExpirationPolicy::getKey). + ifPresent(realmTO::setTicketExpirationPolicy); + + realmTO.getActions().addAll(realm.getActions().stream().map(Implementation::getKey).toList()); realm.getTemplates().forEach( template -> realmTO.getTemplates().put(template.getAnyType().getKey(), template.get())); - realm.getResources().forEach(resource -> realmTO.getResources().add(resource.getKey())); + realmTO.getResources().addAll(realm.getResources().stream().map(ExternalResource::getKey).toList()); } return realmTO; diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java index 617fac3fd04..bc74dbba623 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java @@ -222,20 +222,13 @@ public ExternalResource update(final ExternalResource resource, final ResourceTO } if (provisionTO.getVirSchemas().isEmpty()) { - for (VirSchema s : virSchemaDAO.findByResourceAndAnyType(resource.getKey(), anyType.getKey())) { - virSchemaDAO.delete(s); - } + virSchemaDAO.findByResourceAndAnyType(resource.getKey(), anyType.getKey()). + forEach(virSchemaDAO::delete); } else { - for (String schemaName : provisionTO.getVirSchemas()) { - VirSchema schema = virSchemaDAO.findById(schemaName).orElse(null); - if (schema == null) { - LOG.debug("Invalid {} specified: {}, ignoring...", - VirSchema.class.getSimpleName(), schemaName); - } else { - schema.setResource(resource); - schema.setAnyType(anyType); - } - } + provisionTO.getVirSchemas().forEach(schemaName -> virSchemaDAO.findById(schemaName).ifPresentOrElse( + schema -> schema.setResource(resource), + () -> LOG.debug("Invalid {} specified: {}, ignoring...", + VirSchema.class.getSimpleName(), schemaName))); } } }); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java index 578b6094dab..e06e8c93d9c 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java @@ -93,7 +93,7 @@ import org.springframework.transaction.annotation.Transactional; @Transactional(rollbackFor = { Throwable.class }) -public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDataBinder { +public class UserDataBinderImpl extends AnyDataBinder implements UserDataBinder { protected final RoleDAO roleDAO; @@ -774,9 +774,8 @@ public UserTO getUserTO(final User user, final boolean details) { userDAO.findDynRoles(user.getKey()).stream().map(Role::getKey).toList()); // relationships - userTO.getRelationships().addAll(user.getRelationships().stream().map(relationship -> getRelationshipTO( - relationship.getType().getKey(), RelationshipTO.End.LEFT, relationship.getRightEnd())). - toList()); + userTO.getRelationships().addAll(user.getRelationships().stream().map(r -> getRelationshipTO( + r.getType().getKey(), RelationshipTO.End.LEFT, r.getRightEnd())).toList()); // memberships userTO.getMemberships().addAll(user.getMemberships().stream(). @@ -792,8 +791,7 @@ public UserTO getUserTO(final User user, final boolean details) { // linked accounts userTO.getLinkedAccounts().addAll(user.getLinkedAccounts().stream(). - map(account -> getLinkedAccountTO(account, returnPasswordValue)). - toList()); + map(account -> getLinkedAccountTO(account, returnPasswordValue)).toList()); // delegations userTO.getDelegatingDelegations().addAll( diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationManager.java index 3dfb59c3f4b..6e4001fe0ab 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationManager.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationManager.java @@ -26,6 +26,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; @@ -49,6 +50,7 @@ import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.VirSchema; +import org.apache.syncope.core.persistence.api.entity.policy.PropagationPolicy; import org.apache.syncope.core.persistence.api.entity.task.PropagationData; import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; import org.apache.syncope.core.persistence.api.entity.user.User; @@ -564,7 +566,7 @@ protected List createTasks( mappingItems, Pair.of(account.getConnObjectKeyValue(), mappingManager.prepareAttrsFromLinkedAccount( - user, account, password, + user, account, password, changePwdRes.contains(account.getResource().getKey()), provision))); tasks.add(accountTask); @@ -609,7 +611,7 @@ public List createTasks( LOG.warn("Requesting propagation for {} but no ConnObjectLink provided for {}", realm.getFullPath(), resource); } else { - Pair> preparedAttrs = mappingManager.prepareAttrsFromRealm(realm, orgUnit); + Pair> preparedAttrs = mappingManager.prepareAttrsFromRealm(realm, resource); PropagationTaskInfo task = new PropagationTaskInfo( resource, @@ -631,8 +633,7 @@ public List createTasks( return tasks; } - @Transactional(readOnly = true, - propagation = Propagation.REQUIRES_NEW) + @Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW) @Override public Map, Set> prepareAttrs( final AnyTypeKind kind, @@ -647,64 +648,68 @@ public Map, Set> prepareAttrs( Any any = anyUtilsFactory.getInstance(kind).dao().authFind(key); anyUtilsFactory.getInstance(kind).dao().findAllResourceKeys(key).stream(). + filter(Predicate.not(excludedResources::contains)). map(resourceDAO::findById). flatMap(Optional::stream). - filter(resource -> !excludedResources.contains(resource.getKey()) - && resource.getProvisionByAnyType(any.getType().getKey()).isPresent() - && resource.getPropagationPolicy() != null && resource.getPropagationPolicy().isUpdateDelta()). - forEach(resource -> { + filter(resource -> Optional.ofNullable(resource.getPropagationPolicy()). + map(PropagationPolicy::isUpdateDelta).orElse(false)). + forEach(resource -> resource.getProvisionByAnyType(any.getType().getKey()). + ifPresent(provision -> { Pair> preparedAttrs = mappingManager.prepareAttrsFromAny( any, password, changePwdRes.contains(resource.getKey()), enable, resource, - resource.getProvisionByAnyType(any.getType().getKey()).get()); + provision); attrs.put( Pair.of(resource.getKey(), preparedAttrs.getLeft()), preparedAttrs.getRight()); - }); + })); if (any instanceof User user) { user.getLinkedAccounts().stream(). filter(account -> !excludedResources.contains(account.getResource().getKey()) - && account.getResource().getProvisionByAnyType(any.getType().getKey()).isPresent() - && account.getResource().getPropagationPolicy() != null - && account.getResource().getPropagationPolicy().isUpdateDelta()). - forEach(account -> { - Set preparedAttrs = mappingManager.prepareAttrsFromLinkedAccount(user, + && account.getResource().getProvisionByAnyType(user.getType().getKey()).isPresent() + && Optional.ofNullable(account.getResource().getPropagationPolicy()). + map(PropagationPolicy::isUpdateDelta).orElse(false)). + forEach(account -> account.getResource().getProvisionByAnyType(user.getType().getKey()). + ifPresent(provision -> { + Set preparedAttrs = mappingManager.prepareAttrsFromLinkedAccount( + user, account, password, true, - account.getResource().getProvisionByAnyType(any.getType().getKey()).get()); + provision); attrs.put( Pair.of(account.getResource().getKey(), account.getConnObjectKeyValue()), preparedAttrs); - }); + })); } LOG.debug("Prepared attrs for {} {}: {}", kind, key, attrs); return attrs; } - @Transactional(readOnly = true, - propagation = Propagation.REQUIRES_NEW) + @Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW) @Override public Map, Set> prepareAttrs(final Realm realm) { Map, Set> attrs = new HashMap<>(); realm.getResources().stream(). filter(resource -> resource.getOrgUnit() != null - && resource.getPropagationPolicy() != null && resource.getPropagationPolicy().isUpdateDelta()). + && Optional.ofNullable(resource.getPropagationPolicy()). + map(PropagationPolicy::isUpdateDelta).orElse(false)). forEach(resource -> { Pair> preparedAttrs = mappingManager.prepareAttrsFromRealm( realm, - resource.getOrgUnit()); + resource); attrs.put( Pair.of(resource.getKey(), preparedAttrs.getLeft()), preparedAttrs.getRight()); }); + LOG.debug("Prepared attrs for Realm {}: {}", realm.getKey(), attrs); return attrs; } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java index 5510823ce6d..337c0919715 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java @@ -44,6 +44,7 @@ import org.apache.syncope.core.persistence.api.dao.search.AnyCond; import org.apache.syncope.core.persistence.api.dao.search.AttrCond; import org.apache.syncope.core.persistence.api.dao.search.SearchCond; +import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.task.PullTask; import org.apache.syncope.core.provisioning.api.PropagationByResource; @@ -244,7 +245,9 @@ protected OpEvent.Outcome create( Realm realm = realmDAO.save(binder.create(profile.getTask().getDestinationRealm(), realmTO)); PropagationByResource propByRes = new PropagationByResource<>(); - propByRes.addAll(ResourceOperation.CREATE, realm.getResourceKeys()); + propByRes.addAll( + ResourceOperation.CREATE, + realm.getResources().stream().map(ExternalResource::getKey).toList()); if (unmatchingRule == UnmatchingRule.ASSIGN) { List taskInfos = propagationManager.createTasks(realm, propByRes, null); taskExecutor.execute(taskInfos, false, securityProperties.getAdminUser()); @@ -595,7 +598,9 @@ protected OpEvent.Outcome delete(final SyncDelta delta, final List realms } PropagationByResource propByRes = new PropagationByResource<>(); - propByRes.addAll(ResourceOperation.DELETE, realm.getResourceKeys()); + propByRes.addAll( + ResourceOperation.DELETE, + realm.getResources().stream().map(ExternalResource::getKey).toList()); List taskInfos = propagationManager.createTasks(realm, propByRes, null); taskExecutor.execute(taskInfos, false, securityProperties.getAdminUser()); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java index d34052edcd7..dbef61180f5 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java @@ -38,6 +38,7 @@ import org.apache.syncope.common.lib.types.ResourceOperation; import org.apache.syncope.common.lib.types.UnmatchingRule; import org.apache.syncope.core.persistence.api.dao.NotFoundException; +import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.task.PushTask; import org.apache.syncope.core.provisioning.api.MappingManager; @@ -168,11 +169,14 @@ private Realm update(final RealmTO realmTO, final ConnectorObject beforeObj, fin } private void deprovision(final Realm realm, final ConnectorObject beforeObj, final ProvisioningReport result) { - List noPropResources = new ArrayList<>(realm.getResourceKeys()); + List noPropResources = new ArrayList<>( + realm.getResources().stream().map(ExternalResource::getKey).toList()); noPropResources.remove(profile.getTask().getResource().getKey()); PropagationByResource propByRes = new PropagationByResource<>(); - propByRes.addAll(ResourceOperation.DELETE, realm.getResourceKeys()); + propByRes.addAll( + ResourceOperation.DELETE, + realm.getResources().stream().map(ExternalResource::getKey).toList()); List taskInfos = propagationManager.createTasks(realm, propByRes, noPropResources); if (!taskInfos.isEmpty()) { @@ -184,7 +188,8 @@ private void deprovision(final Realm realm, final ConnectorObject beforeObj, fin } private void provision(final Realm realm, final ProvisioningReport result) { - List noPropResources = new ArrayList<>(realm.getResourceKeys()); + List noPropResources = new ArrayList<>( + realm.getResources().stream().map(ExternalResource::getKey).toList()); noPropResources.remove(profile.getTask().getResource().getKey()); PropagationByResource propByRes = new PropagationByResource<>(); @@ -261,7 +266,8 @@ private void doHandle(final Realm realm) throws JobExecutionException { // Try to read remote object BEFORE any actual operation OrgUnit orgUnit = profile.getTask().getResource().getOrgUnit(); Optional connObjectKey = orgUnit.getConnObjectKeyItem(); - Optional connObjecKeyValue = mappingManager.getConnObjectKeyValue(realm, orgUnit); + Optional connObjecKeyValue = mappingManager.getConnObjectKeyValue( + realm, profile.getTask().getResource()); ConnectorObject beforeObj = null; if (connObjectKey.isPresent() && connObjecKeyValue.isPresent()) { diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java index 00b591c1f94..19c90a401d0 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java @@ -229,8 +229,7 @@ public List match( resource, provision, effectiveMATG, - ArrayUtils.isEmpty(linkingItems) - ? Optional.empty() : Optional.of(List.of(linkingItems))). + ArrayUtils.isEmpty(linkingItems) ? Optional.empty() : Optional.of(List.of(linkingItems))). ifPresent(result::add); } } @@ -297,10 +296,9 @@ public Optional matchByConnObjectKeyValue( Stream items = Stream.concat( provision.getMapping().getItems().stream(), - linkingItems.isPresent() - ? linkingItems.get().stream() - : virSchemaDAO.findByResourceAndAnyType(resource.getKey(), provision.getAnyType()).stream(). - map(VirSchema::asLinkingMappingItem)); + linkingItems.map(Collection::stream). + orElseGet(() -> virSchemaDAO.findByResourceAndAnyType( + resource.getKey(), provision.getAnyType()).stream().map(VirSchema::asLinkingMappingItem))); ConnectorObject obj = null; try { diff --git a/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCClient.properties b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCC4UI.properties similarity index 100% rename from ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCClient.properties rename to ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCC4UI.properties diff --git a/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCC4UI_it.properties b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCC4UI_it.properties index b34f11c3667..e78fe314b36 100644 --- a/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCC4UI_it.properties +++ b/ext/oidcc4ui/client-console/src/main/resources/org/apache/syncope/client/console/pages/OIDCC4UI_it.properties @@ -14,4 +14,4 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -op=OIDC Providers +op=Provider OIDC diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java index 9b03cc1def7..056be0c7bdc 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/PoliciesITCase.java @@ -742,8 +742,8 @@ public void issueSYNCOPE1030() { TESTER.assertRenderedPage(Realms.class); // edit root realm - TESTER.clickLink( - "body:content:body:container:content:tabbedPanel:panel:actions:actions:actionRepeater:1:action:action"); + TESTER.clickLink("body:content:body:container:content:tabbedPanel:panel:" + + "actionsPanel:actions:actionRepeater:1:action:action"); TESTER.assertComponent("body:content:body:outerObjectsRepeater:0:outer", Modal.class); // set new account policy diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java index 255dc2e64bf..b04da889fe7 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/RealmsITCase.java @@ -49,8 +49,8 @@ public void read() { @Test public void create() { - TESTER.clickLink( - "body:content:body:container:content:tabbedPanel:panel:actions:actions:actionRepeater:0:action:action"); + TESTER.clickLink("body:content:body:container:content:tabbedPanel:panel:" + + "actionsPanel:actions:actionRepeater:0:action:action"); TESTER.assertComponent("body:content:body:outerObjectsRepeater:0:outer", Modal.class); FormTester formTester = TESTER.newFormTester( @@ -79,8 +79,8 @@ public void create() { assertTrue(TESTER.getLastResponseAsString().contains(">testRealm")); TESTER.getRequest().addParameter("confirm", "true"); - TESTER.clickLink( - "body:content:body:container:content:tabbedPanel:panel:actions:actions:actionRepeater:3:action:action"); + TESTER.clickLink("body:content:body:container:content:tabbedPanel:panel:" + + "actionsPanel:actions:actionRepeater:3:action:action"); assertSuccessMessage(); TESTER.cleanupFeedbackMessages(); @@ -95,8 +95,8 @@ public void create() { @Test public void update() { - TESTER.clickLink( - "body:content:body:container:content:tabbedPanel:panel:actions:actions:actionRepeater:1:action:action"); + TESTER.clickLink("body:content:body:container:content:tabbedPanel:panel:" + + "actionsPanel:actions:actionRepeater:1:action:action"); TESTER.assertComponent("body:content:body:outerObjectsRepeater:0:outer", Modal.class); FormTester formTester = TESTER.newFormTester( @@ -123,8 +123,8 @@ public void addUserTemplate() { assertTrue(TESTER.getLastResponseAsString().contains(">/")); assertTrue(TESTER.getLastResponseAsString().contains(">odd")); - TESTER.clickLink( - "body:content:body:container:content:tabbedPanel:panel:actions:actions:actionRepeater:2:action:action"); + TESTER.clickLink("body:content:body:container:content:tabbedPanel:panel:" + + "actionsPanel:actions:actionRepeater:2:action:action"); TESTER.assertComponent("body:content:toggleTemplates", TogglePanel.class); FormTester formTester = TESTER.newFormTester( @@ -144,8 +144,8 @@ public void addUserTemplate() { assertTrue(TESTER.getLastResponseAsString().contains(">/")); assertTrue(TESTER.getLastResponseAsString().contains(">odd")); - TESTER.clickLink( - "body:content:body:container:content:tabbedPanel:panel:actions:actions:actionRepeater:2:action:action"); + TESTER.clickLink("body:content:body:container:content:tabbedPanel:panel:" + + "actionsPanel:actions:actionRepeater:2:action:action"); TESTER.assertComponent("body:content:toggleTemplates", TogglePanel.class); formTester = TESTER.newFormTester( @@ -174,8 +174,8 @@ public void verifyPropagation() { + ":realmsFragment:realms:dropdown-menu:buttons:2:button", Constants.ON_CLICK); - TESTER.clickLink( - "body:content:body:container:content:tabbedPanel:panel:actions:actions:actionRepeater:1:action:action"); + TESTER.clickLink("body:content:body:container:content:tabbedPanel:panel:" + + "actionsPanel:actions:actionRepeater:1:action:action"); TESTER.assertComponent("body:content:body:outerObjectsRepeater:0:outer", Modal.class); TESTER.assertModelValue( "body:content:body:outerObjectsRepeater:0:outer:form:content:form:view:details:" @@ -227,8 +227,8 @@ public void verifyPropagation() { "body:content:body:outerObjectsRepeater:0:outer:form:content:action:actionRepeater:" + "0:action:action", Constants.ON_CLICK); - TESTER.clickLink( - "body:content:body:container:content:tabbedPanel:panel:actions:actions:actionRepeater:1:action:action"); + TESTER.clickLink("body:content:body:container:content:tabbedPanel:panel:" + + "actionsPanel:actions:actionRepeater:1:action:action"); TESTER.assertComponent("body:content:body:outerObjectsRepeater:0:outer", Modal.class); TESTER.assertModelValue( "body:content:body:outerObjectsRepeater:0:outer:form:content:form:view:details:" @@ -253,19 +253,19 @@ public void verifyPropagation() { TESTER.assertLabel( "body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:" - + "secondLevelContainer:second:remoteObject:propView:4:value:leftAttribute:field-label", "ou"); + + "secondLevelContainer:second:remoteObject:propView:5:value:leftAttribute:field-label", "ou"); TESTER.assertModelValue( "body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:" - + "secondLevelContainer:second:remoteObject:propView:4:value:leftAttribute:textField", "even"); + + "secondLevelContainer:second:remoteObject:propView:5:value:leftAttribute:textField", "even"); TESTER.assertLabel( "body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:" - + "secondLevelContainer:second:remoteObject:propView:4:value:rightAttribute:field-label", "ou"); + + "secondLevelContainer:second:remoteObject:propView:5:value:rightAttribute:field-label", "ou"); TESTER.assertModelValue( "body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:" - + "secondLevelContainer:second:remoteObject:propView:4:value:rightAttribute:textField", null); + + "secondLevelContainer:second:remoteObject:propView:5:value:rightAttribute:textField", null); TESTER.clickLink("body:content:body:outerObjectsRepeater:0:outer:form:content:customResultBody:" + "secondLevelContainer:back"); diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java index be1f5a66eb4..1e1a30bdc42 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java @@ -26,12 +26,14 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; +import com.unboundid.ldap.sdk.SearchResultEntry; import jakarta.ws.rs.NotFoundException; import jakarta.ws.rs.core.GenericType; import jakarta.ws.rs.core.Response; import java.util.List; import java.util.Optional; import java.util.UUID; +import org.apache.syncope.common.lib.Attr; import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.SyncopeConstants; import org.apache.syncope.common.lib.policy.AccessPolicyTO; @@ -336,10 +338,16 @@ public void propagate() { // 1. create realm and add the LDAP resource RealmTO realm = new RealmTO(); realm.setName("test"); + realm.setAnyTypeClass("other"); + realm.getPlainAttrs().add(new Attr.Builder("ctype").value("number1").build()); realm.getResources().add(RESOURCE_NAME_LDAP_ORGUNIT); + RealmTO childRealm = new RealmTO(); childRealm.setName("child"); + childRealm.setAnyTypeClass("other"); + childRealm.getPlainAttrs().add(new Attr.Builder("ctype").value("number2").build()); childRealm.getResources().add(RESOURCE_NAME_LDAP_ORGUNIT); + RealmTO descendantRealm = new RealmTO(); descendantRealm.setName("test"); descendantRealm.getResources().add(RESOURCE_NAME_LDAP_ORGUNIT); @@ -369,16 +377,27 @@ public void propagate() { assertEquals(ExecStatus.SUCCESS, resultDescendant.getPropagationStatuses().getFirst().getStatus()); // 3. check on LDAP - assertNotNull(getLdapRemoteObject("ou=test,o=isp")); - assertNotNull(getLdapRemoteObject("ou=child,ou=test,o=isp")); - assertNotNull(getLdapRemoteObject("ou=test,ou=child,ou=test,o=isp")); + SearchResultEntry testOnLDAP = getLdapRemoteObject("ou=test,o=isp"); + assertNotNull(testOnLDAP); + assertEquals("/test", testOnLDAP.getAttribute("l").getValue()); + assertEquals("number1", testOnLDAP.getAttribute("description").getValue()); + + SearchResultEntry childOnLDAP = getLdapRemoteObject("ou=child,ou=test,o=isp"); + assertNotNull(childOnLDAP); + assertEquals("/test/child", childOnLDAP.getAttribute("l").getValue()); + assertEquals("number2", childOnLDAP.getAttribute("description").getValue()); + + testOnLDAP = getLdapRemoteObject("ou=test,ou=child,ou=test,o=isp"); + assertNotNull(testOnLDAP); + assertEquals("/test/child/test", testOnLDAP.getAttribute("l").getValue()); + assertNull(testOnLDAP.getAttribute("description")); // 4. remove realms REALM_SERVICE.delete("/test/child/test"); REALM_SERVICE.delete("/test/child"); REALM_SERVICE.delete("/test"); - // 5. check on LDAP: both realms should be deleted + // 5. check on LDAP: all ou are now deleted assertNull(getLdapRemoteObject("ou=test,ou=child,ou=test,o=isp")); assertNull(getLdapRemoteObject("ou=child,ou=test,o=isp")); assertNull(getLdapRemoteObject("ou=test,o=isp")); diff --git a/pom.xml b/pom.xml index 957feec369b..35742f856d3 100644 --- a/pom.xml +++ b/pom.xml @@ -462,7 +462,7 @@ under the License. 4.4.3 10.5.0 - 10.4.0 + 10.5.0 10.0.0-M1 7.0.10 4.0.4 @@ -514,7 +514,7 @@ under the License. 9.0 11 23-slim-faststart - 5.26.4 + 5.26 42.7.5 9.2.0 diff --git a/src/main/asciidoc/reference-guide/concepts/realms.adoc b/src/main/asciidoc/reference-guide/concepts/realms.adoc index b1c01c9d218..4a3b972d45e 100644 --- a/src/main/asciidoc/reference-guide/concepts/realms.adoc +++ b/src/main/asciidoc/reference-guide/concepts/realms.adoc @@ -27,6 +27,7 @@ Each realm: . is either a leaf or root of a sub-tree of realms; . is uniquely identified by the path from the root realm, e.g. `/a/b/c` identifies the sub-realm `c` in the sub-tree rooted at `b`, having in turn `a` as parent realm, directly under the root realm; +. optionally refers to an <> which allows to define plain and derived attributes for the realm; . optionally refers to various <> that are enforced on all Users, Groups and Any Objects in the given realm and sub-realms, unless some sub-realms define their own policies. . optionally refers to <> diff --git a/src/main/asciidoc/reference-guide/concepts/typemanagement.adoc b/src/main/asciidoc/reference-guide/concepts/typemanagement.adoc index 14ea0806afc..5d3360e9f92 100644 --- a/src/main/asciidoc/reference-guide/concepts/typemanagement.adoc +++ b/src/main/asciidoc/reference-guide/concepts/typemanagement.adoc @@ -31,7 +31,7 @@ It is possible to define i18n labels for each schema, with purpose of improving ===== Plain -Values for attributes with such schema types are provided during user, group or any object create / update. +Values for attributes with such schema types are provided during realm, user, group or any object create / update. When defining a plain schema, the following information must be provided: @@ -110,8 +110,8 @@ When defining a virtual schema, the following information must be provided: Any type classes are aggregations of plain, derived and virtual schemas, provided with unique identifiers. -Classes can be assigned to <> and are also available as auxiliary (hence to be specified on a -given user / group / any object instance) and for <>. +Classes can be assigned to <>, <> and are also available as auxiliary (hence to be +specified on a given user / group / any object instance) and for <>. ==== AnyType From a47f7fb97097e8ff914e3a8fc794e2c604100379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Wed, 7 May 2025 09:37:54 +0200 Subject: [PATCH 036/579] [SYNCOPE-1876] Remove Virtual Attributes (#1070) --- ...RepoWizardBuilder$Configuration.properties | 1 - ...zardBuilder$Configuration_fr_CA.properties | 5 +- ...oWizardBuilder$Configuration_it.properties | 1 - ...oWizardBuilder$Configuration_ja.properties | 1 - ...zardBuilder$Configuration_pt_BR.properties | 1 - ...oWizardBuilder$Configuration_ru.properties | 1 - ...duleWizardBuilder$Configuration.properties | 1 - ...zardBuilder$Configuration_fr_CA.properties | 5 +- ...eWizardBuilder$Configuration_it.properties | 1 - ...eWizardBuilder$Configuration_ja.properties | 1 - ...zardBuilder$Configuration_pt_BR.properties | 1 - ...eWizardBuilder$Configuration_ru.properties | 1 - .../client/console/IdMConsoleContext.java | 7 - .../IdMVirSchemaDetailsPanelProvider.java | 33 - .../panels/ResourceDirectoryPanel.java | 2 - .../console/panels/VirSchemaDetails.java | 164 ----- .../console/topology/TopologyTogglePanel.java | 7 - .../resources/ResourceMappingPanel.java | 9 +- .../console/panels/VirSchemaDetails.html | 39 - .../panels/VirSchemaDetails.properties | 24 - .../panels/VirSchemaDetails_it.properties | 24 - .../panels/VirSchemaDetails_ja.properties | 24 - .../panels/VirSchemaDetails_pt_BR.properties | 24 - .../panels/VirSchemaDetails_ru.properties | 24 - .../layout/AbstractAnyFormBaseLayout.java | 10 - .../commons/layout/AbstractAnyFormLayout.java | 6 - .../wizards/any/AbstractAnyWizardBuilder.java | 37 +- .../client/console/IdRepoConsoleContext.java | 8 - .../console/SyncopeConsoleApplication.java | 3 - .../client/console/SyncopeWebApplication.java | 9 - .../console/commons/IdRepoConstants.java | 6 - .../IdRepoVirSchemaDetailsPanelProvider.java | 33 - .../SortableAnyProviderComparator.java | 4 - .../VirSchemaDetailsPanelProvider.java | 29 - .../NotificationWizardBuilder.java | 3 - .../panels/AnyTypeClassDetailsPanel.java | 14 - .../client/console/panels/BeanPanel.java | 16 +- .../console/panels/SchemaTypePanel.java | 4 +- .../panels/SchemaTypeWizardBuilder.java | 7 - .../html/repeater/data/table/AttrColumn.java | 3 - .../console/widgets/CompletenessWidget.java | 8 +- .../console/wizards/any/AbstractAttrs.java | 2 - .../wizards/any/AnyObjectWizardBuilder.java | 2 +- .../console/wizards/any/AnyWizardBuilder.java | 42 +- .../wizards/any/GroupWizardBuilder.java | 2 +- .../wizards/any/UserWizardBuilder.java | 2 +- .../client/console/wizards/any/VirAttrs.java | 213 ------ .../panels/AnyTypeClassDetailsPanel.html | 10 - .../AnyTypeClassDetailsPanel.properties | 1 - .../AnyTypeClassDetailsPanel_fr_CA.properties | 5 +- .../AnyTypeClassDetailsPanel_it.properties | 1 - .../AnyTypeClassDetailsPanel_ja.properties | 1 - .../AnyTypeClassDetailsPanel_pt_BR.properties | 1 - .../AnyTypeClassDetailsPanel_ru.properties | 6 +- .../panels/AnyTypeClassesPanel.properties | 1 - .../AnyTypeClassesPanel_fr_CA.properties | 5 +- .../panels/AnyTypeClassesPanel_it.properties | 1 - .../panels/AnyTypeClassesPanel_ja.properties | 1 - .../AnyTypeClassesPanel_pt_BR.properties | 1 - .../panels/AnyTypeClassesPanel_ru.properties | 14 +- .../panels/VirSchemaDetails_fr_CA.properties | 24 - .../console/widgets/CompletenessWidget.html | 2 +- .../widgets/CompletenessWidget.properties | 2 +- .../CompletenessWidget_fr_CA.properties | 14 +- .../widgets/CompletenessWidget_it.properties | 2 +- .../widgets/CompletenessWidget_ja.properties | 2 +- .../CompletenessWidget_pt_BR.properties | 2 +- .../widgets/CompletenessWidget_ru.properties | 19 +- .../client/console/wizards/any/VirAttrs.html | 26 - .../console/wizards/any/VirAttrs.properties | 18 - .../wizards/any/VirAttrs_fr_CA.properties | 18 - .../wizards/any/VirAttrs_it.properties | 18 - .../wizards/any/VirAttrs_ja.properties | 18 - .../wizards/any/VirAttrs_pt_BR.properties | 18 - .../wizards/any/VirAttrs_ru.properties | 19 - .../syncope/client/console/AbstractTest.java | 8 +- .../enduser/layout/UserFormLayoutInfo.java | 6 - .../client/enduser/panels/AnyFormPanel.java | 55 +- .../client/enduser/panels/UserFormPanel.java | 2 +- .../enduser/panels/any/AbstractAttrs.java | 2 - .../client/enduser/panels/any/VirAttrs.java | 194 ----- .../client/enduser/rest/SchemaRestClient.java | 4 - .../src/main/resources/customFormLayout.json | 2 - .../SyncopeEnduserApplication.properties | 1 - ...SyncopeEnduserApplication_fr_CA.properties | 1 - .../SyncopeEnduserApplication_it.properties | 1 - .../SyncopeEnduserApplication_ja.properties | 117 ++- ...SyncopeEnduserApplication_pt_BR.properties | 1 - .../SyncopeEnduserApplication_ru.properties | 101 ++- .../client/enduser/panels/UserFormPanel.html | 1 - .../client/enduser/panels/any/VirAttrs.html | 27 - .../enduser/panels/any/VirAttrs.properties | 18 - .../enduser/panels/any/VirAttrs_it.properties | 18 - .../enduser/panels/any/VirAttrs_ja.properties | 18 - .../panels/any/VirAttrs_pt_BR.properties | 18 - .../enduser/panels/any/VirAttrs_ru.properties | 18 - .../syncope/client/enduser/AbstractTest.java | 2 - .../apache/syncope/common/lib/to/Mapping.java | 14 - .../syncope/common/lib/to/Provision.java | 10 - .../common/rest/api/beans/CSVPushSpec.java | 21 - .../syncope/common/lib/AnyOperations.java | 32 +- .../syncope/common/lib/EntityTOUtils.java | 2 - .../syncope/common/lib/info/NumbersInfo.java | 1 - .../lib/policy/DefaultAccountRuleConf.java | 2 +- .../lib/policy/DefaultPasswordRuleConf.java | 2 +- .../syncope/common/lib/request/AnyCR.java | 35 - .../syncope/common/lib/request/AnyUR.java | 31 +- .../common/lib/request/MembershipUR.java | 25 - .../apache/syncope/common/lib/to/AnyTO.java | 17 - .../syncope/common/lib/to/AnyTypeClassTO.java | 8 - .../syncope/common/lib/to/AttributableTO.java | 4 - .../syncope/common/lib/to/MembershipTO.java | 32 - .../apache/syncope/common/lib/to/RealmTO.java | 15 - .../syncope/common/lib/to/SchemaTO.java | 2 +- .../syncope/common/lib/to/VirSchemaTO.java | 112 --- .../common/lib/types/ClientExceptionType.java | 1 - .../syncope/common/lib/types/SchemaType.java | 9 +- .../syncope/common/lib/SerializationTest.java | 15 +- .../common/rest/api/beans/AnyQuery.java | 3 +- .../syncope/core/logic/IdMLogicContext.java | 10 - .../core/logic/ReconciliationLogic.java | 34 +- .../syncope/core/logic/ResourceLogic.java | 22 +- .../syncope/core/logic/ResourceLogicTest.java | 38 +- .../core/logic/IdRepoLogicContext.java | 4 +- .../syncope/core/logic/SchemaLogic.java | 43 +- .../rest/cxf/service/AbstractAnyService.java | 12 - .../persistence/api/dao/VirSchemaDAO.java | 30 - .../persistence/api/entity/AnyTypeClass.java | 4 - .../persistence/api/entity/VirSchema.java | 50 -- .../jpa/upgrade/GenerateUpgradeSQL.java | 33 +- .../src/main/resources/schema.xml | 39 +- .../persistence/jpa/PersistenceContext.java | 26 - .../jpa/dao/repo/AbstractAnyRepoExt.java | 6 - .../jpa/dao/repo/AnyTypeClassRepoExtImpl.java | 12 - .../dao/repo/ExternalResourceRepoExtImpl.java | 7 - .../jpa/dao/repo/VirSchemaRepo.java | 28 - .../jpa/dao/repo/VirSchemaRepoExt.java | 37 - .../jpa/dao/repo/VirSchemaRepoExtImpl.java | 85 --- .../jpa/entity/AbstractEntityFactory.java | 3 - .../jpa/entity/JPAAnyTypeClass.java | 15 - .../persistence/jpa/entity/JPAVirSchema.java | 131 ---- .../core/persistence/jpa/AbstractTest.java | 5 +- .../jpa/inner/AnyTypeClassTest.java | 2 - .../jpa/inner/RemediationTest.java | 6 +- .../persistence/jpa/inner/ResourceTest.java | 32 - .../core/persistence/jpa/inner/TaskTest.java | 2 +- .../persistence/jpa/inner/VirSchemaTest.java | 113 --- .../persistence/jpa/outer/VirSchemaTest.java | 82 --- .../test/resources/domains/MasterContent.xml | 74 +- .../persistence/neo4j/PersistenceContext.java | 64 +- .../neo4j/content/ContentLoaderHandler.java | 8 +- .../neo4j/dao/Neo4jEntityCacheDAO.java | 5 +- .../neo4j/dao/repo/AbstractAnyRepoExt.java | 16 - .../neo4j/dao/repo/AbstractSchemaRepoExt.java | 4 - .../neo4j/dao/repo/AnyObjectRepoExtImpl.java | 3 - .../dao/repo/AnyTypeClassRepoExtImpl.java | 22 - .../dao/repo/ExternalResourceRepoExtImpl.java | 7 - .../neo4j/dao/repo/GroupRepoExtImpl.java | 5 +- .../neo4j/dao/repo/UserRepoExtImpl.java | 3 - .../neo4j/dao/repo/VirSchemaRepo.java | 28 - .../neo4j/dao/repo/VirSchemaRepoExt.java | 47 -- .../neo4j/dao/repo/VirSchemaRepoExtImpl.java | 133 ---- .../neo4j/entity/Neo4jAnyTypeClass.java | 17 - .../neo4j/entity/Neo4jEntityFactory.java | 3 - .../neo4j/entity/Neo4jVirSchema.java | 129 ---- ...eCleaningTransactionExecutionListener.java | 8 +- .../src/main/resources/META-INF/indexes.xml | 1 - .../neo4j/inner/AnyTypeClassTest.java | 2 - .../neo4j/inner/RemediationTest.java | 6 +- .../persistence/neo4j/inner/ResourceTest.java | 32 - .../persistence/neo4j/inner/TaskTest.java | 2 +- .../neo4j/inner/VirSchemaTest.java | 113 --- .../neo4j/outer/VirSchemaTest.java | 81 -- .../test/resources/domains/MasterContent.xml | 78 +- .../provisioning/api/IntAttrNameParser.java | 11 +- .../core/provisioning/api/VirAttrHandler.java | 84 --- .../api/data/ItemTransformer.java | 2 - .../api/data/SchemaDataBinder.java | 8 - .../api/propagation/PropagationManager.java | 9 +- .../api/IntAttrNameParserTest.java | 36 +- .../DefaultAnyObjectProvisioningManager.java | 10 +- .../java/DefaultGroupProvisioningManager.java | 11 +- .../java/DefaultMappingManager.java | 155 ++-- .../java/DefaultUserProvisioningManager.java | 13 +- .../java/DefaultVirAttrHandler.java | 191 ----- .../java/ProvisioningContext.java | 88 +-- .../java/cache/VirAttrCacheKey.java | 28 - .../java/cache/VirAttrCacheValue.java | 32 - .../provisioning/java/data/AnyDataBinder.java | 14 - .../java/data/AnyObjectDataBinderImpl.java | 5 - .../java/data/AnyTypeClassDataBinderImpl.java | 25 - .../java/data/GroupDataBinderImpl.java | 4 - .../java/data/JEXLItemTransformerImpl.java | 1 - .../java/data/ResourceDataBinderImpl.java | 59 +- .../java/data/SchemaDataBinderImpl.java | 92 --- .../java/data/UserDataBinderImpl.java | 5 - .../DefaultNotificationManager.java | 43 +- .../DefaultPropagationManager.java | 65 +- .../java/pushpull/AbstractPullExecutor.java | 4 - .../pushpull/AbstractPullResultHandler.java | 30 +- .../pushpull/AbstractPushResultHandler.java | 4 +- .../DefaultUserPushResultHandler.java | 4 - .../java/pushpull/InboundMatcher.java | 24 +- .../java/pushpull/LiveSyncJobDelegate.java | 11 +- .../java/pushpull/OutboundMatcher.java | 64 +- .../java/pushpull/PullJobDelegate.java | 11 +- .../java/pushpull/SinglePullJobDelegate.java | 12 +- .../stream/StreamPullJobDelegate.java | 14 +- .../java/utils/TemplateUtils.java | 35 +- .../java/cache/VirAttrCacheKeyTest.java | 48 -- .../java/cache/VirAttrCacheValueTest.java | 44 -- .../core/starter/SyncopeCoreApplication.java | 3 - .../DefaultSyncopeCoreInfoContributor.java | 7 - .../mapping/OIDCProviderMappingPanel.java | 1 - .../data/OIDCC4UIProviderDataBinderImpl.java | 5 - .../wizards/mapping/SAML2IdPMappingPanel.java | 1 - .../data/SAML2SP4UIIdPDataBinderImpl.java | 5 - .../mapping/SCIMExtensionMappingPanel.java | 1 - .../syncope/core/logic/SCIMDataBinder.java | 92 +-- .../core/logic/scim/SCIMConfManager.java | 14 +- .../apache/syncope/fit/AbstractITCase.java | 2 - .../fit/console/AbstractTypesITCase.java | 12 - .../syncope/fit/console/GroupsITCase.java | 4 - .../syncope/fit/console/SchemasITCase.java | 53 -- .../syncope/fit/console/UsersITCase.java | 4 - .../syncope/fit/core/AnyTypeClassITCase.java | 3 - .../apache/syncope/fit/core/GroupITCase.java | 11 - .../fit/core/PropagationTaskITCase.java | 7 +- .../syncope/fit/core/PullTaskITCase.java | 55 -- .../syncope/fit/core/ResourceITCase.java | 52 +- .../apache/syncope/fit/core/UserITCase.java | 9 - .../syncope/fit/core/UserIssuesITCase.java | 53 +- .../syncope/fit/core/UserSelfITCase.java | 1 - .../syncope/fit/core/VirAttrITCase.java | 697 ------------------ .../syncope/fit/core/VirSchemaITCase.java | 151 ---- .../src/test/resources/customTemplate.json | 3 - .../concepts/typemanagement.adoc | 36 +- .../concepts/usersgroupsandanyobjects.adoc | 2 +- 238 files changed, 566 insertions(+), 5938 deletions(-) delete mode 100644 client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMVirSchemaDetailsPanelProvider.java delete mode 100644 client/idm/console/src/main/java/org/apache/syncope/client/console/panels/VirSchemaDetails.java delete mode 100644 client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails.html delete mode 100644 client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails.properties delete mode 100644 client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_it.properties delete mode 100644 client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_ja.properties delete mode 100644 client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_pt_BR.properties delete mode 100644 client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_ru.properties delete mode 100644 client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoVirSchemaDetailsPanelProvider.java delete mode 100644 client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/VirSchemaDetailsPanelProvider.java delete mode 100644 client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/VirAttrs.java delete mode 100644 client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_fr_CA.properties delete mode 100644 client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs.html delete mode 100644 client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs.properties delete mode 100644 client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_fr_CA.properties delete mode 100644 client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_it.properties delete mode 100644 client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_ja.properties delete mode 100644 client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_pt_BR.properties delete mode 100644 client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_ru.properties delete mode 100644 client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/VirAttrs.java delete mode 100644 client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs.html delete mode 100644 client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs.properties delete mode 100644 client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs_it.properties delete mode 100644 client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs_ja.properties delete mode 100644 client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs_pt_BR.properties delete mode 100644 client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs_ru.properties delete mode 100644 common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/VirSchemaTO.java delete mode 100644 core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java delete mode 100644 core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/VirSchema.java delete mode 100644 core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/VirSchemaRepo.java delete mode 100644 core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/VirSchemaRepoExt.java delete mode 100644 core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/VirSchemaRepoExtImpl.java delete mode 100644 core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java delete mode 100644 core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirSchemaTest.java delete mode 100644 core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/VirSchemaTest.java delete mode 100644 core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/VirSchemaRepo.java delete mode 100644 core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/VirSchemaRepoExt.java delete mode 100644 core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/VirSchemaRepoExtImpl.java delete mode 100644 core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jVirSchema.java delete mode 100644 core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/VirSchemaTest.java delete mode 100644 core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/outer/VirSchemaTest.java delete mode 100644 core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/VirAttrHandler.java delete mode 100644 core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultVirAttrHandler.java delete mode 100644 core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/VirAttrCacheKey.java delete mode 100644 core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/VirAttrCacheValue.java delete mode 100644 core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/cache/VirAttrCacheKeyTest.java delete mode 100644 core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/cache/VirAttrCacheValueTest.java delete mode 100644 fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java delete mode 100644 fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirSchemaITCase.java diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration.properties index 8d2c500e11a..cbd6b3af519 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration.properties @@ -16,7 +16,6 @@ # under the License. plainAttrs=Plain Attributes derAttrs=Derived Attributes -virAttrs=Virtual Attributes features=Features matchingCond=Matching Condition userMatchingCond=User Matching Condition diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_fr_CA.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_fr_CA.properties index e791574a14e..68f0f52287f 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_fr_CA.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_fr_CA.properties @@ -15,9 +15,8 @@ # specific language governing permissions and limitations # under the License. plainAttrs=Attributs simples -derAttrs=Attributs dérivés -virAttrs=Attributs virtuels -features=Caractéristiques +derAttrs=Attributs d\u00e9riv\u00e9s +features=Caract\u00e9ristiques matchingCond=Condition d'appariement userMatchingCond=Condition d'appariement des utilisateurs groupMatchingCond=Condition d'appariement de groupe diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_it.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_it.properties index 6688f852c27..f5186538835 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_it.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_it.properties @@ -16,7 +16,6 @@ # under the License. plainAttrs=Attributi derAttrs=Attributi Derivati -virAttrs=Attributi Virtuali features=Features matchingCond=Condizione di matching userMatchingCond=Condizione di matching utente diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_ja.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_ja.properties index ba85e50448b..83a1dacdd58 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_ja.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_ja.properties @@ -16,7 +16,6 @@ # under the License. plainAttrs=\u30d7\u30ec\u30fc\u30f3\u5c5e\u6027 derAttrs=\u6d3e\u751f\u5c5e\u6027 -virAttrs=\u4eee\u60f3\u5c5e\u6027 features=\u6a5f\u80fd matchingCond=\u4e00\u81f4\u6761\u4ef6 userMatchingCond=\u30e6\u30fc\u30b6\u2015\u4e00\u81f4\u6761\u4ef6 diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_pt_BR.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_pt_BR.properties index 8d2c500e11a..cbd6b3af519 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_pt_BR.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_pt_BR.properties @@ -16,7 +16,6 @@ # under the License. plainAttrs=Plain Attributes derAttrs=Derived Attributes -virAttrs=Virtual Attributes features=Features matchingCond=Matching Condition userMatchingCond=User Matching Condition diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_ru.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_ru.properties index 721b3e531a1..3abdee76868 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_ru.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AttrRepoWizardBuilder$Configuration_ru.properties @@ -17,7 +17,6 @@ # plainAttrs=\u041f\u0440\u043e\u0441\u0442\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b derAttrs=\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b -virAttrs=\u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b features=\u0421\u0432\u043e\u0439\u0441\u0442\u0432\u0430 matchingCond=\u041a\u0440\u0438\u0442\u0435\u0440\u0438\u0439 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044f userMatchingCond=\u041a\u0440\u0438\u0442\u0435\u0440\u0438\u0439 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044f \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration.properties index 8d2c500e11a..cbd6b3af519 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration.properties @@ -16,7 +16,6 @@ # under the License. plainAttrs=Plain Attributes derAttrs=Derived Attributes -virAttrs=Virtual Attributes features=Features matchingCond=Matching Condition userMatchingCond=User Matching Condition diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_fr_CA.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_fr_CA.properties index e791574a14e..68f0f52287f 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_fr_CA.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_fr_CA.properties @@ -15,9 +15,8 @@ # specific language governing permissions and limitations # under the License. plainAttrs=Attributs simples -derAttrs=Attributs dérivés -virAttrs=Attributs virtuels -features=Caractéristiques +derAttrs=Attributs d\u00e9riv\u00e9s +features=Caract\u00e9ristiques matchingCond=Condition d'appariement userMatchingCond=Condition d'appariement des utilisateurs groupMatchingCond=Condition d'appariement de groupe diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_it.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_it.properties index 6688f852c27..f5186538835 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_it.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_it.properties @@ -16,7 +16,6 @@ # under the License. plainAttrs=Attributi derAttrs=Attributi Derivati -virAttrs=Attributi Virtuali features=Features matchingCond=Condizione di matching userMatchingCond=Condizione di matching utente diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_ja.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_ja.properties index ba85e50448b..83a1dacdd58 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_ja.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_ja.properties @@ -16,7 +16,6 @@ # under the License. plainAttrs=\u30d7\u30ec\u30fc\u30f3\u5c5e\u6027 derAttrs=\u6d3e\u751f\u5c5e\u6027 -virAttrs=\u4eee\u60f3\u5c5e\u6027 features=\u6a5f\u80fd matchingCond=\u4e00\u81f4\u6761\u4ef6 userMatchingCond=\u30e6\u30fc\u30b6\u2015\u4e00\u81f4\u6761\u4ef6 diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_pt_BR.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_pt_BR.properties index 8d2c500e11a..cbd6b3af519 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_pt_BR.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_pt_BR.properties @@ -16,7 +16,6 @@ # under the License. plainAttrs=Plain Attributes derAttrs=Derived Attributes -virAttrs=Virtual Attributes features=Features matchingCond=Matching Condition userMatchingCond=User Matching Condition diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_ru.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_ru.properties index 721b3e531a1..3abdee76868 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_ru.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$Configuration_ru.properties @@ -17,7 +17,6 @@ # plainAttrs=\u041f\u0440\u043e\u0441\u0442\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b derAttrs=\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b -virAttrs=\u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b features=\u0421\u0432\u043e\u0439\u0441\u0442\u0432\u0430 matchingCond=\u041a\u0440\u0438\u0442\u0435\u0440\u0438\u0439 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044f userMatchingCond=\u041a\u0440\u0438\u0442\u0435\u0440\u0438\u0439 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044f \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/IdMConsoleContext.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/IdMConsoleContext.java index ae5666f6d27..57d46b8f0f3 100644 --- a/client/idm/console/src/main/java/org/apache/syncope/client/console/IdMConsoleContext.java +++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/IdMConsoleContext.java @@ -29,11 +29,9 @@ import org.apache.syncope.client.console.commons.IdMImplementationInfoProvider; import org.apache.syncope.client.console.commons.IdMPolicyTabProvider; import org.apache.syncope.client.console.commons.IdMStatusProvider; -import org.apache.syncope.client.console.commons.IdMVirSchemaDetailsPanelProvider; import org.apache.syncope.client.console.commons.ImplementationInfoProvider; import org.apache.syncope.client.console.commons.PolicyTabProvider; import org.apache.syncope.client.console.commons.StatusProvider; -import org.apache.syncope.client.console.commons.VirSchemaDetailsPanelProvider; import org.apache.syncope.client.console.init.ClassPathScanImplementationContributor; import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup; import org.apache.syncope.client.console.init.IdMClassPathScanImplementationContributor; @@ -88,11 +86,6 @@ public StatusProvider statusProvider(final ReconStatusUtils reconStatusUtils) { return new IdMStatusProvider(reconStatusUtils); } - @Bean - public VirSchemaDetailsPanelProvider virSchemaDetailsPanelProvider() { - return new IdMVirSchemaDetailsPanelProvider(); - } - @Bean public ImplementationInfoProvider implementationInfoProvider( final ClassPathScanImplementationLookup lookup, diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMVirSchemaDetailsPanelProvider.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMVirSchemaDetailsPanelProvider.java deleted file mode 100644 index ecc06051c7b..00000000000 --- a/client/idm/console/src/main/java/org/apache/syncope/client/console/commons/IdMVirSchemaDetailsPanelProvider.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.client.console.commons; - -import org.apache.syncope.client.console.panels.VirSchemaDetails; -import org.apache.syncope.common.lib.to.VirSchemaTO; -import org.apache.wicket.markup.html.panel.Panel; - -public class IdMVirSchemaDetailsPanelProvider implements VirSchemaDetailsPanelProvider { - - private static final long serialVersionUID = -173141337550903982L; - - @Override - public Panel get(final String id, final VirSchemaTO schemaTO) { - return new VirSchemaDetails("details", schemaTO); - } -} diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.java index b9ede15c03b..081481d0ca4 100644 --- a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.java +++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDirectoryPanel.java @@ -359,8 +359,6 @@ public void onClick(final AjaxRequestTarget target, final Serializable ignore) { ResourceTO resource = restClient.read(key); resource.setKey("Copy of " + resource.getKey()); // reset some resource objects keys - resource.getProvisions().stream().filter(p -> p.getMapping() != null). - forEach(p -> p.getVirSchemas().clear()); target.add(modal.setContent(new ResourceWizardBuilder( resource, restClient, connectorRestClient, pageRef). build(BaseModal.CONTENT_ID, AjaxWizard.Mode.CREATE))); diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/VirSchemaDetails.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/VirSchemaDetails.java deleted file mode 100644 index a2c59d7ea02..00000000000 --- a/client/idm/console/src/main/java/org/apache/syncope/client/console/panels/VirSchemaDetails.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.client.console.panels; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import org.apache.syncope.client.console.SyncopeConsoleSession; -import org.apache.syncope.client.console.rest.ConnectorRestClient; -import org.apache.syncope.client.console.rest.ResourceRestClient; -import org.apache.syncope.client.ui.commons.Constants; -import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior; -import org.apache.syncope.client.ui.commons.markup.html.form.AjaxCheckBoxPanel; -import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel; -import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel; -import org.apache.syncope.common.lib.SyncopeConstants; -import org.apache.syncope.common.lib.to.ResourceTO; -import org.apache.syncope.common.lib.to.VirSchemaTO; -import org.apache.syncope.common.lib.types.IdMEntitlement; -import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.model.PropertyModel; -import org.apache.wicket.spring.injection.annot.SpringBean; - -public class VirSchemaDetails extends AbstractSchemaDetailsPanel { - - private static final long serialVersionUID = 5979623248182851337L; - - @SpringBean - protected ResourceRestClient resourceRestClient; - - @SpringBean - protected ConnectorRestClient connectorRestClient; - - protected final Map anyTypes = new HashMap<>(); - - protected final AjaxDropDownChoicePanel anyType; - - protected ResourceTO selectedResource; - - public VirSchemaDetails(final String id, final VirSchemaTO schemaTO) { - super(id, schemaTO); - - AjaxCheckBoxPanel readonly = new AjaxCheckBoxPanel("readonly", getString("readonly"), - new PropertyModel<>(schemaTO, "readonly")); - add(readonly); - - AjaxDropDownChoicePanel resource = new AjaxDropDownChoicePanel<>( - "resource", getString("resource"), new PropertyModel(schemaTO, "resource"), false). - setNullValid(false); - resource.setChoices(resourceRestClient.list().stream().map(ResourceTO::getKey).collect(Collectors.toList())); - resource.setOutputMarkupId(true); - resource.addRequiredLabel(); - if (resource.getModelObject() != null) { - populateAnyTypes(resource.getModelObject()); - } - add(resource); - - anyType = new AjaxDropDownChoicePanel<>( - "anyType", getString("anyType"), new PropertyModel(schemaTO, "anyType"), false). - setNullValid(false); - anyType.setChoices(new ArrayList<>(anyTypes.keySet())); - anyType.setOutputMarkupId(true); - anyType.setOutputMarkupPlaceholderTag(true); - anyType.addRequiredLabel(); - if (resource.getModelObject() == null) { - anyType.setEnabled(false); - } - add(anyType); - - AjaxTextFieldPanel extAttrName = new AjaxTextFieldPanel( - "extAttrName", getString("extAttrName"), new PropertyModel<>(schemaTO, "extAttrName")); - extAttrName.setOutputMarkupId(true); - extAttrName.addRequiredLabel(); - if (selectedResource != null) { - extAttrName.setChoices(getExtAttrNames()); - } - add(extAttrName); - - resource.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { - - private static final long serialVersionUID = -1107858522700306810L; - - @Override - protected void onUpdate(final AjaxRequestTarget target) { - anyTypes.clear(); - if (resource.getModelObject() != null) { - populateAnyTypes(resource.getModelObject()); - anyType.setEnabled(true); - } - anyType.setChoices(new ArrayList<>(anyTypes.keySet())); - anyType.setModelObject(null); - target.add(anyType); - } - }); - - anyType.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { - - private static final long serialVersionUID = -1107858522700306810L; - - @Override - protected void onUpdate(final AjaxRequestTarget target) { - if (selectedResource != null) { - String adminRealm = getAdminRealm(selectedResource.getConnector()); - - if (SyncopeConsoleSession.get().owns(IdMEntitlement.CONNECTOR_READ, adminRealm)) { - extAttrName.setChoices(getExtAttrNames()); - target.add(extAttrName); - } - } - } - }); - } - - protected String getAdminRealm(final String connectorKey) { - String adminRealm = null; - try { - adminRealm = connectorRestClient.read(connectorKey).getAdminRealm(); - } catch (Exception e) { - LOG.error("Could not read Admin Realm for External Resource {}", selectedResource.getKey()); - } - - return adminRealm; - } - - protected void populateAnyTypes(final String resourceKey) { - anyTypes.clear(); - if (resourceKey != null) { - ResourceTO resource = resourceRestClient.read(resourceKey); - String adminRealm = getAdminRealm(resource.getConnector()); - - if (SyncopeConsoleSession.get().owns(IdMEntitlement.RESOURCE_READ, adminRealm)) { - selectedResource = resource; - selectedResource.getProvisions().forEach( - provisionTO -> anyTypes.put(provisionTO.getAnyType(), provisionTO.getObjectClass())); - } - } - } - - protected List getExtAttrNames() { - return connectorRestClient.getExtAttrNames( - SyncopeConstants.ROOT_REALM, - anyTypes.get(anyType.getModelObject()), - selectedResource.getConnector(), - selectedResource.getConfOverride()); - } -} diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java index 2ff8db53785..ab8db42b800 100644 --- a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java +++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java @@ -45,7 +45,6 @@ import org.apache.syncope.client.ui.commons.wizards.AjaxWizard; import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.to.ConnInstanceTO; -import org.apache.syncope.common.lib.to.Provision; import org.apache.syncope.common.lib.to.ResourceTO; import org.apache.syncope.common.lib.types.IdMEntitlement; import org.apache.syncope.common.lib.types.IdRepoEntitlement; @@ -636,12 +635,6 @@ public void onClick(final AjaxRequestTarget target) { ResourceTO resource = resourceRestClient.read(node.getKey()); resource.setKey("Copy of " + node.getKey()); - for (Provision provision : resource.getProvisions()) { - if (provision.getMapping() != null) { - provision.getMapping().getLinkingItems().clear(); - } - provision.getVirSchemas().clear(); - } target.add(modal.setContent(new ResourceWizardBuilder( resource, resourceRestClient, connectorRestClient, pageRef). build(BaseModal.CONTENT_ID, AjaxWizard.Mode.CREATE))); diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java index 1441795726d..6b4994e94d1 100644 --- a/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java +++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java @@ -165,22 +165,19 @@ protected void setAttrNames(final AjaxTextFieldPanel toBeUpdated) { }); switch (provision.getAnyType()) { - case "USER": + case "USER" -> choices.addAll(ClassPathScanImplementationLookup.USER_FIELD_NAMES); - break; - case "GROUP": + case "GROUP" -> choices.addAll(ClassPathScanImplementationLookup.GROUP_FIELD_NAMES); - break; - default: + default -> choices.addAll(ClassPathScanImplementationLookup.ANY_OBJECT_FIELD_NAMES); } anyTypeClassTOs.forEach(anyTypeClassTO -> { choices.addAll(anyTypeClassTO.getPlainSchemas()); choices.addAll(anyTypeClassTO.getDerSchemas()); - choices.addAll(anyTypeClassTO.getVirSchemas()); }); } diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails.html b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails.html deleted file mode 100644 index b5d83e86fef..00000000000 --- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails.html +++ /dev/null @@ -1,39 +0,0 @@ - - - -
-
- [name] -
-
- [readonly] -
-
- [resource] -
-
- [anyType] -
-
- [extAttrName] -
-
-
- diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails.properties deleted file mode 100644 index a93c17a1f9a..00000000000 --- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails.properties +++ /dev/null @@ -1,24 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -required_alert=All form fields are required. -edit_attribute=Edit attribute -attributes=Virtual attributes -title=Virtual Schema -readonly=Read-only -resource=Resource -anyType=Type -extAttrName=External attribute diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_it.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_it.properties deleted file mode 100644 index 24de32579cf..00000000000 --- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_it.properties +++ /dev/null @@ -1,24 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -required_alert=Tutti i campi sono richiesti. -edit_attribute=Modifica attributo -attributes=Attributi virtuali -title=Schema Virtuale -readonly=Read-only -resource=Risorsa -anyType=Tipo -extAttrName=Attributo esterno diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_ja.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_ja.properties deleted file mode 100644 index 8475c1a7047..00000000000 --- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_ja.properties +++ /dev/null @@ -1,24 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -required_alert=\u3059\u3079\u3066\u306e\u30d5\u30a9\u30fc\u30e0\u30d5\u30a3\u30fc\u30eb\u30c9\u304c\u5fc5\u9808\u3067\u3059\u3002 -edit_attribute=\u5c5e\u6027\u3092\u7de8\u96c6 -attributes=\u4eee\u60f3\u5c5e\u6027 -title=\u4eee\u60f3\u30b9\u30ad\u30fc\u30de -readonly=\u8aad\u307f\u53d6\u308a\u5c02\u7528 -resource=\u30ea\u30bd\u30fc\u30b9 -anyType=\u30bf\u30a4\u30d7 -extAttrName=\u5916\u90e8\u5c5e\u6027 diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_pt_BR.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_pt_BR.properties deleted file mode 100644 index c757d89a73c..00000000000 --- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_pt_BR.properties +++ /dev/null @@ -1,24 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -required_alert=Todos os campos do formul\u00e1rio s\u00e3o obrigat\u00f3rios -edit_attribute=Editar Atributo -attributes=Atributos Virtuais -title=Esquema Virtual -readonly=Apenas Leitura -resource=Recurso -anyType=Type -extAttrName=Atributo Externo diff --git a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_ru.properties b/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_ru.properties deleted file mode 100644 index 132ad5aa0f3..00000000000 --- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_ru.properties +++ /dev/null @@ -1,24 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -required_alert=\u0412\u0441\u0435 \u043f\u043e\u043b\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b \u0434\u043b\u044f \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f. -edit_attribute=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442 -attributes=\u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b -title=\u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u0445\u0435\u043c\u0430 -readonly=\u0422\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u0435\u043d\u0438\u0435 -resource=\u0420\u0435\u0441\u0443\u0440\u0441 -anyType=\u0422\u0438\u043f -extAttrName=\u0412\u043d\u0435\u0448\u043d\u0438\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442 diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/layout/AbstractAnyFormBaseLayout.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/layout/AbstractAnyFormBaseLayout.java index 8cba2481f28..60173c13d79 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/layout/AbstractAnyFormBaseLayout.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/layout/AbstractAnyFormBaseLayout.java @@ -36,8 +36,6 @@ public abstract class AbstractAnyFormBaseLayout getDefaultFormClass(); @@ -82,14 +80,6 @@ public void setDerAttrs(final boolean derAttrs) { this.derAttrs = derAttrs; } - public boolean isVirAttrs() { - return virAttrs; - } - - public void setVirAttrs(final boolean virAttrs) { - this.virAttrs = virAttrs; - } - public boolean isResources() { return resources; } diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/layout/AbstractAnyFormLayout.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/layout/AbstractAnyFormLayout.java index 3e2ba898205..f9980393846 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/layout/AbstractAnyFormLayout.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/layout/AbstractAnyFormLayout.java @@ -32,8 +32,6 @@ public abstract class AbstractAnyFormLayout whichDerAttrs = new ArrayList<>(); - private final List whichVirAttrs = new ArrayList<>(); - public List getWhichPlainAttrs() { return whichPlainAttrs; } @@ -41,8 +39,4 @@ public List getWhichPlainAttrs() { public List getWhichDerAttrs() { return whichDerAttrs; } - - public List getWhichVirAttrs() { - return whichVirAttrs; - } } diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/any/AbstractAnyWizardBuilder.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/any/AbstractAnyWizardBuilder.java index 0c59a3b635e..01d5dd70ef0 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/any/AbstractAnyWizardBuilder.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/wizards/any/AbstractAnyWizardBuilder.java @@ -31,37 +31,26 @@ public AbstractAnyWizardBuilder(final AnyWrapper defaultItem, final PageRefer super(defaultItem, pageRef); } - protected void fixPlainAndVirAttrs(final AnyTO updated, final AnyTO original) { - // re-add to the updated object any missing plain or virtual attribute (compared to original): this to cope with - // form layout, which might have not included some plain or virtual attributes + protected void fixPlainAttrs(final AnyTO updated, final AnyTO original) { + // re-add to the updated object any missing plain attribute (compared to original): this to cope with + // form layout, which might have not included some plain attributes original.getPlainAttrs().stream(). filter(attr -> updated.getPlainAttr(attr.getSchema()).isPresent()). forEach(attr -> updated.getPlainAttrs().add(attr)); - original.getVirAttrs().stream(). - filter(attr -> updated.getVirAttr(attr.getSchema()).isPresent()). - forEach(attr -> updated.getVirAttrs().add(attr)); - if (updated instanceof GroupableRelatableTO && original instanceof GroupableRelatableTO) { - GroupableRelatableTO.class.cast(original).getMemberships() - .forEach(oMemb -> GroupableRelatableTO.class.cast(updated).getMembership(oMemb.getGroupKey()) - .ifPresent(uMemb -> { - oMemb.getPlainAttrs().stream(). - filter(attr -> uMemb.getPlainAttr(attr.getSchema()).isPresent()). - forEach(attr -> uMemb.getPlainAttrs().add(attr)); - oMemb.getVirAttrs().stream(). - filter(attr -> uMemb.getVirAttr(attr.getSchema()).isPresent()). - forEach(attr -> uMemb.getVirAttrs().add(attr)); - })); + if (updated instanceof GroupableRelatableTO updatedTO && original instanceof GroupableRelatableTO originalTO) { + originalTO.getMemberships(). + forEach(oMemb -> updatedTO.getMembership(oMemb.getGroupKey()). + ifPresent(uMemb -> oMemb.getPlainAttrs().stream(). + filter(attr -> uMemb.getPlainAttr(attr.getSchema()).isPresent()). + forEach(attr -> uMemb.getPlainAttrs().add(attr)))); } - // remove from the updated object any plain or virtual attribute without values, thus triggering for removal in + // remove from the updated object any plain attribute without values, thus triggering for removal in // the generated patch updated.getPlainAttrs().removeIf(attr -> attr.getValues().isEmpty()); - updated.getVirAttrs().removeIf(attr -> attr.getValues().isEmpty()); - if (updated instanceof GroupableRelatableTO) { - GroupableRelatableTO.class.cast(updated).getMemberships().forEach(memb -> { - memb.getPlainAttrs().removeIf(attr -> attr.getValues().isEmpty()); - memb.getVirAttrs().removeIf(attr -> attr.getValues().isEmpty()); - }); + if (updated instanceof GroupableRelatableTO updatedTO) { + updatedTO.getMemberships(). + forEach(memb -> memb.getPlainAttrs().removeIf(attr -> attr.getValues().isEmpty())); } } } diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/IdRepoConsoleContext.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/IdRepoConsoleContext.java index 4e3c64c5618..a18e81a2510 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/IdRepoConsoleContext.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/IdRepoConsoleContext.java @@ -33,13 +33,11 @@ import org.apache.syncope.client.console.commons.IdRepoPolicyTabProvider; import org.apache.syncope.client.console.commons.IdRepoRealmPolicyProvider; import org.apache.syncope.client.console.commons.IdRepoStatusProvider; -import org.apache.syncope.client.console.commons.IdRepoVirSchemaDetailsPanelProvider; import org.apache.syncope.client.console.commons.ImplementationInfoProvider; import org.apache.syncope.client.console.commons.PolicyTabProvider; import org.apache.syncope.client.console.commons.PreviewUtils; import org.apache.syncope.client.console.commons.RealmPolicyProvider; import org.apache.syncope.client.console.commons.StatusProvider; -import org.apache.syncope.client.console.commons.VirSchemaDetailsPanelProvider; import org.apache.syncope.client.console.init.ClassPathScanImplementationContributor; import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup; import org.apache.syncope.client.console.rest.AccessTokenRestClient; @@ -130,12 +128,6 @@ public StatusProvider statusProvider() { return new IdRepoStatusProvider(); } - @ConditionalOnMissingBean - @Bean - public VirSchemaDetailsPanelProvider virSchemaDetailsPanelProvider() { - return new IdRepoVirSchemaDetailsPanelProvider(); - } - @ConditionalOnMissingBean @Bean public ImplementationInfoProvider implementationInfoProvider( diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java index ff65011667b..a79d100fc95 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java @@ -29,7 +29,6 @@ import org.apache.syncope.client.console.commons.ImplementationInfoProvider; import org.apache.syncope.client.console.commons.PolicyTabProvider; import org.apache.syncope.client.console.commons.StatusProvider; -import org.apache.syncope.client.console.commons.VirSchemaDetailsPanelProvider; import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup; import org.apache.syncope.client.console.wizards.any.UserFormFinalizer; import org.apache.syncope.client.ui.commons.actuate.SyncopeCoreHealthIndicator; @@ -75,7 +74,6 @@ public SyncopeWebApplication syncopeWebApplication( final AnyDirectoryPanelAdditionalActionLinksProvider anyDirectoryPanelAdditionalActionLinksProvider, final AnyWizardBuilderAdditionalSteps anyWizardBuilderAdditionalSteps, final StatusProvider statusProvider, - final VirSchemaDetailsPanelProvider virSchemaDetailsPanelProvider, final ImplementationInfoProvider implementationInfoProvider, final AccessPolicyConfProvider accessPolicyConfProvider, final List policyTabProviders, @@ -90,7 +88,6 @@ public SyncopeWebApplication syncopeWebApplication( anyDirectoryPanelAdditionalActionsProvider, anyDirectoryPanelAdditionalActionLinksProvider, anyWizardBuilderAdditionalSteps, statusProvider, - virSchemaDetailsPanelProvider, implementationInfoProvider, accessPolicyConfProvider, policyTabProviders, diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeWebApplication.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeWebApplication.java index b4003dd6d10..0f48e51b266 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeWebApplication.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeWebApplication.java @@ -36,7 +36,6 @@ import org.apache.syncope.client.console.commons.PolicyTabProvider; import org.apache.syncope.client.console.commons.RealmsUtils; import org.apache.syncope.client.console.commons.StatusProvider; -import org.apache.syncope.client.console.commons.VirSchemaDetailsPanelProvider; import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup; import org.apache.syncope.client.console.pages.BasePage; import org.apache.syncope.client.console.pages.Dashboard; @@ -98,8 +97,6 @@ public static SyncopeWebApplication get() { protected final StatusProvider statusProvider; - protected final VirSchemaDetailsPanelProvider virSchemaDetailsPanelProvider; - protected final ImplementationInfoProvider implementationInfoProvider; protected final AccessPolicyConfProvider accessPolicyConfProvider; @@ -119,7 +116,6 @@ public SyncopeWebApplication( final AnyDirectoryPanelAdditionalActionLinksProvider anyDirectoryPanelAdditionalActionLinksProvider, final AnyWizardBuilderAdditionalSteps anyWizardBuilderAdditionalSteps, final StatusProvider statusProvider, - final VirSchemaDetailsPanelProvider virSchemaDetailsPanelProvider, final ImplementationInfoProvider implementationInfoProvider, final AccessPolicyConfProvider accessPolicyConfProvider, final List policyTabProviders, @@ -134,7 +130,6 @@ public SyncopeWebApplication( this.anyDirectoryPanelAdditionalActionLinksProvider = anyDirectoryPanelAdditionalActionLinksProvider; this.anyWizardBuilderAdditionalSteps = anyWizardBuilderAdditionalSteps; this.statusProvider = statusProvider; - this.virSchemaDetailsPanelProvider = virSchemaDetailsPanelProvider; this.implementationInfoProvider = implementationInfoProvider; this.accessPolicyConfProvider = accessPolicyConfProvider; this.policyTabProviders = policyTabProviders; @@ -342,10 +337,6 @@ public StatusProvider getStatusProvider() { return statusProvider; } - public VirSchemaDetailsPanelProvider getVirSchemaDetailsPanelProvider() { - return virSchemaDetailsPanelProvider; - } - public ImplementationInfoProvider getImplementationInfoProvider() { return implementationInfoProvider; } diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoConstants.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoConstants.java index 49888da7188..2514be26fb4 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoConstants.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoConstants.java @@ -26,8 +26,6 @@ public final class IdRepoConstants { public static final String PREF_USER_DER_SCHEMA_PAGINATOR_ROWS = "user.derived.schema.paginator.rows"; - public static final String PREF_USER_VIR_SCHEMA_PAGINATOR_ROWS = "user.virtual.schema.paginator.rows"; - public static final String PREF_ANYTYPE_PAGINATOR_ROWS = "anytype.paginator.rows"; public static final String PREF_SECURITY_QUESTIONS_PAGINATOR_ROWS = "security.questions.paginator.rows"; @@ -40,14 +38,10 @@ public final class IdRepoConstants { public static final String PREF_GROUP_DER_SCHEMA_PAGINATOR_ROWS = "group.derived.schema.paginator.rows"; - public static final String PREF_GROUP_VIR_SCHEMA_PAGINATOR_ROWS = "group.virtual.schema.paginator.rows"; - public static final String PREF_MEMBERSHIP_PLAIN_SCHEMA_PAGINATOR_ROWS = "membership.schema.paginator.rows"; public static final String PREF_MEMBERSHIP_DER_SCHEMA_PAGINATOR_ROWS = "membership.derived.aschema.paginator.rows"; - public static final String PREF_MEMBERSHIP_VIR_SCHEMA_PAGINATOR_ROWS = "membership.virtual.aschema.paginator.rows"; - public static final String PREF_USERS_PAGINATOR_ROWS = "users.paginator.rows"; public static final String PREF_ANYOBJECT_PAGINATOR_ROWS = "anyobject.paginator.rows"; diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoVirSchemaDetailsPanelProvider.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoVirSchemaDetailsPanelProvider.java deleted file mode 100644 index fcecfab3931..00000000000 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/IdRepoVirSchemaDetailsPanelProvider.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.client.console.commons; - -import org.apache.syncope.common.lib.to.VirSchemaTO; -import org.apache.wicket.markup.html.panel.EmptyPanel; -import org.apache.wicket.markup.html.panel.Panel; - -public class IdRepoVirSchemaDetailsPanelProvider implements VirSchemaDetailsPanelProvider { - - private static final long serialVersionUID = 1972241879030801082L; - - @Override - public Panel get(final String id, final VirSchemaTO schemaTO) { - return new EmptyPanel(id); - } -} diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/SortableAnyProviderComparator.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/SortableAnyProviderComparator.java index 5411e8e4b46..78b359bc756 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/SortableAnyProviderComparator.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/SortableAnyProviderComparator.java @@ -91,10 +91,6 @@ public Comparable getObject() { case DERIVED: attr = this.anyTO.getDerAttr(schema).orElse(null); break; - - case VIRTUAL: - attr = this.anyTO.getVirAttr(schema).orElse(null); - break; } } diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/VirSchemaDetailsPanelProvider.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/VirSchemaDetailsPanelProvider.java deleted file mode 100644 index d635e7d9a56..00000000000 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/commons/VirSchemaDetailsPanelProvider.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.client.console.commons; - -import java.io.Serializable; -import org.apache.syncope.common.lib.to.VirSchemaTO; -import org.apache.wicket.markup.html.panel.Panel; - -@FunctionalInterface -public interface VirSchemaDetailsPanelProvider extends Serializable { - - Panel get(String id, VirSchemaTO schemaTO); -} diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/NotificationWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/NotificationWizardBuilder.java index ac4d7ae827f..50bb34560d7 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/NotificationWizardBuilder.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/notifications/NotificationWizardBuilder.java @@ -51,7 +51,6 @@ import org.apache.syncope.common.lib.to.MailTemplateTO; import org.apache.syncope.common.lib.to.NotificationTO; import org.apache.syncope.common.lib.to.PlainSchemaTO; -import org.apache.syncope.common.lib.to.VirSchemaTO; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.IdRepoImplementationType; import org.apache.syncope.common.lib.types.SchemaType; @@ -415,8 +414,6 @@ protected List getSchemas() { stream().map(PlainSchemaTO::getKey).toList()); result.addAll(schemaRestClient.getSchemas(SchemaType.DERIVED, null, anyTypeClasses). stream().map(DerSchemaTO::getKey).toList()); - result.addAll(schemaRestClient.getSchemas(SchemaType.VIRTUAL, null, anyTypeClasses). - stream().map(VirSchemaTO::getKey).toList()); Collections.sort(result); return result; diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel.java index 49f8c0dfc94..20933f7880f 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel.java @@ -45,8 +45,6 @@ public class AnyTypeClassDetailsPanel extends Panel { protected final List availableDerSchemas; - protected final List availableVirSchemas; - protected final AnyTypeClassRestClient anyTypeClassRestClient; public AnyTypeClassDetailsPanel( @@ -61,7 +59,6 @@ public AnyTypeClassDetailsPanel( availablePlainSchemas = schemaRestClient.getSchemaNames(SchemaType.PLAIN); availableDerSchemas = schemaRestClient.getSchemaNames(SchemaType.DERIVED); - availableVirSchemas = schemaRestClient.getSchemaNames(SchemaType.VIRTUAL); this.anyTypeClassRestClient = anyTypeClassRestClient; @@ -103,16 +100,6 @@ public AnyTypeClassDetailsPanel( derSchema.hideLabel(); derSchema.setOutputMarkupId(true); container.add(derSchema); - - AjaxPalettePanel virSchema = new AjaxPalettePanel.Builder(). - setAllowOrder(true). - setAllowMoveAll(true). - build("virSchemas", - new PropertyModel<>(this.anyTypeClassTO, "virSchemas"), - new ListModel<>(availableVirSchemas)); - virSchema.hideLabel(); - virSchema.setOutputMarkupId(true); - container.add(virSchema); } protected void buildAvailableSchemas(final String key) { @@ -121,7 +108,6 @@ protected void buildAvailableSchemas(final String key) { forEach(item -> { availablePlainSchemas.removeAll(item.getPlainSchemas()); availableDerSchemas.removeAll(item.getDerSchemas()); - availableVirSchemas.removeAll(item.getVirSchemas()); }); availablePlainSchemas.removeAll(LAYOUT_PARAMETERS); diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/BeanPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/BeanPanel.java index 319971734ae..34473862d34 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/BeanPanel.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/BeanPanel.java @@ -184,7 +184,7 @@ protected void populateItem(final ListItem item) { List clauses = Optional.ofNullable(fiql). map(f -> SearchUtils.getSearchClauses(f.replaceAll( SearchUtils.getTypeConditionPattern(scondAnnot.type()).pattern(), ""))). - orElseGet(ArrayList::new); + orElseGet(ArrayList::new); AbstractFiqlSearchConditionBuilder builder; switch (scondAnnot.type()) { @@ -221,22 +221,16 @@ protected void populateItem(final ListItem item) { for (SchemaType type : schema.type()) { switch (type) { - case PLAIN: + case PLAIN -> choices.addAll( schemaRestClient.getSchemas(SchemaType.PLAIN, schema.anyTypeKind())); - break; - case DERIVED: + case DERIVED -> choices.addAll( schemaRestClient.getSchemas(SchemaType.DERIVED, schema.anyTypeKind())); - break; - case VIRTUAL: - choices.addAll( - schemaRestClient.getSchemas(SchemaType.VIRTUAL, schema.anyTypeKind())); - break; - - default: + default -> { + } } } diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java index 336694843f8..08e9810f64e 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/SchemaTypePanel.java @@ -63,9 +63,7 @@ public class SchemaTypePanel extends TypesDirectoryPanel rowModel.getObject().getDerAttr(name).ifPresent(attr -> values.addAll(attr.getValues())); - case VIRTUAL -> - rowModel.getObject().getVirAttr(name).ifPresent(attr -> values.addAll(attr.getValues())); - default -> { } } diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/CompletenessWidget.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/CompletenessWidget.java index 9b2a511de93..655a275bd2a 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/CompletenessWidget.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/CompletenessWidget.java @@ -92,9 +92,7 @@ public CompletenessWidget(final String id, final Map confComple types.setOutputMarkupPlaceholderTag(true); MetaDataRoleAuthorizationStrategy.authorize(types, WebPage.ENABLE, IdRepoEntitlement.ANYTYPECLASS_LIST); actions.add(types); - types.setVisible( - !confCompleteness.get(NumbersInfo.ConfItem.VIR_SCHEMA.name()) - || !confCompleteness.get(NumbersInfo.ConfItem.ANY_TYPE.name())); + types.setVisible(!confCompleteness.get(NumbersInfo.ConfItem.ANY_TYPE.name())); securityquestions = BookmarkablePageLinkBuilder.build("securityquestions", Security.class); securityquestions.setOutputMarkupPlaceholderTag(true); @@ -158,9 +156,7 @@ public boolean refresh(final Map confCompleteness) { notifications.setVisible(!confCompleteness.get(NumbersInfo.ConfItem.NOTIFICATION.name())); - types.setVisible( - !confCompleteness.get(NumbersInfo.ConfItem.VIR_SCHEMA.name()) - || !confCompleteness.get(NumbersInfo.ConfItem.ANY_TYPE.name())); + types.setVisible(!confCompleteness.get(NumbersInfo.ConfItem.ANY_TYPE.name())); securityquestions.setVisible(!confCompleteness.get(NumbersInfo.ConfItem.SECURITY_QUESTION.name())); diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java index ada7c05b6ed..698514d48e0 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AbstractAttrs.java @@ -84,8 +84,6 @@ private List loadMemberships() { membs.add(memb); } else if (this instanceof DerAttrs && !memb.getDerAttrs().isEmpty()) { membs.add(memb); - } else if (this instanceof VirAttrs && !memb.getVirAttrs().isEmpty()) { - membs.add(memb); } }); } catch (WicketRuntimeException | IllegalArgumentException | IllegalAccessException ex) { diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectWizardBuilder.java index 89f3624cabb..5771d4af9cd 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectWizardBuilder.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyObjectWizardBuilder.java @@ -82,7 +82,7 @@ protected Serializable onApplyInternal(final AnyWrapper modelObject result = anyObjectRestClient.create(req); } else { - fixPlainAndVirAttrs(inner, getOriginalItem().getInnerObject()); + fixPlainAttrs(inner, getOriginalItem().getInnerObject()); AnyObjectUR req = AnyOperations.diff(inner, getOriginalItem().getInnerObject(), false); // update just if it is changed diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java index c979ea091be..cedd20287e0 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java @@ -141,9 +141,6 @@ public PageReference getPageReference() { if (formLayoutInfo.isDerAttrs() && mode != AjaxWizard.Mode.TEMPLATE) { wizardModel.add(new DerAttrs(modelObject, anyTypeClasses, formLayoutInfo.getWhichDerAttrs())); } - if (formLayoutInfo.isVirAttrs()) { - wizardModel.add(new VirAttrs(modelObject, mode, anyTypeClasses, formLayoutInfo.getWhichVirAttrs())); - } // role panel step (just available for users) if ((this instanceof UserWizardBuilder) @@ -178,42 +175,29 @@ protected Optional> addOptionalDetailsPanel(final AnyWrapper model } @Override - protected void fixPlainAndVirAttrs(final AnyTO updated, final AnyTO original) { - // re-add to the updated object any missing plain or virtual attribute (compared to original): this to cope with - // form layout, which might have not included some plain or virtual attributes + protected void fixPlainAttrs(final AnyTO updated, final AnyTO original) { + // re-add to the updated object any missing plain attribute (compared to original): this to cope with + // form layout, which might have not included some plain attributes for (Attr plainAttr : original.getPlainAttrs()) { if (updated.getPlainAttr(plainAttr.getSchema()).isEmpty()) { updated.getPlainAttrs().add(plainAttr); } } - for (Attr virAttr : original.getVirAttrs()) { - if (updated.getVirAttr(virAttr.getSchema()).isEmpty()) { - updated.getVirAttrs().add(virAttr); - } - } - if (updated instanceof GroupableRelatableTO && original instanceof GroupableRelatableTO) { - GroupableRelatableTO.class.cast(original).getMemberships(). - forEach(oMemb -> GroupableRelatableTO.class.cast(updated).getMembership(oMemb.getGroupKey()). - ifPresent(uMemb -> { - oMemb.getPlainAttrs().stream(). - filter(attr -> uMemb.getPlainAttr(attr.getSchema()).isEmpty()). - forEach(attr -> uMemb.getPlainAttrs().add(attr)); - oMemb.getVirAttrs().stream(). - filter(attr -> uMemb.getVirAttr(attr.getSchema()).isEmpty()). - forEach(attr -> uMemb.getVirAttrs().add(attr)); - })); + if (updated instanceof GroupableRelatableTO updatedTO && original instanceof GroupableRelatableTO originalTO) { + originalTO.getMemberships(). + forEach(oMemb -> updatedTO.getMembership(oMemb.getGroupKey()). + ifPresent(uMemb -> oMemb.getPlainAttrs().stream(). + filter(attr -> uMemb.getPlainAttr(attr.getSchema()).isEmpty()). + forEach(attr -> uMemb.getPlainAttrs().add(attr)))); } - // remove from the updated object any plain or virtual attribute without values, thus triggering for removal in + // remove from the updated object any plain attribute without values, thus triggering for removal in // the generated patch updated.getPlainAttrs().removeIf(attr -> attr.getValues().isEmpty()); - updated.getVirAttrs().removeIf(attr -> attr.getValues().isEmpty()); - if (updated instanceof GroupableRelatableTO) { - GroupableRelatableTO.class.cast(updated).getMemberships().forEach(memb -> { - memb.getPlainAttrs().removeIf(attr -> attr.getValues().isEmpty()); - memb.getVirAttrs().removeIf(attr -> attr.getValues().isEmpty()); - }); + if (updated instanceof GroupableRelatableTO updatedTO) { + updatedTO.getMemberships(). + forEach(memb -> memb.getPlainAttrs().removeIf(attr -> attr.getValues().isEmpty())); } } diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupWizardBuilder.java index ba44a5477c6..936adcc25cd 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupWizardBuilder.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/GroupWizardBuilder.java @@ -101,7 +101,7 @@ protected Serializable onApplyInternal(final AnyWrapper modelObject) { result = groupRestClient.create(req); } else { GroupTO original = getOriginalItem().getInnerObject(); - fixPlainAndVirAttrs(updated, original); + fixPlainAttrs(updated, original); // SYNCOPE-1170 boolean othersNotEqualsOrBlanks = diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java index f2985e6de07..b91a95f60a4 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java @@ -80,7 +80,7 @@ protected Serializable onApplyInternal(final AnyWrapper modelObject) { result = userRestClient.create(req); } else { - fixPlainAndVirAttrs(inner, getOriginalItem().getInnerObject()); + fixPlainAttrs(inner, getOriginalItem().getInnerObject()); UserUR userUR = AnyOperations.diff(inner, getOriginalItem().getInnerObject(), false); if (StringUtils.isNotBlank(inner.getPassword())) { diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/VirAttrs.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/VirAttrs.java deleted file mode 100644 index 44c65e5a4ac..00000000000 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/VirAttrs.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.client.console.wizards.any; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import org.apache.commons.lang3.StringUtils; -import org.apache.syncope.client.console.SyncopeConsoleSession; -import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel; -import org.apache.syncope.client.ui.commons.ajax.markup.html.LabelInfo; -import org.apache.syncope.client.ui.commons.markup.html.form.AbstractFieldPanel; -import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel; -import org.apache.syncope.client.ui.commons.wicket.markup.html.bootstrap.tabs.Accordion; -import org.apache.syncope.client.ui.commons.wizards.AjaxWizard; -import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper; -import org.apache.syncope.client.ui.commons.wizards.any.UserWrapper; -import org.apache.syncope.common.lib.Attr; -import org.apache.syncope.common.lib.EntityTOUtils; -import org.apache.syncope.common.lib.to.AnyTO; -import org.apache.syncope.common.lib.to.GroupableRelatableTO; -import org.apache.syncope.common.lib.to.MembershipTO; -import org.apache.syncope.common.lib.to.VirSchemaTO; -import org.apache.syncope.common.lib.types.SchemaType; -import org.apache.wicket.extensions.markup.html.tabs.AbstractTab; -import org.apache.wicket.markup.html.WebMarkupContainer; -import org.apache.wicket.markup.html.list.ListItem; -import org.apache.wicket.markup.html.list.ListView; -import org.apache.wicket.model.IModel; -import org.apache.wicket.model.Model; -import org.apache.wicket.model.PropertyModel; -import org.apache.wicket.model.ResourceModel; -import org.apache.wicket.model.StringResourceModel; -import org.apache.wicket.model.util.ListModel; - -public class VirAttrs extends AbstractAttrs { - - private static final long serialVersionUID = -7982691107029848579L; - - private final AnyWrapper modelObject; - - public VirAttrs( - final AnyWrapper modelObject, - final AjaxWizard.Mode mode, - final List anyTypeClasses, - final List whichVirAttrs) { - - super(modelObject, mode, anyTypeClasses, whichVirAttrs); - this.modelObject = modelObject; - - setTitleModel(new ResourceModel("attributes.virtual")); - - add(new Accordion("virSchemas", List.of(new AbstractTab( - new ResourceModel("attributes.accordion", "Virtual Attributes")) { - - private static final long serialVersionUID = 1037272333056449378L; - - @Override - public WebMarkupContainer getPanel(final String panelId) { - return new VirAttrs.VirSchemas(panelId, schemas, attrs); - } - }), Model.of(0)).setOutputMarkupId(true)); - - add(new ListView<>("membershipsVirSchemas", memberships) { - - private static final long serialVersionUID = 9101744072914090143L; - - @Override - protected void populateItem(final ListItem item) { - MembershipTO membTO = item.getModelObject(); - item.add(new Accordion("membershipVirSchemas", List.of(new AbstractTab( - new StringResourceModel("attributes.membership.accordion", VirAttrs.this, Model.of(membTO))) { - - private static final long serialVersionUID = 1037272333056449378L; - - @Override - public WebMarkupContainer getPanel(final String panelId) { - return new VirAttrs.VirSchemas( - panelId, - membershipSchemas.get(membTO.getGroupKey()), - new ListModel<>(getAttrsFromTO(membTO))); - } - }), Model.of(-1)).setOutputMarkupId(true)); - } - }); - } - - @Override - protected SchemaType getSchemaType() { - return SchemaType.VIRTUAL; - } - - @Override - protected List getAttrsFromTO() { - return attributable.getVirAttrs().stream().sorted(attrComparator).collect(Collectors.toList()); - } - - @Override - protected List getAttrsFromTO(final MembershipTO membershipTO) { - return membershipTO.getVirAttrs().stream().sorted(attrComparator).collect(Collectors.toList()); - } - - @Override - protected void setAttrs() { - List virAttrs = new ArrayList<>(); - - Map attrMap = EntityTOUtils.buildAttrMap(attributable.getVirAttrs()); - - virAttrs.addAll(schemas.values().stream().map(schema -> { - Attr attrTO = new Attr(); - attrTO.setSchema(schema.getKey()); - if (attrMap.containsKey(schema.getKey())) { - attrTO.getValues().addAll(attrMap.get(schema.getKey()).getValues()); - } else { - attrTO.getValues().add(StringUtils.EMPTY); - } - return attrTO; - }).toList()); - - attributable.getVirAttrs().clear(); - attributable.getVirAttrs().addAll(virAttrs); - } - - @Override - protected void setAttrs(final MembershipTO membershipTO) { - Map attrMap = GroupableRelatableTO.class.cast(attributable). - getMembership(membershipTO.getGroupKey()). - map(gr -> EntityTOUtils.buildAttrMap(gr.getVirAttrs())). - orElseGet(HashMap::new); - - List virAttrs = membershipSchemas.get(membershipTO.getGroupKey()).values().stream().map(schema -> { - Attr attr = new Attr(); - attr.setSchema(schema.getKey()); - if (attrMap.get(schema.getKey()) == null || attrMap.get(schema.getKey()).getValues().isEmpty()) { - attr.getValues().add(StringUtils.EMPTY); - } else { - attr.getValues().addAll(attrMap.get(schema.getKey()).getValues()); - } - return attr; - }).toList(); - - membershipTO.getVirAttrs().clear(); - membershipTO.getVirAttrs().addAll(virAttrs); - } - - public class VirSchemas extends Schemas { - - private static final long serialVersionUID = -4730563859116024676L; - - public VirSchemas( - final String id, - final Map schemas, - final IModel> attrTOs) { - super(id); - - add(new ListView<>("schemas", attrTOs) { - - private static final long serialVersionUID = 9101744072914090143L; - - @Override - @SuppressWarnings("unchecked") - protected void populateItem(final ListItem item) { - Attr attrTO = item.getModelObject(); - VirSchemaTO virSchemaTO = schemas.get(attrTO.getSchema()); - - AbstractFieldPanel panel = new AjaxTextFieldPanel( - "panel", - virSchemaTO.getLabel(SyncopeConsoleSession.get().getLocale()), - new Model<>(), - false); - - if (mode == AjaxWizard.Mode.TEMPLATE) { - AjaxTextFieldPanel.class.cast(panel).enableJexlHelp().setEnabled(!virSchemaTO.isReadonly()); - } else { - panel = new MultiFieldPanel.Builder<>( - new PropertyModel>(attrTO, "values")).build( - "panel", - virSchemaTO.getLabel(SyncopeConsoleSession.get().getLocale()), - AjaxTextFieldPanel.class.cast(panel)); - panel.setEnabled(!virSchemaTO.isReadonly()); - } - - item.add(panel); - - if (!attrTO.getValues().isEmpty() - && VirAttrs.this.modelObject instanceof UserWrapper - && UserWrapper.class.cast(VirAttrs.this.modelObject).getPreviousUserTO() != null) { - - panel.showExternAction(new LabelInfo("externalAction", StringUtils.EMPTY)); - } - } - }); - } - } -} diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel.html index e6b1a79f118..b377eaf5012 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel.html +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel.html @@ -45,16 +45,6 @@

-
-
-

-
-
-
- [virSchemas] -
-
-
diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel.properties index e5b9884798a..051020324e8 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel.properties @@ -16,4 +16,3 @@ # under the License. plainSchemas=Plain Schemas derSchemas=Derived Schemas -virSchemas=Virtual Schemas diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_fr_CA.properties index 6519550353c..e8e311a46c1 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_fr_CA.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_fr_CA.properties @@ -14,6 +14,5 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -plainSchemas=Schémas simples -derSchemas=Schémas dérivés -virSchemas=Schémas virtuels +plainSchemas=Sch\u00e9mas simples +derSchemas=Sch\u00e9mas d\u00e9riv\u00e9s diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_it.properties index e5b9884798a..051020324e8 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_it.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_it.properties @@ -16,4 +16,3 @@ # under the License. plainSchemas=Plain Schemas derSchemas=Derived Schemas -virSchemas=Virtual Schemas diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_ja.properties index d91e2d72873..f037a57811b 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_ja.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_ja.properties @@ -16,4 +16,3 @@ # under the License. plainSchemas=\u30d7\u30ec\u30fc\u30f3\u30b9\u30ad\u30fc\u30de derSchemas=\u6d3e\u751f\u30b9\u30ad\u30fc\u30de -virSchemas=\u4eee\u60f3\u30b9\u30ad\u30fc\u30de diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_pt_BR.properties index e5b9884798a..051020324e8 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_pt_BR.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_pt_BR.properties @@ -16,4 +16,3 @@ # under the License. plainSchemas=Plain Schemas derSchemas=Derived Schemas -virSchemas=Virtual Schemas diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_ru.properties index 7f0a1c2a761..217a7b84da7 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_ru.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassDetailsPanel_ru.properties @@ -15,9 +15,7 @@ # specific language governing permissions and limitations # under the License. # -# plainSchemas=ПроÑтые атрибуты +# plainSchemas=\u00d0\u009f\u00d1\u0080\u00d0\u00be\u00d1\u0081\u00d1\u0082\u00d1\u008b\u00d0\u00b5 \u00d0\u00b0\u00d1\u0082\u00d1\u0080\u00d0\u00b8\u00d0\u00b1\u00d1\u0083\u00d1\u0082\u00d1\u008b plainSchemas=\u041f\u0440\u043e\u0441\u0442\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b -# derSchemas=Производные атрибуты +# derSchemas=\u00d0\u009f\u00d1\u0080\u00d0\u00be\u00d0\u00b8\u00d0\u00b7\u00d0\u00b2\u00d0\u00be\u00d0\u00b4\u00d0\u00bd\u00d1\u008b\u00d0\u00b5 \u00d0\u00b0\u00d1\u0082\u00d1\u0080\u00d0\u00b8\u00d0\u00b1\u00d1\u0083\u00d1\u0082\u00d1\u008b derSchemas=\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b -# virSchemas=Виртуальные атрибуты -virSchemas=\u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.properties index 5614a54ecad..8f92ac22a5f 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel.properties @@ -19,5 +19,4 @@ any.new=New AnyTypeClass anyTypeClasses=AnyTypeClasses plainSchemas=Plain Schemas derSchemas=Derived Schemas -virSchemas=Virtual Schemas inUseByTypes=AnyTypes diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_fr_CA.properties index 6fa53091024..cddacebeec8 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_fr_CA.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_fr_CA.properties @@ -17,7 +17,6 @@ any.edit=Modifier classe tout type ${key} any.new=Nouvelle classe tout type anyTypeClasses=Classes tous types -plainSchemas=Schémas simples -derSchemas=Schémas dérivés -virSchemas=Schémas virtuels +plainSchemas=Sch\u00e9mas simples +derSchemas=Sch\u00e9mas d\u00e9riv\u00e9s inUseByTypes=Tous types diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_it.properties index cc1c289a590..6b85715cf12 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_it.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_it.properties @@ -19,5 +19,4 @@ any.new=Nuovo AnyTypeClass anyTypeClasses=AnyTypeClasses plainSchemas=Plain Schemas derSchemas=Derived Schemas -virSchemas=Virtual Schemas inUseByTypes=AnyTypes diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_ja.properties index 55ba9916028..e014c291c5e 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_ja.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_ja.properties @@ -19,5 +19,4 @@ any.new=\u65b0\u3057\u3044\u4efb\u610f\u30bf\u30a4\u30d7\u30af\u30e9\u30b9 anyTypeClasses=\u4efb\u610f\u30bf\u30a4\u30d7\u30af\u30e9\u30b9 plainSchemas=\u30d7\u30ec\u30fc\u30f3\u30b9\u30ad\u30fc\u30de derSchemas=\u6d3e\u751f\u30b9\u30ad\u30fc\u30de -virSchemas=\u4eee\u60f3\u30b9\u30ad\u30fc\u30de inUseByTypes=\u4efb\u610f\u30bf\u30a4\u30d7 diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_pt_BR.properties index fbe36fd6347..0fe3266bc98 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_pt_BR.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_pt_BR.properties @@ -19,5 +19,4 @@ any.new=Novo AnyTypeClass anyTypeClasses=AnyTypeClasses plainSchemas=Plain Schemas derSchemas=Derived Schemas -virSchemas=Virtual Schemas inUseByTypes=AnyTypes diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_ru.properties index c6f2f84068b..2cdceab8edb 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_ru.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/AnyTypeClassesPanel_ru.properties @@ -15,17 +15,15 @@ # specific language governing permissions and limitations # under the License. # -# any.edit=Изменить клаÑÑ Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° объектов ${key} +# any.edit=\u00d0\u0098\u00d0\u00b7\u00d0\u00bc\u00d0\u00b5\u00d0\u00bd\u00d0\u00b8\u00d1\u0082\u00d1\u008c \u00d0\u00ba\u00d0\u00bb\u00d0\u00b0\u00d1\u0081\u00d1\u0081 \u00d0\u00b4\u00d0\u00bb\u00d1\u008f \u00d1\u0082\u00d0\u00b8\u00d0\u00bf\u00d0\u00b0 \u00d0\u00be\u00d0\u00b1\u00d1\u008a\u00d0\u00b5\u00d0\u00ba\u00d1\u0082\u00d0\u00be\u00d0\u00b2 ${key} any.edit=\u0418\u0445\u043c\u0435\u043d\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0442\u0438\u043f\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 ${key} -# any.new=Создать клаÑÑ Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° объектов +# any.new=\u00d0\u00a1\u00d0\u00be\u00d0\u00b7\u00d0\u00b4\u00d0\u00b0\u00d1\u0082\u00d1\u008c \u00d0\u00ba\u00d0\u00bb\u00d0\u00b0\u00d1\u0081\u00d1\u0081 \u00d0\u00b4\u00d0\u00bb\u00d1\u008f \u00d1\u0082\u00d0\u00b8\u00d0\u00bf\u00d0\u00b0 \u00d0\u00be\u00d0\u00b1\u00d1\u008a\u00d0\u00b5\u00d0\u00ba\u00d1\u0082\u00d0\u00be\u00d0\u00b2 any.new=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0442\u0438\u043f\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 -# anyTypeClasses=КлаÑÑ Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° объектов +# anyTypeClasses=\u00d0\u009a\u00d0\u00bb\u00d0\u00b0\u00d1\u0081\u00d1\u0081 \u00d0\u00b4\u00d0\u00bb\u00d1\u008f \u00d1\u0082\u00d0\u00b8\u00d0\u00bf\u00d0\u00b0 \u00d0\u00be\u00d0\u00b1\u00d1\u008a\u00d0\u00b5\u00d0\u00ba\u00d1\u0082\u00d0\u00be\u00d0\u00b2 anyTypeClasses=\u041a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0442\u0438\u043f\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 -# plainSchemas=ПроÑтые атрибуты +# plainSchemas=\u00d0\u009f\u00d1\u0080\u00d0\u00be\u00d1\u0081\u00d1\u0082\u00d1\u008b\u00d0\u00b5 \u00d0\u00b0\u00d1\u0082\u00d1\u0080\u00d0\u00b8\u00d0\u00b1\u00d1\u0083\u00d1\u0082\u00d1\u008b plainSchemas=\u041f\u0440\u043e\u0441\u0442\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b -# derSchemas=Производные атрибуты +# derSchemas=\u00d0\u009f\u00d1\u0080\u00d0\u00be\u00d0\u00b8\u00d0\u00b7\u00d0\u00b2\u00d0\u00be\u00d0\u00b4\u00d0\u00bd\u00d1\u008b\u00d0\u00b5 \u00d0\u00b0\u00d1\u0082\u00d1\u0080\u00d0\u00b8\u00d0\u00b1\u00d1\u0083\u00d1\u0082\u00d1\u008b derSchemas=\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b -# virSchemas=Виртуальные атрибуты -virSchemas=\u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b -# inUseByTypes=Тип объектов +# inUseByTypes=\u00d0\u00a2\u00d0\u00b8\u00d0\u00bf \u00d0\u00be\u00d0\u00b1\u00d1\u008a\u00d0\u00b5\u00d0\u00ba\u00d1\u0082\u00d0\u00be\u00d0\u00b2 inUseByTypes=\u0422\u0438\u043f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_fr_CA.properties deleted file mode 100644 index 2fbe9d07d84..00000000000 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails_fr_CA.properties +++ /dev/null @@ -1,24 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -required_alert=Tous les champs du formulaire sont obligatoires -edit_attribute=Modifier attribut -attributes=Attributs virtuels -title=Schéma virtuel -readonly=Lecture seulement -resource=Ressource -anyType=Type -extAttrName=Attribut externe diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html index 92bf09bb9cb..8bb6131b19e 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html @@ -30,7 +30,7 @@

diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.properties index 1693f614076..bf01272724a 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.properties @@ -17,7 +17,7 @@ configurationStatus=Configuration Status createResourceOrPullTask=Create Resource or PullTask createPolicy=Create Policy -createVirSchemaOrAnyType=Create Virtual Schema or AnyType +createAnyType=Create AnyType createSecurityQuestion=Create Security Question createRole=Create Role createNotification=Create Notification diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_fr_CA.properties index 1670c8a8c5e..28a7ae20b10 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_fr_CA.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_fr_CA.properties @@ -14,12 +14,12 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -configurationStatus=État de la configuration -createResourceOrPullTask=Création d'une ressource ou tâche pull -createPolicy=Créer une stratégie -createVirSchemaOrAnyType=Créer un schéma virtuel ou un type quelconque -createSecurityQuestion=Créer une question de sécurité -createRole=Créer un rôle -createNotification=Créer un avis +configurationStatus=\u00c9tat de la configuration +createResourceOrPullTask=Cr\u00e9ation d'une ressource ou t\u00e2che pull +createPolicy=Cr\u00e9er une strat\u00e9gie +createAnyType=Cr\u00e9er un type quelconque +createSecurityQuestion=Cr\u00e9er une question de s\u00e9curit\u00e9 +createRole=Cr\u00e9er un r\u00f4le +createNotification=Cr\u00e9er un avis done=Fait todo=A faire diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_it.properties index 37252bfc747..7c010700adc 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_it.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_it.properties @@ -17,7 +17,7 @@ configurationStatus=Stato Configurazione createResourceOrPullTask=Crea Risorsa o PullTask createPolicy=Crea Politica -createVirSchemaOrAnyType=Crea Virtual Schema o AnyType +createAnyType=Crea AnyType createSecurityQuestion=Crea Domanda di Sicurezza createRole=Crea Ruolo createNotification=Crea Notifica diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_ja.properties index ad183bed22a..97ca5091db5 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_ja.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_ja.properties @@ -17,7 +17,7 @@ configurationStatus=\u8a2d\u5b9a\u30b9\u30c6\u30fc\u30bf\u30b9 createResourceOrPullTask=\u30ea\u30bd\u30fc\u30b9\u307e\u305f\u306f\u30d7\u30eb\u30bf\u30b9\u30af\u3092\u4f5c\u6210 createPolicy=\u30dd\u30ea\u30b7\u30fc\u3092\u4f5c\u6210 -createVirSchemaOrAnyType=\u4eee\u60f3\u30b9\u30ad\u30fc\u30de\u307e\u305f\u306f\u4efb\u610f\u30bf\u30a4\u30d7\u3092\u4f5c\u6210 +createAnyType=\u4eee\u60f3\u30b9\u30ad\u30fc\u30de\u307e\u305f\u306f\u4efb\u610f\u30bf\u30a4\u30d7\u3092\u4f5c\u6210 createSecurityQuestion=\u79d8\u5bc6\u306e\u8cea\u554f\u3092\u4f5c\u6210 createRole=\u30ed\u30fc\u30eb\u3092\u4f5c\u6210 createNotification=\u901a\u77e5\u3092\u4f5c\u6210 diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_pt_BR.properties index 774a9d95489..ba4206f1347 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_pt_BR.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_pt_BR.properties @@ -17,7 +17,7 @@ configurationStatus=Estado de configura\u00e7\u00e3o createResourceOrPullTask=Criar recursos ou PullTask createPolicy=Criar Politica -createVirSchemaOrAnyType=Criar Virtual Schema ou AnyType +createAnyType=Criar AnyType createSecurityQuestion=Criar Perguntas de Seguran\u00e7a createRole=Criar Fun\u00e7\u00e3o createNotification=Criar Notifica\u00e7\u00e3o diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_ru.properties index 3b09c47333d..fdc962e5839 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_ru.properties +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_ru.properties @@ -14,21 +14,20 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -# configurationStatus=Ð¡Ñ‚Ð°Ñ‚ÑƒÑ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ð¸ +# configurationStatus=\u00d0\u00a1\u00d1\u0082\u00d0\u00b0\u00d1\u0082\u00d1\u0083\u00d1\u0081 \u00d0\u00ba\u00d0\u00be\u00d0\u00bd\u00d1\u0084\u00d0\u00b8\u00d0\u00b3\u00d1\u0083\u00d1\u0080\u00d0\u00b0\u00d1\u0086\u00d0\u00b8\u00d0\u00b8 configurationStatus=\u0421\u0442\u0430\u0442\u0443\u0441 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 -# createResourceOrPullTask=Создать реÑÑƒÑ€Ñ Ð¸Ð»Ð¸ задачу +# createResourceOrPullTask=\u00d0\u00a1\u00d0\u00be\u00d0\u00b7\u00d0\u00b4\u00d0\u00b0\u00d1\u0082\u00d1\u008c \u00d1\u0080\u00d0\u00b5\u00d1\u0081\u00d1\u0083\u00d1\u0080\u00d1\u0081 \u00d0\u00b8\u00d0\u00bb\u00d0\u00b8 \u00d0\u00b7\u00d0\u00b0\u00d0\u00b4\u00d0\u00b0\u00d1\u0087\u00d1\u0083 createResourceOrPullTask=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441 \u0438\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0443 -# createPolicy=Создать политику +# createPolicy=\u00d0\u00a1\u00d0\u00be\u00d0\u00b7\u00d0\u00b4\u00d0\u00b0\u00d1\u0082\u00d1\u008c \u00d0\u00bf\u00d0\u00be\u00d0\u00bb\u00d0\u00b8\u00d1\u0082\u00d0\u00b8\u00d0\u00ba\u00d1\u0083 createPolicy=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0443 -# createVirSchemaOrAnyType=Создать Ñхему или тип объекта -createVirSchemaOrAnyType=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0445\u0435\u043c\u0443 \u0438\u043b\u0438 \u0442\u0438\u043f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 -# createSecurityQuestion=Создать Ð²Ð¾Ð¿Ñ€Ð¾Ñ +createAnyType=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0445\u0435\u043c\u0443 \u0438\u043b\u0438 \u0442\u0438\u043f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 +# createSecurityQuestion=\u00d0\u00a1\u00d0\u00be\u00d0\u00b7\u00d0\u00b4\u00d0\u00b0\u00d1\u0082\u00d1\u008c \u00d0\u00b2\u00d0\u00be\u00d0\u00bf\u00d1\u0080\u00d0\u00be\u00d1\u0081 createSecurityQuestion=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0432\u043e\u043f\u0440\u043e\u0441 -# createRole=Создать роль +# createRole=\u00d0\u00a1\u00d0\u00be\u00d0\u00b7\u00d0\u00b4\u00d0\u00b0\u00d1\u0082\u00d1\u008c \u00d1\u0080\u00d0\u00be\u00d0\u00bb\u00d1\u008c createRole=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0440\u043e\u043b\u044c -# createNotification=Создать уведомление +# createNotification=\u00d0\u00a1\u00d0\u00be\u00d0\u00b7\u00d0\u00b4\u00d0\u00b0\u00d1\u0082\u00d1\u008c \u00d1\u0083\u00d0\u00b2\u00d0\u00b5\u00d0\u00b4\u00d0\u00be\u00d0\u00bc\u00d0\u00bb\u00d0\u00b5\u00d0\u00bd\u00d0\u00b8\u00d0\u00b5 createNotification=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 -# done=Выполнено +# done=\u00d0\u0092\u00d1\u008b\u00d0\u00bf\u00d0\u00be\u00d0\u00bb\u00d0\u00bd\u00d0\u00b5\u00d0\u00bd\u00d0\u00be done=\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e -# К выполнению +# \u00d0\u009a \u00d0\u00b2\u00d1\u008b\u00d0\u00bf\u00d0\u00be\u00d0\u00bb\u00d0\u00bd\u00d0\u00b5\u00d0\u00bd\u00d0\u00b8\u00d1\u008e todo=\u041a \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044e diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs.html b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs.html deleted file mode 100644 index abff807cc08..00000000000 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs.html +++ /dev/null @@ -1,26 +0,0 @@ - - - -
- -
- - - \ No newline at end of file diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs.properties deleted file mode 100644 index 812b050fe46..00000000000 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs.properties +++ /dev/null @@ -1,18 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -attribute.empty.list=No virtual attributes available -attributes.virtual=Virtual Attributes diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_fr_CA.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_fr_CA.properties deleted file mode 100644 index c99fd0ed6ed..00000000000 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_fr_CA.properties +++ /dev/null @@ -1,18 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -attribute.empty.list=Aucun attribut virtuel disponible -attributes.virtual=Attributs virtuels diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_it.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_it.properties deleted file mode 100644 index 711f97015fd..00000000000 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_it.properties +++ /dev/null @@ -1,18 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -attribute.empty.list=Non ci sono attributi virtuali disponibili -attributes.virtual=Attributi Virtuali diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_ja.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_ja.properties deleted file mode 100644 index f274ab8001e..00000000000 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_ja.properties +++ /dev/null @@ -1,18 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -attribute.empty.list=\u4eee\u60f3\u5c5e\u6027\u306f\u3042\u308a\u307e\u305b\u3093 -attributes.virtual=\u4eee\u60f3\u5c5e\u6027 diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_pt_BR.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_pt_BR.properties deleted file mode 100644 index eb977484fd7..00000000000 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_pt_BR.properties +++ /dev/null @@ -1,18 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -attribute.empty.list=Sem atributos virtuais dispon\u00edveis -attributes.virtual=Virtual Attributes diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_ru.properties b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_ru.properties deleted file mode 100644 index 750989648a3..00000000000 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/wizards/any/VirAttrs_ru.properties +++ /dev/null @@ -1,19 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -attribute.empty.list=\u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 -attributes.virtual=\u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b diff --git a/client/idrepo/console/src/test/java/org/apache/syncope/client/console/AbstractTest.java b/client/idrepo/console/src/test/java/org/apache/syncope/client/console/AbstractTest.java index 4584a7b2910..6a2065f74f0 100644 --- a/client/idrepo/console/src/test/java/org/apache/syncope/client/console/AbstractTest.java +++ b/client/idrepo/console/src/test/java/org/apache/syncope/client/console/AbstractTest.java @@ -44,7 +44,6 @@ import org.apache.syncope.client.console.commons.ImplementationInfoProvider; import org.apache.syncope.client.console.commons.PolicyTabProvider; import org.apache.syncope.client.console.commons.StatusProvider; -import org.apache.syncope.client.console.commons.VirSchemaDetailsPanelProvider; import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup; import org.apache.syncope.client.console.wizards.any.UserFormFinalizer; import org.apache.syncope.client.lib.AuthenticationHandler; @@ -150,7 +149,6 @@ public TestSyncopeWebApplication( final AnyDirectoryPanelAdditionalActionLinksProvider anyDirectoryPanelAdditionalActionLinksProvider, final AnyWizardBuilderAdditionalSteps anyWizardBuilderAdditionalSteps, final StatusProvider statusProvider, - final VirSchemaDetailsPanelProvider virSchemaDetailsPanelProvider, final ImplementationInfoProvider implementationInfoProvider, final AccessPolicyConfProvider accessPolicyConfProvider, final List policyTabProviders, @@ -159,8 +157,8 @@ public TestSyncopeWebApplication( super(props, lookup, serviceOps, resourceProvider, anyDirectoryPanelAdditionalActionsProvider, anyDirectoryPanelAdditionalActionLinksProvider, anyWizardBuilderAdditionalSteps, statusProvider, - virSchemaDetailsPanelProvider, implementationInfoProvider, accessPolicyConfProvider, - policyTabProviders, userFormFinalizers, resources); + implementationInfoProvider, accessPolicyConfProvider, policyTabProviders, userFormFinalizers, + resources); } public interface SyncopeServiceClient extends SyncopeService, Client { @@ -250,8 +248,6 @@ public SyncopeClientFactoryBean newClientFactory() { NumbersInfo.ConfItem.NOTIFICATION.name(), false); numbersInfo.getConfCompleteness().put( NumbersInfo.ConfItem.PULL_TASK.name(), false); - numbersInfo.getConfCompleteness().put( - NumbersInfo.ConfItem.VIR_SCHEMA.name(), false); numbersInfo.getConfCompleteness().put( NumbersInfo.ConfItem.ANY_TYPE.name(), false); numbersInfo.getConfCompleteness().put( diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/layout/UserFormLayoutInfo.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/layout/UserFormLayoutInfo.java index 0ec64c42bd2..a876b192dbd 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/layout/UserFormLayoutInfo.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/layout/UserFormLayoutInfo.java @@ -33,8 +33,6 @@ public class UserFormLayoutInfo extends AbstractAnyFormBaseLayout whichDerAttrs = new HashMap<>(); - private final Map whichVirAttrs = new HashMap<>(); - private boolean passwordManagement = true; private boolean detailsManagement = true; @@ -53,10 +51,6 @@ public Map getWhichDerAttrs() { return whichDerAttrs; } - public Map getWhichVirAttrs() { - return whichVirAttrs; - } - @Override protected Class getDefaultFormClass() { return UserFormPanel.class; diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/AnyFormPanel.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/AnyFormPanel.java index c29ff5ec5e6..ac40a2439da 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/AnyFormPanel.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/AnyFormPanel.java @@ -27,7 +27,6 @@ import org.apache.syncope.client.enduser.panels.any.Groups; import org.apache.syncope.client.enduser.panels.any.PlainAttrs; import org.apache.syncope.client.enduser.panels.any.Resources; -import org.apache.syncope.client.enduser.panels.any.VirAttrs; import org.apache.syncope.client.enduser.panels.captcha.CaptchaPanel; import org.apache.syncope.client.ui.commons.panels.CardPanel; import org.apache.syncope.client.ui.commons.wizards.any.UserWrapper; @@ -109,16 +108,7 @@ protected void buildLayout(final UserWrapper modelObject) { form.add(new CardPanel.Builder() .setName("attributes.derived") .setComponent(derAttrs) - .isVisible(formLayoutInfo.isVirAttrs() && derAttrs.isPanelVisible()).build("derAttrsPanelCard")); - - VirAttrs virAttrs = new VirAttrs(EnduserConstants.CONTENT_PANEL, - modelObject, anyTypeClasses, formLayoutInfo.getWhichVirAttrs()); - virAttrs.setOutputMarkupId(true); - - form.add(new CardPanel.Builder() - .setName("attributes.virtual") - .setComponent(virAttrs) - .isVisible(formLayoutInfo.isVirAttrs() && virAttrs.isPanelVisible()).build("virAttrsPanelCard")); + .isVisible(formLayoutInfo.isDerAttrs() && derAttrs.isPanelVisible()).build("derAttrsPanelCard")); Resources resources = new Resources(EnduserConstants.CONTENT_PANEL, modelObject); resources.setOutputMarkupId(true); @@ -138,47 +128,28 @@ protected void buildLayout(final UserWrapper modelObject) { .isVisible(SyncopeWebApplication.get().isCaptchaEnabled()).build("captchaPanelCard")); } - protected void fixPlainAndVirAttrs(final AnyTO updated, final AnyTO original) { - // re-add to the updated object any missing plain or virtual attribute (compared to original): this to cope with - // form layout, which might have not included some plain or virtual attributes + protected void fixPlainAttrs(final AnyTO updated, final AnyTO original) { + // re-add to the updated object any missing plain attribute (compared to original): this to cope with + // form layout, which might have not included some plain attributes for (Attr plainAttr : original.getPlainAttrs()) { if (updated.getPlainAttr(plainAttr.getSchema()).isEmpty()) { updated.getPlainAttrs().add(plainAttr); } } - for (Attr virAttr : original.getVirAttrs()) { - if (updated.getVirAttr(virAttr.getSchema()).isEmpty()) { - updated.getVirAttrs().add(virAttr); - } - } - if (updated instanceof GroupableRelatableTO && original instanceof GroupableRelatableTO) { - GroupableRelatableTO.class - .cast(original).getMemberships().forEach(oMemb -> { - GroupableRelatableTO.class - .cast(updated).getMembership(oMemb.getGroupKey()).ifPresent(uMemb -> { - oMemb.getPlainAttrs() - .stream(). - filter(attr -> uMemb.getPlainAttr(attr.getSchema()).isEmpty()). - forEach(attr -> uMemb.getPlainAttrs().add(attr)); - oMemb.getVirAttrs() - .stream(). - filter(attr -> uMemb.getVirAttr(attr.getSchema()).isEmpty()). - forEach(attr -> uMemb.getVirAttrs().add(attr)); - } - ); - }); + if (updated instanceof GroupableRelatableTO updatedTO && original instanceof GroupableRelatableTO originalTO) { + originalTO.getMemberships().forEach(oMemb -> updatedTO.getMembership(oMemb.getGroupKey()). + ifPresent(uMemb -> oMemb.getPlainAttrs().stream(). + filter(attr -> uMemb.getPlainAttr(attr.getSchema()).isEmpty()). + forEach(attr -> uMemb.getPlainAttrs().add(attr)))); } - // remove from the updated object any plain or virtual attribute without values, thus triggering for removal in + // remove from the updated object any plain attribute without values, thus triggering for removal in // the generated patch updated.getPlainAttrs().removeIf(attr -> attr.getValues().isEmpty()); - updated.getVirAttrs().removeIf(attr -> attr.getValues().isEmpty()); - if (updated instanceof GroupableRelatableTO) { - GroupableRelatableTO.class.cast(updated).getMemberships().forEach(memb -> { - memb.getPlainAttrs().removeIf(attr -> attr.getValues().isEmpty()); - memb.getVirAttrs().removeIf(attr -> attr.getValues().isEmpty()); - }); + if (updated instanceof GroupableRelatableTO updatedTO) { + updatedTO.getMemberships(). + forEach(memb -> memb.getPlainAttrs().removeIf(attr -> attr.getValues().isEmpty())); } } } diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserFormPanel.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserFormPanel.java index ad5a1adfc11..46d589638bb 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserFormPanel.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserFormPanel.java @@ -105,7 +105,7 @@ protected void onFormSubmit(final AjaxRequestTarget target) { AnyWrapper updatedWrapper = form.getModelObject(); UserTO userTO = updatedWrapper.getInnerObject(); - fixPlainAndVirAttrs(userTO, getOriginalItem().getInnerObject()); + fixPlainAttrs(userTO, getOriginalItem().getInnerObject()); // update and set page parameters according to provisioning result UserUR updateReq = AnyOperations.diff(userTO, getOriginalItem().getInnerObject(), false); ProvisioningResult provisioningResult = updateReq.isEmpty() diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/AbstractAttrs.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/AbstractAttrs.java index 0c19683f3ea..b092ac3bd8e 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/AbstractAttrs.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/AbstractAttrs.java @@ -115,8 +115,6 @@ protected List loadMembershipAttrs() { memberships.add(membership); } else if (AbstractAttrs.this instanceof DerAttrs && !membership.getDerAttrs().isEmpty()) { memberships.add(membership); - } else if (AbstractAttrs.this instanceof VirAttrs && !membership.getVirAttrs().isEmpty()) { - memberships.add(membership); } } diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/VirAttrs.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/VirAttrs.java deleted file mode 100644 index 2563d1fcbff..00000000000 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/VirAttrs.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.client.enduser.panels.any; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import org.apache.commons.lang3.StringUtils; -import org.apache.syncope.client.enduser.SyncopeEnduserSession; -import org.apache.syncope.client.enduser.layout.CustomizationOption; -import org.apache.syncope.client.enduser.markup.html.form.MultiFieldPanel; -import org.apache.syncope.client.ui.commons.markup.html.form.AbstractFieldPanel; -import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel; -import org.apache.syncope.client.ui.commons.wicket.markup.html.bootstrap.tabs.Accordion; -import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper; -import org.apache.syncope.common.lib.Attr; -import org.apache.syncope.common.lib.EntityTOUtils; -import org.apache.syncope.common.lib.to.GroupableRelatableTO; -import org.apache.syncope.common.lib.to.MembershipTO; -import org.apache.syncope.common.lib.to.UserTO; -import org.apache.syncope.common.lib.to.VirSchemaTO; -import org.apache.syncope.common.lib.types.SchemaType; -import org.apache.wicket.extensions.markup.html.tabs.AbstractTab; -import org.apache.wicket.markup.html.WebMarkupContainer; -import org.apache.wicket.markup.html.list.ListItem; -import org.apache.wicket.markup.html.list.ListView; -import org.apache.wicket.model.IModel; -import org.apache.wicket.model.Model; -import org.apache.wicket.model.PropertyModel; -import org.apache.wicket.model.StringResourceModel; -import org.apache.wicket.model.util.ListModel; - -public class VirAttrs extends AbstractAttrs { - - private static final long serialVersionUID = -7982691107029848579L; - - public VirAttrs( - final String id, - final AnyWrapper modelObject, - final List anyTypeClasses, - final Map whichVirAttrs) { - - super(id, modelObject, anyTypeClasses, whichVirAttrs); - - add(new VirAttrs.VirSchemas("virSchemas", null, schemas, attrs).setOutputMarkupId(true)); - add(new ListView<>("membershipsVirSchemas", membershipTOs) { - - private static final long serialVersionUID = 9101744072914090143L; - - @Override - protected void populateItem(final ListItem item) { - MembershipTO membershipTO = item.getModelObject(); - item.add(new Accordion("membershipVirSchemas", List.of( - new AbstractTab(new StringResourceModel( - "attributes.membership.accordion", VirAttrs.this, Model.of(membershipTO))) { - - private static final long serialVersionUID = 1037272333056449378L; - - @Override - public WebMarkupContainer getPanel(final String panelId) { - return new VirAttrs.VirSchemas( - panelId, - membershipTO.getGroupName(), - membershipSchemas.get(membershipTO.getGroupKey()), - new ListModel<>(getAttrsFromTO(membershipTO))); - } - }), Model.of(-1)).setOutputMarkupId(true)); - } - }).setOutputMarkupId(true); - } - - @Override - protected SchemaType getSchemaType() { - return SchemaType.VIRTUAL; - } - - @Override - protected List getAttrsFromTO() { - return userTO.getVirAttrs().stream().sorted(attrComparator).collect(Collectors.toList()); - } - - @Override - protected List getAttrsFromTO(final MembershipTO membershipTO) { - return membershipTO.getVirAttrs().stream().sorted(attrComparator).collect(Collectors.toList()); - } - - @Override - protected void setAttrs() { - List virAttrs = new ArrayList<>(); - - Map attrMap = EntityTOUtils.buildAttrMap(userTO.getVirAttrs()); - - virAttrs.addAll(schemas.values().stream().map(schema -> { - Attr attrTO = new Attr(); - attrTO.setSchema(schema.getKey()); - if (attrMap.containsKey(schema.getKey())) { - attrTO.getValues().addAll(attrMap.get(schema.getKey()).getValues()); - } else { - attrTO.getValues().add(StringUtils.EMPTY); - } - return attrTO; - }).toList()); - - userTO.getVirAttrs().clear(); - userTO.getVirAttrs().addAll(virAttrs); - } - - @Override - protected void setAttrs(final MembershipTO membershipTO) { - Map attrMap = GroupableRelatableTO.class.cast(userTO).getMembership(membershipTO.getGroupKey()). - map(gr -> EntityTOUtils.buildAttrMap(gr.getVirAttrs())). - orElseGet(HashMap::new); - - List virAttrs = membershipSchemas.get(membershipTO.getGroupKey()).values().stream().map(schema -> { - Attr attr = new Attr(); - attr.setSchema(schema.getKey()); - if (attrMap.get(schema.getKey()) == null || attrMap.get(schema.getKey()).getValues().isEmpty()) { - attr.getValues().add(StringUtils.EMPTY); - } else { - attr.getValues().addAll(attrMap.get(schema.getKey()).getValues()); - } - return attr; - }).toList(); - - membershipTO.getVirAttrs().clear(); - membershipTO.getVirAttrs().addAll(virAttrs); - } - - public class VirSchemas extends Schemas { - - private static final long serialVersionUID = -4730563859116024676L; - - public VirSchemas( - final String id, - final String groupName, - final Map schemas, - final IModel> attrTOs) { - - super(id); - - add(new ListView<>("schemas", attrTOs) { - - private static final long serialVersionUID = 9101744072914090143L; - - @Override - @SuppressWarnings("unchecked") - protected void populateItem(final ListItem item) { - Attr attrTO = item.getModelObject(); - - // set default values, if any - if (attrTO.getValues().stream().filter(StringUtils::isNotBlank).count() == 0) { - attrTO.getValues().clear(); - attrTO.getValues().addAll(getDefaultValues(attrTO.getSchema(), groupName)); - } - - VirSchemaTO virSchemaTO = schemas.get(attrTO.getSchema()); - - AbstractFieldPanel panel = new AjaxTextFieldPanel( - "panel", - virSchemaTO.getLabel(SyncopeEnduserSession.get().getLocale()), - new Model<>(), - false); - - panel = new MultiFieldPanel.Builder<>( - new PropertyModel>(attrTO, "values")).build( - "panel", - virSchemaTO.getLabel(SyncopeEnduserSession.get().getLocale()), - AjaxTextFieldPanel.class.cast(panel)); - panel.setEnabled(!virSchemaTO.isReadonly() && !renderAsReadonly(attrTO.getSchema(), groupName)); - - item.add(panel); - } - }); - } - } -} diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/rest/SchemaRestClient.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/rest/SchemaRestClient.java index a878ef0899d..58a391c3b97 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/rest/SchemaRestClient.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/rest/SchemaRestClient.java @@ -103,10 +103,6 @@ public List getDerSchemaNames() { return getSchemaNames(SchemaType.DERIVED); } - public List getVirSchemaNames() { - return getSchemaNames(SchemaType.VIRTUAL); - } - public T read(final SchemaType schemaType, final String key) { return getService(SchemaService.class).read(schemaType, key); } diff --git a/client/idrepo/enduser/src/main/resources/customFormLayout.json b/client/idrepo/enduser/src/main/resources/customFormLayout.json index c6bdc1ee5a7..4a11228aeb5 100644 --- a/client/idrepo/enduser/src/main/resources/customFormLayout.json +++ b/client/idrepo/enduser/src/main/resources/customFormLayout.json @@ -4,11 +4,9 @@ "groups": true, "plainAttrs": true, "derAttrs": true, - "virAttrs": true, "resources": true, "whichPlainAttrs": {}, "whichDerAttrs": {}, - "whichVirAttrs": {}, "passwordManagement": true, "detailsManagement": true, "sidebarLayout": { diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication.properties index b5cfbfd2a96..73f7b76e6b0 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication.properties @@ -91,7 +91,6 @@ cancel=Cancel editchangepassword=Change password attributes.derived=Derived Attributes attributes.plain=Plain Attributes -attributes.virtual=Virtual Attributes captcha=Captcha details=Details user_request_error=Error during user request. Please contact your administrator diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_fr_CA.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_fr_CA.properties index 4cb035495c8..56d614e715f 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_fr_CA.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_fr_CA.properties @@ -90,7 +90,6 @@ cancel=Annuler editchangepassword=Changer mot de passe attributes.derived=Derived Attributes attributes.plain=Editer le profil -attributes.virtual=Virtual Attributes captcha=Captcha details=Des d\u00e9tails user_request_error=Erreur lors de la demande de l'utilisateur. Veuillez contacter votre administrateur diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_it.properties index ffa23aa2d78..dd048076309 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_it.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_it.properties @@ -88,7 +88,6 @@ cancel=Cancel editchangepassword=Gestione password attributes.derived=Derived Attributes attributes.plain=Plain Attributes -attributes.virtual=Virtual Attributes captcha=Captcha details=Details user-requests-link=User Requests diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ja.properties index dd6cb624152..4b9640769ed 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ja.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ja.properties @@ -14,85 +14,84 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -users=\u30E6\u30FC\u30B6\u30FC -groups=\u30B0\u30EB\u30FC\u30D7 -configuration=\u8A2D\u5B9A -resources=\u30EA\u30BD\u30FC\u30B9 -connectors=\u30B3\u30CD\u30AF\u30BF\u30FC -reports=\u30EC\u30DD\u30FC\u30C8 -tasks=\u30BF\u30B9\u30AF -logout=\u30ED\u30B0\u30A2\u30A6\u30C8 -schema=\u30B9\u30AD\u30FC\u30DE -operation_succeeded=\u64CD\u4F5C\u3092\u6B63\u5E38\u306B\u5B9F\u884C\u3057\u307E\u3057\u305F -operation_error=\u8981\u6C42\u3057\u305F\u64CD\u4F5C\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F -alert=\u30A2\u30E9\u30FC\u30C8\: -confirmDelete=\u9078\u629E\u3057\u305F\u30A2\u30A4\u30C6\u30E0\u3092\u524A\u9664\u3057\u3066\u3082\u3088\u308D\u3057\u3044\u3067\u3059\u304B? -confirmUnlink=\u9078\u629E\u3057\u305F\u30A2\u30A4\u30C6\u30E0\u3068\u30EA\u30BD\u30FC\u30B9\u306E\u9593\u306E\u30EA\u30F3\u30AF\u3092\u524A\u9664\u3057\u3066\u3082\u3088\u308D\u3057\u3044\u3067\u3059\u304B? -confirmUnassign=\u9078\u629E\u3057\u305F\u30A2\u30A4\u30C6\u30E0\u3068\u30EA\u30BD\u30FC\u30B9\u306E\u9593\u306E\u5272\u308A\u5F53\u3066\u3092\u524A\u9664\u3057\u3066\u3082\u3088\u308D\u3057\u3044\u3067\u3059\u304B? -confirmDeprovision=\u9078\u629E\u3057\u305F\u30A2\u30A4\u30C6\u30E0\u3092\u30C7\u30D7\u30ED\u30D3\u30B8\u30E7\u30F3\uFF08\u524A\u9664\uFF09\u3057\u3066\u3082\u3088\u308D\u3057\u3044\u3067\u3059\u304B? -confirmProvision=\u9078\u629E\u3057\u305F\u30A2\u30A4\u30C6\u30E0\u3092\u30D7\u30ED\u30D3\u30B8\u30E7\u30F3\u3057\u3066\u3082\u3088\u308D\u3057\u3044\u3067\u3059\u304B? -confirmClone=\u9078\u629E\u3057\u305F\u30A2\u30A4\u30C6\u30E0\u3092\u8907\u88FD\u3057\u3066\u3082\u3088\u308D\u3057\u3044\u3067\u3059\u304B? -dropDownChoiceField.nullValid=\uFF11\u3064\u9078\u629E -DateTimeField$HoursValidator=\u6642\u9593\u306E\u5024\u306F 1\uFF5E12 \u306E\u7BC4\u56F2 -error=\u30A8\u30E9\u30FC -generic_error=\u64CD\u4F5C\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F -id=\u30AD\u30FC -name=\u540D\u524D -palette.available=\u5229\u7528\u53EF\u80FD -palette.selected=\u9078\u629E\u6E08 -jexl_info=\u3053\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u306F JEXL \u8868\u73FE\u3092\u671F\u5F85\u3057\u3066\u3044\u307E\u3059\u3002\u4F8B\: -jexl_ex1=\u59D3 + ',' + \u540D -jexl_ex2='\u65B0\u3057\u3044.' + \u59D3 -jexl_syntax_url=\u5B8C\u5168 JEXL \u53C2\u7167 -create=\u4F5C\u6210 -key=\u30AD\u30FC -types=\u30BF\u30A4\u30D7 -realms=\u30EC\u30EB\u30E0 -roles=\u30ED\u30FC\u30EB -policies=\u30DD\u30EA\u30B7\u30FC -workflow=\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC -logs=\u30ED\u30B0 -layouts=\u30EC\u30A4\u30A2\u30A6\u30C8 -notifications=\u901A\u77E5 -parameters=\u30D1\u30E9\u30E1\u30FC\u30BF\u30FC -extensions=\u62E1\u5F35 -NavigatorLabel=${from} \uFF5E ${to} \uFF0F ${of} \u884C\u3092\u8868\u793A\u4E2D -displayRows=\u8868\u793A\u3059\u308B\u884C\u6570\: +users=\u30e6\u30fc\u30b6\u30fc +groups=\u30b0\u30eb\u30fc\u30d7 +configuration=\u8a2d\u5b9a +resources=\u30ea\u30bd\u30fc\u30b9 +connectors=\u30b3\u30cd\u30af\u30bf\u30fc +reports=\u30ec\u30dd\u30fc\u30c8 +tasks=\u30bf\u30b9\u30af +logout=\u30ed\u30b0\u30a2\u30a6\u30c8 +schema=\u30b9\u30ad\u30fc\u30de +operation_succeeded=\u64cd\u4f5c\u3092\u6b63\u5e38\u306b\u5b9f\u884c\u3057\u307e\u3057\u305f +operation_error=\u8981\u6c42\u3057\u305f\u64cd\u4f5c\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f +alert=\u30a2\u30e9\u30fc\u30c8\: +confirmDelete=\u9078\u629e\u3057\u305f\u30a2\u30a4\u30c6\u30e0\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +confirmUnlink=\u9078\u629e\u3057\u305f\u30a2\u30a4\u30c6\u30e0\u3068\u30ea\u30bd\u30fc\u30b9\u306e\u9593\u306e\u30ea\u30f3\u30af\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +confirmUnassign=\u9078\u629e\u3057\u305f\u30a2\u30a4\u30c6\u30e0\u3068\u30ea\u30bd\u30fc\u30b9\u306e\u9593\u306e\u5272\u308a\u5f53\u3066\u3092\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +confirmDeprovision=\u9078\u629e\u3057\u305f\u30a2\u30a4\u30c6\u30e0\u3092\u30c7\u30d7\u30ed\u30d3\u30b8\u30e7\u30f3\uff08\u524a\u9664\uff09\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +confirmProvision=\u9078\u629e\u3057\u305f\u30a2\u30a4\u30c6\u30e0\u3092\u30d7\u30ed\u30d3\u30b8\u30e7\u30f3\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +confirmClone=\u9078\u629e\u3057\u305f\u30a2\u30a4\u30c6\u30e0\u3092\u8907\u88fd\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +dropDownChoiceField.nullValid=\uff11\u3064\u9078\u629e +DateTimeField$HoursValidator=\u6642\u9593\u306e\u5024\u306f 1\uff5e12 \u306e\u7bc4\u56f2 +error=\u30a8\u30e9\u30fc +generic_error=\u64cd\u4f5c\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f +id=\u30ad\u30fc +name=\u540d\u524d +palette.available=\u5229\u7528\u53ef\u80fd +palette.selected=\u9078\u629e\u6e08 +jexl_info=\u3053\u306e\u30d5\u30a3\u30fc\u30eb\u30c9\u306f JEXL \u8868\u73fe\u3092\u671f\u5f85\u3057\u3066\u3044\u307e\u3059\u3002\u4f8b\: +jexl_ex1=\u59d3 + ',' + \u540d +jexl_ex2='\u65b0\u3057\u3044.' + \u59d3 +jexl_syntax_url=\u5b8c\u5168 JEXL \u53c2\u7167 +create=\u4f5c\u6210 +key=\u30ad\u30fc +types=\u30bf\u30a4\u30d7 +realms=\u30ec\u30eb\u30e0 +roles=\u30ed\u30fc\u30eb +policies=\u30dd\u30ea\u30b7\u30fc +workflow=\u30ef\u30fc\u30af\u30d5\u30ed\u30fc +logs=\u30ed\u30b0 +layouts=\u30ec\u30a4\u30a2\u30a6\u30c8 +notifications=\u901a\u77e5 +parameters=\u30d1\u30e9\u30e1\u30fc\u30bf\u30fc +extensions=\u62e1\u5f35 +NavigatorLabel=${from} \uff5e ${to} \uff0f ${of} \u884c\u3092\u8868\u793a\u4e2d +displayRows=\u8868\u793a\u3059\u308b\u884c\u6570\: OrderByLink.CSS.ascending=sorting_asc OrderByLink.CSS.descending=sorting_desc OrderByLink.CSS.none=sorting -entitlements=\u4ED8\u4E0E -audit=\u76E3\u67FB -connectors.confirm.reload=\u3053\u306E\u8981\u6C42\u306F\u3001\u5B9F\u884C\u4E2D\u306E\u64CD\u4F5C\u306B\u5BFE\u3057\u3066\u5371\u967A\u306A\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002\u7D9A\u884C\u3057\u307E\u3059\u304B? -intAttrNameInfo.help=\u30AA\u30FC\u30C8\u30B3\u30F3\u30D7\u30EA\u30FC\u30C8\u306E\u5C5E\u6027\u4EE5\u5916\u306B\u3001\u30B0\u30EB\u30FC\u30D7\u3001\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3001\u30E1\u30F3\u30D0\u30FC\u30B7\u30C3\u30D7\u3082\u53C2\u7167\u53EF\u80FD\u3067\u3059 (\u8A72\u5F53\u3059\u308B\u5834\u5408)\u3002\u4F8B\: -confirmGlobalLogout=\u30B0\u30ED\u30FC\u30D0\u30EB\u30ED\u30B0\u30A2\u30A6\u30C8\u3057\u3066\u3082\u3088\u308D\u3057\u3044\u3067\u3059\u304B? -implementations=\u5C0E\u5165 -timeout=\u64CD\u4F5C\u306B\u9577\u6642\u9593\u304B\u304B\u3063\u3066\u3044\u307E\u3059\: \u30D0\u30C3\u30AF\u30B0\u30E9\u30A6\u30F3\u30C9\u3067\u5B9F\u884C\u3055\u308C\u307E\u3059\u3002 \u7D50\u679C\u3092\u5F8C\u3067\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044 (\u30A8\u30E9\u30FC\u306F\u5F15\u304D\u8D77\u3053\u3057\u307E\u305B\u3093)\u3002 -editsecurityquestion=\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3 -before=\u524D -after=\u5F8C +entitlements=\u4ed8\u4e0e +audit=\u76e3\u67fb +connectors.confirm.reload=\u3053\u306e\u8981\u6c42\u306f\u3001\u5b9f\u884c\u4e2d\u306e\u64cd\u4f5c\u306b\u5bfe\u3057\u3066\u5371\u967a\u306a\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002\u7d9a\u884c\u3057\u307e\u3059\u304b? +intAttrNameInfo.help=\u30aa\u30fc\u30c8\u30b3\u30f3\u30d7\u30ea\u30fc\u30c8\u306e\u5c5e\u6027\u4ee5\u5916\u306b\u3001\u30b0\u30eb\u30fc\u30d7\u3001\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3001\u30e1\u30f3\u30d0\u30fc\u30b7\u30c3\u30d7\u3082\u53c2\u7167\u53ef\u80fd\u3067\u3059 (\u8a72\u5f53\u3059\u308b\u5834\u5408)\u3002\u4f8b\: +confirmGlobalLogout=\u30b0\u30ed\u30fc\u30d0\u30eb\u30ed\u30b0\u30a2\u30a6\u30c8\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b? +implementations=\u5c0e\u5165 +timeout=\u64cd\u4f5c\u306b\u9577\u6642\u9593\u304b\u304b\u3063\u3066\u3044\u307e\u3059\: \u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u3067\u5b9f\u884c\u3055\u308c\u307e\u3059\u3002 \u7d50\u679c\u3092\u5f8c\u3067\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044 (\u30a8\u30e9\u30fc\u306f\u5f15\u304d\u8d77\u3053\u3057\u307e\u305b\u3093)\u3002 +editsecurityquestion=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 +before=\u524d +after=\u5f8c -captcha_error=\u5165\u529B\u3055\u308C\u305F\u30AD\u30E3\u30D7\u30C1\u30E3\u304C\u4E00\u81F4\u3057\u307E\u305B\u3093 -blank_security_info=\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u306E\u8CEA\u554F\u304A\u3088\u3073/\u307E\u305F\u306F\u56DE\u7B54\u304C\u7A7A\u767D\u3067\u3042\u308B +captcha_error=\u5165\u529b\u3055\u308c\u305f\u30ad\u30e3\u30d7\u30c1\u30e3\u304c\u4e00\u81f4\u3057\u307e\u305b\u3093 +blank_security_info=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u306e\u8cea\u554f\u304a\u3088\u3073/\u307e\u305f\u306f\u56de\u7b54\u304c\u7a7a\u767d\u3067\u3042\u308b invalid.security.answer=Invalid security answer tooLargeFile=File is too large, max upload file size is ${maxUploadSizeB} bytes (${maxUploadSizeMB} MB). home=Home profile=Personal Information requests=User Requests -edituser=\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u7DE8\u96C6 +edituser=\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u7de8\u96c6 submit=Submit cancel=Cancel editchangepassword=Change password attributes.derived=Derived Attributes attributes.plain=Plain Attributes -attributes.virtual=Virtual Attributes captcha=Captcha details=Details user-requests-link=User Requests self-pwd-reset-link=Self Password Reset self-registration-link=Self Registration -user_request_error=\u30E6\u30FC\u30B6\u30FC\u30EA\u30AF\u30A8\u30B9\u30C8\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002 \u7BA1\u7406\u8005\u306B\u9023\u7D61\u3057\u3066\u304F\u3060\u3055\u3044 +user_request_error=\u30e6\u30fc\u30b6\u30fc\u30ea\u30af\u30a8\u30b9\u30c8\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 \u7ba1\u7406\u8005\u306b\u9023\u7d61\u3057\u3066\u304f\u3060\u3055\u3044 page.home=Home page.changePassword=Change Password diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_pt_BR.properties index 4ccad26602b..45fc6c0abe2 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_pt_BR.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_pt_BR.properties @@ -88,7 +88,6 @@ cancel=Cancel editchangepassword=Change password attributes.derived=Derived Attributes attributes.plain=Plain Attributes -attributes.virtual=Virtual Attributes captcha=Captcha details=Details user-requests-link=User Requests diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ru.properties index 2ecc5877c96..4e79d544b0e 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ru.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ru.properties @@ -14,59 +14,59 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -users=\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0438 -groups=\u0413\u0440\u0443\u043F\u043F\u044B -configuration=\u041A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044F -resources=\u0420\u0435\u0441\u0443\u0440\u0441\u044B -connectors=\u041A\u043E\u043D\u043D\u0435\u043A\u0442\u043E\u0440\u044B -reports=\u041E\u0442\u0447\u0435\u0442\u044B +users=\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 +groups=\u0413\u0440\u0443\u043f\u043f\u044b +configuration=\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f +resources=\u0420\u0435\u0441\u0443\u0440\u0441\u044b +connectors=\u041a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u044b +reports=\u041e\u0442\u0447\u0435\u0442\u044b tasks=\u0417\u0430\u0434\u0430\u0447\u0438 -logout=\u0412\u044B\u0439\u0442\u0438 +logout=\u0412\u044b\u0439\u0442\u0438 schema=\u0410\u0442\u0440\u0438\u0431\u0443\u0442 -operation_succeeded=\u041E\u043F\u0435\u0440\u0430\u0446\u0438\u044F \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0430 \u0443\u0441\u043F\u0435\u0448\u043D\u043E -operation_error=\u0412\u043E \u0432\u0440\u0435\u043C\u044F \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F \u0437\u0430\u043F\u0440\u043E\u0441\u0430 \u043F\u0440\u043E\u0438\u0437\u043E\u0448\u043B\u0430 \u043E\u0448\u0438\u0431\u043A\u0430 -alert=\u041F\u0440\u0435\u0434\u0443\u043F\u0440\u0435\u0436\u0434\u0435\u043D\u0438\u0435: -confirmDelete=\u0412\u044B \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043B\u0438\u0442\u044C \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0435 \u043E\u0431\u044A\u0435\u043A\u0442\u044B? -confirmUnlink=\u0412\u044B \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043B\u0438\u0442\u044C \u0441\u0432\u044F\u0437\u044C \u043C\u0435\u0436\u0434\u0443 \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u043C\u0438 \u043E\u0431\u044A\u0435\u043A\u0442\u0430\u043C\u0438 \u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u043E\u043C? -confirmUnassign=\u0412\u044B \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043B\u0438\u0442\u044C \u043D\u0430\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u0430 \u0434\u043B\u044F \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0445 \u043E\u0431\u044A\u0435\u043A\u0442\u043E\u0432? -confirmDeprovision=\u0412\u044B \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u043E\u0442\u043E\u0437\u0432\u0430\u0442\u044C \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0435 \u043E\u0431\u044A\u0435\u043A\u0442\u044B? -confirmProvision=\u0412\u044B \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u043F\u0440\u0435\u0434\u043E\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0435 \u043E\u0431\u044A\u0435\u043A\u0442\u044B? -confirmClone=\u0412\u044B \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u043A\u043B\u043E\u043D\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0435 \u043E\u0431\u044A\u0435\u043A\u0442\u044B? -dropDownChoiceField.nullValid=\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 -DateTimeField$HoursValidator=\u0427\u0430\u0441\u044B \u0434\u043E\u043B\u0436\u043D\u044B \u0431\u044B\u0442\u044C \u0443\u043A\u0430\u0437\u0430\u043D\u044B \u0432 \u0434\u0438\u0430\u043F\u0430\u0437\u043E\u043D\u0435 (1, 12) -error=\u041E\u0448\u0438\u0431\u043A\u0430 -generic_error=\u0412\u043E \u0432\u0440\u0435\u043C\u044F \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u0438 \u043F\u0440\u043E\u0438\u0437\u043E\u0448\u043B\u0430 \u043E\u0448\u0438\u0431\u043A\u0430 -id=\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 -name=\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 -palette.available=\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u043E -palette.selected=\u0412\u044B\u0431\u0440\u0430\u043D\u043E -jexl_info=\u042D\u0442\u043E \u043F\u043E\u043B\u0435 \u0434\u043E\u043B\u0436\u043D\u043E \u0441\u043E\u0434\u0435\u0440\u0436\u0430\u0442\u044C JEXL \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u0435, \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440: +operation_succeeded=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e +operation_error=\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 +alert=\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435: +confirmDelete=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b? +confirmUnlink=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 \u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u043c? +confirmUnassign=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u0430 \u0434\u043b\u044f \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432? +confirmDeprovision=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043e\u0442\u043e\u0437\u0432\u0430\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b? +confirmProvision=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b? +confirmClone=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b? +dropDownChoiceField.nullValid=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 +DateTimeField$HoursValidator=\u0427\u0430\u0441\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u0432 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 (1, 12) +error=\u041e\u0448\u0438\u0431\u043a\u0430 +generic_error=\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 +id=\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 +name=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 +palette.available=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e +palette.selected=\u0412\u044b\u0431\u0440\u0430\u043d\u043e +jexl_info=\u042d\u0442\u043e \u043f\u043e\u043b\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c JEXL \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440: jexl_ex1=surname + ',' + firstname jexl_ex2='new.' + surname -jexl_syntax_url=\u0421\u043F\u0440\u0430\u0432\u043A\u0430 \u043F\u043E JEXL -create=\u0421\u043E\u0437\u0434\u0430\u0442\u044C -key=\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 -types=\u0422\u0438\u043F\u044B \u043E\u0431\u044A\u0435\u043A\u0442\u043E\u0432 -realms=\u041E\u0431\u043B\u0430\u0441\u0442\u0438 -roles=\u0420\u043E\u043B\u0438 -policies=\u041F\u043E\u043B\u0438\u0442\u0438\u043A\u0438 -workflow=\u041F\u0440\u043E\u0446\u0435\u0441\u0441 \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D\u0438\u044F -logs=\u041B\u043E\u0433\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435 -layouts=\u0420\u0430\u0437\u043C\u0435\u0442\u043A\u0430 -notifications=\u0423\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u044F -parameters=\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B -extensions=\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F -NavigatorLabel=\u0421\u0442\u0440\u043E\u043A\u0438 ${from}-${to} \u0438\u0437 ${of} -displayRows=\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u043F\u043E: -OrderByLink.CSS.ascending=\u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0430_\u043F\u043E_\u0432\u043E\u0437\u0440\u0430\u0441\u0442\u0430\u043D\u0438\u044E -OrderByLink.CSS.descending=\u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0430_\u043F\u043E_\u0443\u0431\u044B\u0432\u0430\u043D\u0438\u044E -OrderByLink.CSS.none=\u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0430 -entitlements=\u041F\u043E\u043B\u043D\u043E\u043C\u043E\u0447\u0438\u044F +jexl_syntax_url=\u0421\u043f\u0440\u0430\u0432\u043a\u0430 \u043f\u043e JEXL +create=\u0421\u043e\u0437\u0434\u0430\u0442\u044c +key=\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 +types=\u0422\u0438\u043f\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 +realms=\u041e\u0431\u043b\u0430\u0441\u0442\u0438 +roles=\u0420\u043e\u043b\u0438 +policies=\u041f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 +workflow=\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u0438\u044f +logs=\u041b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 +layouts=\u0420\u0430\u0437\u043c\u0435\u0442\u043a\u0430 +notifications=\u0423\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f +parameters=\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b +extensions=\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f +NavigatorLabel=\u0421\u0442\u0440\u043e\u043a\u0438 ${from}-${to} \u0438\u0437 ${of} +displayRows=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e: +OrderByLink.CSS.ascending=\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430_\u043f\u043e_\u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0430\u043d\u0438\u044e +OrderByLink.CSS.descending=\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430_\u043f\u043e_\u0443\u0431\u044b\u0432\u0430\u043d\u0438\u044e +OrderByLink.CSS.none=\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430 +entitlements=\u041f\u043e\u043b\u043d\u043e\u043c\u043e\u0447\u0438\u044f audit=\u0410\u0443\u0434\u0438\u0442 -connectors.confirm.reload=\u0412\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u0435 \u044D\u0442\u043E\u0433\u043E \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044F \u043F\u043E\u0442\u0435\u043D\u0446\u0438\u0430\u043B\u044C\u043D\u043E \u043E\u043F\u0430\u0441\u043D\u043E \u0434\u043B\u044F \u0432\u044B\u043F\u043E\u043B\u043D\u044F\u0435\u043C\u044B\u0445 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u0439. \u041F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442\u044C? -intAttrNameInfo.help=\u041F\u043E\u043C\u0438\u043C\u043E \u0430\u0432\u0442\u043E\u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043E\u0432, \u0432\u044B \u0442\u0430\u043A\u0436\u0435 \u043C\u043E\u0436\u0435\u0442\u0435 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u0433\u0440\u0443\u043F\u043F\u044B, \u0440\u0430\u0437\u043B\u0438\u0447\u043D\u044B\u0435 \u043E\u0431\u044A\u0435\u043A\u0442\u044B \u0438 \u0447\u043B\u0435\u043D\u0441\u0442\u0432\u043E (\u043F\u0440\u0438 \u043D\u0430\u043B\u0438\u0447\u0438\u0438), \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440: +connectors.confirm.reload=\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043e\u043f\u0430\u0441\u043d\u043e \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439. \u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c? +intAttrNameInfo.help=\u041f\u043e\u043c\u0438\u043c\u043e \u0430\u0432\u0442\u043e\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432, \u0432\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0433\u0440\u0443\u043f\u043f\u044b, \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0438 \u0447\u043b\u0435\u043d\u0441\u0442\u0432\u043e (\u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438), \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440: confirmGlobalLogout=Do you really want to perform global logout? -implementations=\u0420\u0435\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u0438 +implementations=\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 timeout=Operation is taking too long: it will be executed in background. Please check later for the result (errors won't be triggered). editsecurityquestion=Security question @@ -74,26 +74,25 @@ before=Before after=After captcha_error=Captcha entered does not match -blank_security_info=\u041A\u043E\u043D\u0442\u0440\u043E\u043B\u044C\u043D\u044B\u0439 \u0432\u043E\u043F\u0440\u043E\u0441 \u0438/\u0438\u043B\u0438 \u043E\u0442\u0432\u0435\u0442 \u043F\u0443\u0441\u0442\u044B +blank_security_info=\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 \u0438/\u0438\u043b\u0438 \u043e\u0442\u0432\u0435\u0442 \u043f\u0443\u0441\u0442\u044b invalid.security.answer=Invalid security answer tooLargeFile=File is too large, max upload file size is ${maxUploadSizeB} bytes (${maxUploadSizeMB} MB). home=Home profile=Personal Information requests=User Requests -edituser=\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043F\u0440\u043E\u0444\u0438\u043B\u044C +edituser=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0444\u0438\u043b\u044c submit=Submit cancel=Cancel editchangepassword=Change password attributes.derived=Derived Attributes attributes.plain=Plain Attributes -attributes.virtual=Virtual Attributes captcha=Captcha details=Details user-requests-link=User Requests self-pwd-reset-link=Self Password Reset self-registration-link=Self Registration -user_request_error=\u041E\u0448\u0438\u0431\u043A\u0430 \u043F\u0440\u0438 \u0437\u0430\u043F\u0440\u043E\u0441\u0435 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F. \u041E\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044C \u043A \u0430\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440\u0443 +user_request_error=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044c \u043a \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0443 page.home=Home page.changePassword=Change Password diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel.html b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel.html index 969fcd5c584..16628b213a9 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel.html +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserFormPanel.html @@ -28,7 +28,6 @@ [groupsPanelCard] [plainAttrsPanelCard] [derAttrsPanelCard] - [virAttrsPanelCard] [resourcesPanelCard] [captchaPanelCard]
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs.html b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs.html deleted file mode 100644 index 5968a336a1f..00000000000 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - -
- -
- - - \ No newline at end of file diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs.properties deleted file mode 100644 index 812b050fe46..00000000000 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs.properties +++ /dev/null @@ -1,18 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -attribute.empty.list=No virtual attributes available -attributes.virtual=Virtual Attributes diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs_it.properties deleted file mode 100644 index 711f97015fd..00000000000 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs_it.properties +++ /dev/null @@ -1,18 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -attribute.empty.list=Non ci sono attributi virtuali disponibili -attributes.virtual=Attributi Virtuali diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs_ja.properties deleted file mode 100644 index f274ab8001e..00000000000 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs_ja.properties +++ /dev/null @@ -1,18 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -attribute.empty.list=\u4eee\u60f3\u5c5e\u6027\u306f\u3042\u308a\u307e\u305b\u3093 -attributes.virtual=\u4eee\u60f3\u5c5e\u6027 diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs_pt_BR.properties deleted file mode 100644 index eb977484fd7..00000000000 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs_pt_BR.properties +++ /dev/null @@ -1,18 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -attribute.empty.list=Sem atributos virtuais dispon\u00edveis -attributes.virtual=Virtual Attributes diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs_ru.properties deleted file mode 100644 index a162426a09d..00000000000 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/any/VirAttrs_ru.properties +++ /dev/null @@ -1,18 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -attribute.empty.list=\u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 -attributes.virtual=\u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b diff --git a/client/idrepo/enduser/src/test/java/org/apache/syncope/client/enduser/AbstractTest.java b/client/idrepo/enduser/src/test/java/org/apache/syncope/client/enduser/AbstractTest.java index e522834cfe0..7e5fe1716a4 100644 --- a/client/idrepo/enduser/src/test/java/org/apache/syncope/client/enduser/AbstractTest.java +++ b/client/idrepo/enduser/src/test/java/org/apache/syncope/client/enduser/AbstractTest.java @@ -215,8 +215,6 @@ public SyncopeClientFactoryBean newClientFactory() { NumbersInfo.ConfItem.NOTIFICATION.name(), false); numbersInfo.getConfCompleteness().put( NumbersInfo.ConfItem.PULL_TASK.name(), false); - numbersInfo.getConfCompleteness().put( - NumbersInfo.ConfItem.VIR_SCHEMA.name(), false); numbersInfo.getConfCompleteness().put( NumbersInfo.ConfItem.ANY_TYPE.name(), false); numbersInfo.getConfCompleteness().put( diff --git a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/Mapping.java b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/Mapping.java index 81bb31f7cb1..57fa9669947 100644 --- a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/Mapping.java +++ b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/Mapping.java @@ -18,10 +18,6 @@ */ package org.apache.syncope.common.lib.to; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; -import java.util.ArrayList; -import java.util.List; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; @@ -31,8 +27,6 @@ public class Mapping extends ItemContainer { private String connObjectLink; - private final List linkingItems = new ArrayList<>(); - public String getConnObjectLink() { return connObjectLink; } @@ -41,12 +35,6 @@ public void setConnObjectLink(final String connObjectLink) { this.connObjectLink = connObjectLink; } - @JacksonXmlElementWrapper(localName = "linkingItems") - @JacksonXmlProperty(localName = "linkingItem") - public List getLinkingItems() { - return linkingItems; - } - @Override public boolean equals(final Object obj) { if (this == obj) { @@ -62,7 +50,6 @@ public boolean equals(final Object obj) { return new EqualsBuilder(). appendSuper(super.equals(obj)). append(connObjectLink, other.connObjectLink). - append(linkingItems, other.linkingItems). build(); } @@ -71,7 +58,6 @@ public int hashCode() { return new HashCodeBuilder(). appendSuper(super.hashCode()). append(connObjectLink). - append(linkingItems). build(); } } diff --git a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/Provision.java b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/Provision.java index 9e82deaf77f..702bba65bca 100644 --- a/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/Provision.java +++ b/common/idm/lib/src/main/java/org/apache/syncope/common/lib/to/Provision.java @@ -44,8 +44,6 @@ public class Provision implements Serializable { private Mapping mapping; - private final List virSchemas = new ArrayList<>(); - public String getAnyType() { return anyType; } @@ -100,12 +98,6 @@ public void setMapping(final Mapping mapping) { this.mapping = mapping; } - @JacksonXmlElementWrapper(localName = "virSchemas") - @JacksonXmlProperty(localName = "virSchema") - public List getVirSchemas() { - return virSchemas; - } - @Override public boolean equals(final Object obj) { if (this == obj) { @@ -126,7 +118,6 @@ public boolean equals(final Object obj) { append(syncToken, other.syncToken). append(uidOnCreate, other.uidOnCreate). append(mapping, other.mapping). - append(virSchemas, other.virSchemas). build(); } @@ -140,7 +131,6 @@ public int hashCode() { append(ignoreCaseMatch). append(uidOnCreate). append(mapping). - append(virSchemas). build(); } } diff --git a/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/CSVPushSpec.java b/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/CSVPushSpec.java index 539c49f28d4..33b4e36f69f 100644 --- a/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/CSVPushSpec.java +++ b/common/idm/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/CSVPushSpec.java @@ -69,16 +69,6 @@ public Builder derAttrs(final Collection derAttrs) { return this; } - public Builder virAttr(final String virAttr) { - getInstance().getVirAttrs().add(virAttr); - return this; - } - - public Builder virAttrs(final Collection virAttrs) { - getInstance().getVirAttrs().addAll(virAttrs); - return this; - } - public Builder ignorePaging(final boolean ignorePaging) { getInstance().setIgnorePaging(ignorePaging); return this; @@ -96,8 +86,6 @@ public Builder propagationAction(final String propagationAction) { private List derAttrs = new ArrayList<>(); - private List virAttrs = new ArrayList<>(); - private Boolean ignorePaging; protected List propagationActions = new ArrayList<>(); @@ -129,15 +117,6 @@ public void setDerAttrs(final List derAttrs) { this.derAttrs = derAttrs; } - public List getVirAttrs() { - return virAttrs; - } - - @QueryParam("virAttrs") - public void setVirAttrs(final List virAttrs) { - this.virAttrs = virAttrs; - } - public Boolean getIgnorePaging() { return ignorePaging == null ? Boolean.FALSE : ignorePaging; } diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java index 33fbb9339fc..7fd3ed12273 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java @@ -136,11 +136,7 @@ private static void diff( } }); - // 4. virtual attributes - result.getVirAttrs().clear(); - result.getVirAttrs().addAll(updated.getVirAttrs()); - - // 5. resources + // 4. resources result.getResources().clear(); if (!incremental) { @@ -215,14 +211,10 @@ private static void diff( final MembershipTO updated, final MembershipUR result) { - // 1. plain attributes + // plain attributes result.getPlainAttrs().addAll(updated.getPlainAttrs().stream(). filter(attr -> !isEmpty(attr)). collect(Collectors.toSet())); - - // 2. virtual attributes - result.getVirAttrs().clear(); - result.getVirAttrs().addAll(updated.getVirAttrs()); } /** @@ -320,10 +312,10 @@ public static UserUR diff(final UserTO updated, final UserTO original, final boo Map, LinkedAccountTO> originalAccounts = EntityTOUtils.buildLinkedAccountMap(original.getLinkedAccounts()); - updatedAccounts.forEach((key, value) -> - result.getLinkedAccounts().add(new LinkedAccountUR.Builder(). - operation(PatchOperation.ADD_REPLACE). - linkedAccountTO(value).build())); + updatedAccounts.forEach((key, value) + -> result.getLinkedAccounts().add(new LinkedAccountUR.Builder(). + operation(PatchOperation.ADD_REPLACE). + linkedAccountTO(value).build())); if (!incremental) { originalAccounts.keySet().stream().filter(account -> !updatedAccounts.containsKey(account)). @@ -378,7 +370,7 @@ public static P diff( } else if (updated instanceof GroupTO updatedGroupTO && original instanceof GroupTO originalGroupTO) { return (P) diff(updatedGroupTO, originalGroupTO, incremental); } else if (updated instanceof AnyObjectTO updatedAnyObjectTO - && original instanceof AnyObjectTO originalObjectTO) { + && original instanceof AnyObjectTO originalObjectTO) { return (P) diff(updatedAnyObjectTO, originalObjectTO, incremental); } @@ -431,11 +423,7 @@ private static void patch(final T to, final K result.getPlainAttrs().clear(); result.getPlainAttrs().addAll(patch(EntityTOUtils.buildAttrMap(to.getPlainAttrs()), req.getPlainAttrs())); - // 3. virtual attributes - result.getVirAttrs().clear(); - result.getVirAttrs().addAll(req.getVirAttrs()); - - // 4. resources + // 3. resources for (StringPatchItem resourcePatch : req.getResources()) { switch (resourcePatch.getOperation()) { case ADD_REPLACE: @@ -518,8 +506,6 @@ public static AnyObjectTO patch(final AnyObjectTO anyObjectTO, final AnyObjectUR MembershipTO newMembershipTO = new MembershipTO.Builder(membPatch.getGroup()). // 3. plain attributes plainAttrs(membPatch.getPlainAttrs()). - // 4. virtual attributes - virAttrs(membPatch.getVirAttrs()). build(); result.getMemberships().add(newMembershipTO); @@ -569,8 +555,6 @@ public static UserTO patch(final UserTO userTO, final UserUR userUR) { MembershipTO newMembershipTO = new MembershipTO.Builder(membPatch.getGroup()). // 3. plain attributes plainAttrs(membPatch.getPlainAttrs()). - // 4. virtual attributes - virAttrs(membPatch.getVirAttrs()). build(); result.getMemberships().add(newMembershipTO); diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/EntityTOUtils.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/EntityTOUtils.java index cbe65dc17d8..9b7d37259d1 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/EntityTOUtils.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/EntityTOUtils.java @@ -67,7 +67,6 @@ public static void toAnyCR(final A anyTO, fin anyCR.setRealm(anyTO.getRealm()); anyCR.getAuxClasses().addAll(anyTO.getAuxClasses()); anyCR.getPlainAttrs().addAll(anyTO.getPlainAttrs()); - anyCR.getVirAttrs().addAll(anyTO.getVirAttrs()); anyCR.getResources().addAll(anyTO.getResources()); if (anyCR instanceof final UserCR userCR && anyTO instanceof final UserTO userTO) { @@ -101,7 +100,6 @@ public static void toAnyTO(final C anyCR, fin anyTO.setRealm(anyCR.getRealm()); anyTO.getAuxClasses().addAll(anyCR.getAuxClasses()); anyTO.getPlainAttrs().addAll(anyCR.getPlainAttrs()); - anyTO.getVirAttrs().addAll(anyCR.getVirAttrs()); anyTO.getResources().addAll(anyCR.getResources()); if (anyTO instanceof final UserTO userTO && anyCR instanceof final UserCR userCR) { diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/info/NumbersInfo.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/info/NumbersInfo.java index f9295f353a2..2f6dcc2a9cb 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/info/NumbersInfo.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/info/NumbersInfo.java @@ -35,7 +35,6 @@ public enum ConfItem { PASSWORD_POLICY(10), NOTIFICATION(8), PULL_TASK(10), - VIR_SCHEMA(10), ANY_TYPE(5), SECURITY_QUESTION(12), ROLE(15); diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultAccountRuleConf.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultAccountRuleConf.java index 7d0dfa5eeb5..75f84b0986c 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultAccountRuleConf.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultAccountRuleConf.java @@ -64,7 +64,7 @@ public class DefaultAccountRuleConf extends AbstractAccountRuleConf implements A * User attribute values not permitted. */ @Schema(anyTypeKind = AnyTypeKind.USER, - type = { SchemaType.PLAIN, SchemaType.DERIVED, SchemaType.VIRTUAL }) + type = { SchemaType.PLAIN, SchemaType.DERIVED }) private final List schemasNotPermitted = new ArrayList<>(); /** diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultPasswordRuleConf.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultPasswordRuleConf.java index 16b501f24ce..68ace87d119 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultPasswordRuleConf.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/policy/DefaultPasswordRuleConf.java @@ -64,7 +64,7 @@ public class DefaultPasswordRuleConf extends AbstractPasswordRuleConf { * User attribute values not permitted. */ @Schema(anyTypeKind = AnyTypeKind.USER, - type = { SchemaType.PLAIN, SchemaType.DERIVED, SchemaType.VIRTUAL }) + type = { SchemaType.PLAIN, SchemaType.DERIVED }) private final List schemasNotPermitted = new ArrayList<>(); public int getMaxLength() { diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyCR.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyCR.java index e577607e2e3..f7d67b90ec4 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyCR.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyCR.java @@ -96,24 +96,6 @@ public B plainAttrs(final Collection plainAttrs) { return (B) this; } - @SuppressWarnings("unchecked") - public B virAttr(final Attr virAttr) { - getInstance().getVirAttrs().add(virAttr); - return (B) this; - } - - @SuppressWarnings("unchecked") - public B virAttrs(final Collection virAttrs) { - getInstance().getVirAttrs().addAll(virAttrs); - return (B) this; - } - - @SuppressWarnings("unchecked") - public B virAttrs(final Attr... virAttrs) { - getInstance().getVirAttrs().addAll(List.of(virAttrs)); - return (B) this; - } - @SuppressWarnings("unchecked") public B resource(final String resource) { getInstance().getResources().add(resource); @@ -147,8 +129,6 @@ public R build() { private final Set plainAttrs = new HashSet<>(); - private final Set virAttrs = new HashSet<>(); - private final Set resources = new HashSet<>(); @Schema(name = "_class", requiredMode = Schema.RequiredMode.REQUIRED) @@ -199,19 +179,6 @@ public Set getDerAttrs() { return Set.of(); } - @JsonIgnore - @Override - public Optional getVirAttr(final String schema) { - return virAttrs.stream().filter(attr -> attr.getSchema().equals(schema)).findFirst(); - } - - @JacksonXmlElementWrapper(localName = "virAttrs") - @JacksonXmlProperty(localName = "virAttr") - @Override - public Set getVirAttrs() { - return virAttrs; - } - @JacksonXmlElementWrapper(localName = "resources") @JacksonXmlProperty(localName = "resource") @Override @@ -226,7 +193,6 @@ public int hashCode() { append(realm). append(auxClasses). append(plainAttrs). - append(virAttrs). append(resources). build(); } @@ -248,7 +214,6 @@ public boolean equals(final Object obj) { append(realm, other.realm). append(auxClasses, other.auxClasses). append(plainAttrs, other.plainAttrs). - append(virAttrs, other.virAttrs). append(resources, other.resources). build(); } diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyUR.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyUR.java index d2d2a8dc812..7e2f8cbb547 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyUR.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/AnyUR.java @@ -32,7 +32,6 @@ import java.util.Set; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; -import org.apache.syncope.common.lib.Attr; import org.apache.syncope.common.lib.BaseBean; @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "_class") @@ -101,24 +100,6 @@ public B plainAttrs(final Collection plainAttrs) { return (B) this; } - @SuppressWarnings("unchecked") - public B virAttr(final Attr virAttr) { - getInstance().getVirAttrs().add(virAttr); - return (B) this; - } - - @SuppressWarnings("unchecked") - public B virAttrs(final Collection virAttrs) { - getInstance().getVirAttrs().addAll(virAttrs); - return (B) this; - } - - @SuppressWarnings("unchecked") - public B virAttrs(final Attr... virAttrs) { - getInstance().getVirAttrs().addAll(List.of(virAttrs)); - return (B) this; - } - @SuppressWarnings("unchecked") public B resource(final StringPatchItem resource) { getInstance().getResources().add(resource); @@ -154,8 +135,6 @@ public R build() { private final Set plainAttrs = new HashSet<>(); - private final Set virAttrs = new HashSet<>(); - private final Set resources = new HashSet<>(); @Schema(name = "_class", requiredMode = Schema.RequiredMode.REQUIRED) @@ -195,12 +174,6 @@ public Set getPlainAttrs() { return plainAttrs; } - @JacksonXmlElementWrapper(localName = "virAttrs") - @JacksonXmlProperty(localName = "virAttr") - public Set getVirAttrs() { - return virAttrs; - } - @JacksonXmlElementWrapper(localName = "resources") @JacksonXmlProperty(localName = "resource") public Set getResources() { @@ -214,7 +187,7 @@ public Set getResources() { public boolean isEmpty() { return realm == null && auxClasses.isEmpty() - && plainAttrs.isEmpty() && virAttrs.isEmpty() + && plainAttrs.isEmpty() && resources.isEmpty(); } @@ -226,7 +199,6 @@ public int hashCode() { append(realm). append(auxClasses). append(plainAttrs). - append(virAttrs). append(resources). build(); } @@ -249,7 +221,6 @@ public boolean equals(final Object obj) { append(realm, other.realm). append(auxClasses, other.auxClasses). append(plainAttrs, other.plainAttrs). - append(virAttrs, other.virAttrs). append(resources, other.resources). build(); } diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/MembershipUR.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/MembershipUR.java index 2ec0c7fc235..44d6ea16703 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/MembershipUR.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/MembershipUR.java @@ -58,29 +58,12 @@ public Builder plainAttrs(final Collection plainAttrs) { getInstance().getPlainAttrs().addAll(plainAttrs); return this; } - - public Builder virAttr(final Attr virAttr) { - getInstance().getVirAttrs().add(virAttr); - return this; - } - - public Builder virAttrs(final Attr... virAttrs) { - getInstance().getVirAttrs().addAll(List.of(virAttrs)); - return this; - } - - public Builder virAttrs(final Collection virAttrs) { - getInstance().getVirAttrs().addAll(virAttrs); - return this; - } } private String group; private final Set plainAttrs = new HashSet<>(); - private final Set virAttrs = new HashSet<>(); - public String getGroup() { return group; } @@ -95,19 +78,12 @@ public Set getPlainAttrs() { return plainAttrs; } - @JacksonXmlElementWrapper(localName = "virAttrs") - @JacksonXmlProperty(localName = "virAttr") - public Set getVirAttrs() { - return virAttrs; - } - @Override public int hashCode() { return new HashCodeBuilder(). appendSuper(super.hashCode()). append(group). append(plainAttrs). - append(virAttrs). build(); } @@ -127,7 +103,6 @@ public boolean equals(final Object obj) { appendSuper(super.equals(obj)). append(group, other.group). append(plainAttrs, other.plainAttrs). - append(virAttrs, other.virAttrs). build(); } } diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java index 859766ecb34..09665bc5efe 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java @@ -88,8 +88,6 @@ public abstract class AnyTO implements EntityTO, RealmMember { private final Set derAttrs = new TreeSet<>(); - private final Set virAttrs = new TreeSet<>(); - private final Set resources = new TreeSet<>(); @Schema(name = "_class", requiredMode = Schema.RequiredMode.REQUIRED) @@ -231,19 +229,6 @@ public Optional getDerAttr(final String schema) { return derAttrs.stream().filter(attr -> attr.getSchema().equals(schema)).findFirst(); } - @JacksonXmlElementWrapper(localName = "virAttrs") - @JacksonXmlProperty(localName = "virAttr") - @Override - public Set getVirAttrs() { - return virAttrs; - } - - @JsonIgnore - @Override - public Optional getVirAttr(final String schema) { - return virAttrs.stream().filter(attr -> attr.getSchema().equals(schema)).findFirst(); - } - @Override public Set getResources() { return resources; @@ -266,7 +251,6 @@ public int hashCode() { append(auxClasses). append(plainAttrs). append(derAttrs). - append(virAttrs). append(resources). build(); } @@ -298,7 +282,6 @@ public boolean equals(final Object obj) { append(auxClasses, other.auxClasses). append(plainAttrs, other.plainAttrs). append(derAttrs, other.derAttrs). - append(virAttrs, other.virAttrs). append(resources, other.resources). build(); } diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java index 86a5c0f45dc..fb99fcefdc9 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java @@ -34,8 +34,6 @@ public class AnyTypeClassTO implements EntityTO { private final List derSchemas = new ArrayList<>(); - private final List virSchemas = new ArrayList<>(); - private final List inUseByTypes = new ArrayList<>(); @Override @@ -61,12 +59,6 @@ public List getDerSchemas() { return derSchemas; } - @JacksonXmlElementWrapper(localName = "virSchemas") - @JacksonXmlProperty(localName = "virSchema") - public List getVirSchemas() { - return virSchemas; - } - @JacksonXmlElementWrapper(localName = "inUseByTypes") @JacksonXmlProperty(localName = "inUseByType") public List getInUseByTypes() { diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AttributableTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AttributableTO.java index 1e029f9eefa..816112d8f47 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AttributableTO.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/AttributableTO.java @@ -31,8 +31,4 @@ public interface AttributableTO { Set getDerAttrs(); Optional getDerAttr(String schema); - - Set getVirAttrs(); - - Optional getVirAttr(String schema); } diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/MembershipTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/MembershipTO.java index 79c8305c749..7f3045ce0bf 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/MembershipTO.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/MembershipTO.java @@ -65,21 +65,6 @@ public Builder plainAttrs(final Collection plainAttrs) { return this; } - public Builder virAttr(final Attr virAttr) { - instance.getVirAttrs().add(virAttr); - return this; - } - - public Builder virAttrs(final Collection virAttrs) { - instance.getVirAttrs().addAll(virAttrs); - return this; - } - - public Builder virAttrs(final Attr... virAttrs) { - instance.getVirAttrs().addAll(List.of(virAttrs)); - return this; - } - public MembershipTO build() { return instance; } @@ -93,8 +78,6 @@ public MembershipTO build() { private final Set derAttrs = new TreeSet<>(); - private final Set virAttrs = new TreeSet<>(); - public String getGroupKey() { return groupKey; } @@ -137,19 +120,6 @@ public Optional getDerAttr(final String schema) { return derAttrs.stream().filter(attr -> attr.getSchema().equals(schema)).findFirst(); } - @JacksonXmlElementWrapper(localName = "virAttrs") - @JacksonXmlProperty(localName = "virAttr") - @Override - public Set getVirAttrs() { - return virAttrs; - } - - @JsonIgnore - @Override - public Optional getVirAttr(final String schema) { - return virAttrs.stream().filter(attr -> attr.getSchema().equals(schema)).findFirst(); - } - @Override public int hashCode() { return new HashCodeBuilder(). @@ -157,7 +127,6 @@ public int hashCode() { append(groupName). append(plainAttrs). append(derAttrs). - append(virAttrs). build(); } @@ -178,7 +147,6 @@ public boolean equals(final Object obj) { append(groupName, other.groupName). append(plainAttrs, other.plainAttrs). append(derAttrs, other.derAttrs). - append(virAttrs, other.virAttrs). build(); } diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/RealmTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/RealmTO.java index fa8951d13ea..242d368dec7 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/RealmTO.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/RealmTO.java @@ -63,8 +63,6 @@ public class RealmTO implements NamedEntityTO, TemplatableTO, AttributableTO { private final Set derAttrs = new TreeSet<>(); - private final Set virAttrs = Set.of(); - private final List actions = new ArrayList<>(); private final Map templates = new HashMap<>(); @@ -190,19 +188,6 @@ public Optional getDerAttr(final String schema) { return derAttrs.stream().filter(attr -> attr.getSchema().equals(schema)).findFirst(); } - @JacksonXmlElementWrapper(localName = "virAttrs") - @JacksonXmlProperty(localName = "virAttr") - @Override - public Set getVirAttrs() { - return virAttrs; - } - - @JsonIgnore - @Override - public Optional getVirAttr(final String schema) { - return Optional.empty(); - } - @JacksonXmlElementWrapper(localName = "actions") @JacksonXmlProperty(localName = "action") public List getActions() { diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/SchemaTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/SchemaTO.java index 6f46c9e3e8d..f577fea61fa 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/SchemaTO.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/SchemaTO.java @@ -33,7 +33,7 @@ @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "_class") @JsonPropertyOrder(value = { "_class", "key" }) -@Schema(subTypes = { PlainSchemaTO.class, DerSchemaTO.class, VirSchemaTO.class }, discriminatorProperty = "_class") +@Schema(subTypes = { PlainSchemaTO.class, DerSchemaTO.class }, discriminatorProperty = "_class") public abstract class SchemaTO implements EntityTO { private static final long serialVersionUID = 4088388951694301759L; diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/VirSchemaTO.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/VirSchemaTO.java deleted file mode 100644 index 79723119b41..00000000000 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/to/VirSchemaTO.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.common.lib.to; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; -import io.swagger.v3.oas.annotations.media.Schema; -import org.apache.commons.lang3.builder.EqualsBuilder; -import org.apache.commons.lang3.builder.HashCodeBuilder; - -@Schema(allOf = { SchemaTO.class }) -public class VirSchemaTO extends SchemaTO { - - private static final long serialVersionUID = -8198557479659701343L; - - private boolean readonly; - - private String resource; - - private String anyType; - - private String extAttrName; - - @JacksonXmlProperty(localName = "_class", isAttribute = true) - @JsonProperty("_class") - @Schema(name = "_class", requiredMode = Schema.RequiredMode.REQUIRED, - example = "org.apache.syncope.common.lib.to.VirSchemaTO") - @Override - public String getDiscriminator() { - return getClass().getName(); - } - - public boolean isReadonly() { - return readonly; - } - - public void setReadonly(final boolean readonly) { - this.readonly = readonly; - } - - public String getResource() { - return resource; - } - - public void setResource(final String resource) { - this.resource = resource; - } - - public String getAnyType() { - return anyType; - } - - public void setAnyType(final String anyType) { - this.anyType = anyType; - } - - public String getExtAttrName() { - return extAttrName; - } - - public void setExtAttrName(final String extAttrName) { - this.extAttrName = extAttrName; - } - - @Override - public int hashCode() { - return new HashCodeBuilder(). - appendSuper(super.hashCode()). - append(readonly). - append(resource). - append(anyType). - append(extAttrName). - build(); - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final VirSchemaTO other = (VirSchemaTO) obj; - return new EqualsBuilder(). - appendSuper(super.equals(obj)). - append(readonly, other.readonly). - append(resource, other.resource). - append(anyType, other.anyType). - append(extAttrName, other.extAttrName). - build(); - } -} diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java index fecae97a6d7..9ff64d1c316 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java @@ -55,7 +55,6 @@ public enum ClientExceptionType { InvalidPropagationTaskExecReport(Response.Status.BAD_REQUEST), InvalidPlainSchema(Response.Status.BAD_REQUEST), InvalidDerSchema(Response.Status.BAD_REQUEST), - InvalidVirSchema(Response.Status.BAD_REQUEST), InvalidMapping(Response.Status.BAD_REQUEST), InvalidMembership(Response.Status.BAD_REQUEST), InvalidRealm(Response.Status.BAD_REQUEST), diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/SchemaType.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/SchemaType.java index f972600cca9..7f3f0031e83 100644 --- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/SchemaType.java +++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/types/SchemaType.java @@ -21,7 +21,6 @@ import org.apache.syncope.common.lib.to.DerSchemaTO; import org.apache.syncope.common.lib.to.PlainSchemaTO; import org.apache.syncope.common.lib.to.SchemaTO; -import org.apache.syncope.common.lib.to.VirSchemaTO; public enum SchemaType { @@ -32,11 +31,7 @@ public enum SchemaType { /** * Derived schema calculated based on other attributes. */ - DERIVED(DerSchemaTO.class), - /** - * Virtual schema for attributes fetched from remote resources only. - */ - VIRTUAL(VirSchemaTO.class); + DERIVED(DerSchemaTO.class); private final Class toClass; @@ -55,8 +50,6 @@ public static SchemaType fromToClass(final Class toClass) { schemaType = SchemaType.PLAIN; } else if (DerSchemaTO.class.equals(toClass)) { schemaType = SchemaType.DERIVED; - } else if (VirSchemaTO.class.equals(toClass)) { - schemaType = SchemaType.VIRTUAL; } else { throw new IllegalArgumentException("Unexpected class: " + toClass.getName()); } diff --git a/common/idrepo/lib/src/test/java/org/apache/syncope/common/lib/SerializationTest.java b/common/idrepo/lib/src/test/java/org/apache/syncope/common/lib/SerializationTest.java index e804951bf25..8ca429696e2 100644 --- a/common/idrepo/lib/src/test/java/org/apache/syncope/common/lib/SerializationTest.java +++ b/common/idrepo/lib/src/test/java/org/apache/syncope/common/lib/SerializationTest.java @@ -55,8 +55,8 @@ public void emptyListAsRoot() throws IOException { objectMapper().writeValue(writer, original); List actual = objectMapper().readValue(writer.toString(), - new TypeReference<>() { - }); + new TypeReference<>() { + }); assertEquals(original, actual); } @@ -125,9 +125,8 @@ public void pagedResult() throws IOException { StringWriter writer = new StringWriter(); objectMapper().writeValue(writer, original); - PagedResult actual = objectMapper().readValue(writer.toString(), - new TypeReference<>() { - }); + PagedResult actual = objectMapper().readValue(writer.toString(), new TypeReference<>() { + }); assertEquals(original, actual); } @@ -136,7 +135,6 @@ public void provisioningResult() throws IOException { GroupTO group = new GroupTO(); group.setName(UUID.randomUUID().toString()); group.setRealm(SyncopeConstants.ROOT_REALM); - group.getVirAttrs().add(new Attr.Builder("rvirtualdata").value("rvirtualvalue").build()); group.getADynMembershipConds().put("USER", "username==a*"); ProvisioningResult original = new ProvisioningResult<>(); @@ -150,9 +148,8 @@ public void provisioningResult() throws IOException { StringWriter writer = new StringWriter(); objectMapper().writeValue(writer, original); - ProvisioningResult actual = objectMapper().readValue(writer.toString(), - new TypeReference<>() { - }); + ProvisioningResult actual = objectMapper().readValue(writer.toString(), new TypeReference<>() { + }); assertEquals(original, actual); } } diff --git a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AnyQuery.java b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AnyQuery.java index 630861a3b76..5d13ea2b8b5 100644 --- a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AnyQuery.java +++ b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AnyQuery.java @@ -99,8 +99,7 @@ public void setRecursive(final Boolean recursive) { } @Parameter(name = JAXRSService.PARAM_DETAILS, description = "whether detailed information is to be included, " - + "if applicable, about virtual attributes, (dynamic) roles, relationships, " - + "(dynamic) memberships or linked accounts", schema = + + "if applicable, about (dynamic) roles, relationships, (dynamic) memberships or linked accounts", schema = @Schema(implementation = Boolean.class)) public Boolean getDetails() { return Optional.ofNullable(details).orElse(Boolean.TRUE); diff --git a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/IdMLogicContext.java b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/IdMLogicContext.java index 2d07bcf632b..944577369d1 100644 --- a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/IdMLogicContext.java +++ b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/IdMLogicContext.java @@ -28,12 +28,10 @@ import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.dao.RealmSearchDAO; import org.apache.syncope.core.persistence.api.dao.RemediationDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.provisioning.api.ConnIdBundleManager; import org.apache.syncope.core.provisioning.api.ConnectorManager; import org.apache.syncope.core.provisioning.api.MappingManager; -import org.apache.syncope.core.provisioning.api.VirAttrHandler; import org.apache.syncope.core.provisioning.api.data.ConnInstanceDataBinder; import org.apache.syncope.core.provisioning.api.data.RemediationDataBinder; import org.apache.syncope.core.provisioning.api.data.ResourceDataBinder; @@ -83,9 +81,7 @@ public ReconciliationLogic reconciliationLogic( final RealmSearchDAO realmSearchDAO, final PlainSchemaDAO plainSchemaDAO, final DerSchemaDAO derSchemaDAO, - final VirSchemaDAO virSchemaDAO, final AnySearchDAO anySearchDAO, - final VirAttrHandler virAttrHandler, final ConnectorManager connectorManager, final InboundMatcher inboundMatcher, final OutboundMatcher outboundMatcher, @@ -98,9 +94,7 @@ public ReconciliationLogic reconciliationLogic( realmSearchDAO, plainSchemaDAO, derSchemaDAO, - virSchemaDAO, anySearchDAO, - virAttrHandler, mappingManager, inboundMatcher, outboundMatcher, @@ -127,8 +121,6 @@ public ResourceLogic resourceLogic( final AnyTypeDAO anyTypeDAO, final ExternalResourceDAO resourceDAO, final ConnInstanceDAO connInstanceDAO, - final VirSchemaDAO virSchemaDAO, - final VirAttrHandler virAttrHandler, final ConnInstanceDataBinder connInstanceDataBinder, final ConnectorManager connectorManager, final OutboundMatcher outboundMatcher, @@ -138,8 +130,6 @@ public ResourceLogic resourceLogic( resourceDAO, anyTypeDAO, connInstanceDAO, - virSchemaDAO, - virAttrHandler, resourceDataBinder, connInstanceDataBinder, outboundMatcher, diff --git a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java index 0961da6c044..40fd1f311ea 100644 --- a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java +++ b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java @@ -26,9 +26,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; -import java.util.stream.Stream; import org.apache.commons.lang3.BooleanUtils; -import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Triple; import org.apache.syncope.common.lib.Attr; @@ -63,7 +61,6 @@ import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.dao.RealmSearchDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.dao.search.SearchCond; import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyType; @@ -71,13 +68,11 @@ import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.Realm; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.persistence.api.utils.RealmUtils; import org.apache.syncope.core.provisioning.api.ConnectorManager; import org.apache.syncope.core.provisioning.api.MappingManager; -import org.apache.syncope.core.provisioning.api.VirAttrHandler; import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.pushpull.ConstantReconFilterBuilder; import org.apache.syncope.core.provisioning.api.pushpull.KeyValueReconFilterBuilder; @@ -127,12 +122,8 @@ public class ReconciliationLogic extends AbstractTransactionalLogic { protected final DerSchemaDAO derSchemaDAO; - protected final VirSchemaDAO virSchemaDAO; - protected final AnySearchDAO anySearchDAO; - protected final VirAttrHandler virAttrHandler; - protected final MappingManager mappingManager; protected final InboundMatcher inboundMatcher; @@ -148,9 +139,7 @@ public ReconciliationLogic( final RealmSearchDAO realmSearchDAO, final PlainSchemaDAO plainSchemaDAO, final DerSchemaDAO derSchemaDAO, - final VirSchemaDAO virSchemaDAO, final AnySearchDAO anySearchDAO, - final VirAttrHandler virAttrHandler, final MappingManager mappingManager, final InboundMatcher inboundMatcher, final OutboundMatcher outboundMatcher, @@ -162,9 +151,7 @@ public ReconciliationLogic( this.realmSearchDAO = realmSearchDAO; this.plainSchemaDAO = plainSchemaDAO; this.derSchemaDAO = derSchemaDAO; - this.virSchemaDAO = virSchemaDAO; this.anySearchDAO = anySearchDAO; - this.virAttrHandler = virAttrHandler; this.mappingManager = mappingManager; this.inboundMatcher = inboundMatcher; this.outboundMatcher = outboundMatcher; @@ -292,8 +279,6 @@ public ReconStatus status( if (connObjs.size() > 1) { LOG.warn("Expected single match, found {}", connObjs); - } else { - virAttrHandler.setValues(any, connObjs.getFirst()); } } @@ -307,11 +292,9 @@ protected SyncDeltaBuilder syncDeltaBuilder( final Filter filter, final Set moreAttrsToGet) { - Stream mapItems = Stream.concat( + OperationOptions options = MappingUtils.buildOperationOptions( provision.getMapping().getItems().stream(), - virSchemaDAO.findByResourceAndAnyType(resource.getKey(), anyType.getKey()).stream(). - map(VirSchema::asLinkingMappingItem)); - OperationOptions options = MappingUtils.buildOperationOptions(mapItems, moreAttrsToGet.toArray(String[]::new)); + moreAttrsToGet.toArray(String[]::new)); SyncDeltaBuilder syncDeltaBuilder = new SyncDeltaBuilder(). setToken(new SyncToken("")). @@ -378,12 +361,6 @@ public ReconStatus status( status.setOnResource(ConnObjectUtils.getConnObjectTO( outboundMatcher.getFIQL(syncDeltaBuilder.getObject(), triple.getMiddle(), triple.getRight()), syncDeltaBuilder.getObject().getAttributes())); - - if (status.getMatchType() == MatchType.ANY && StringUtils.isNotBlank(status.getAnyKey())) { - virAttrHandler.setValues( - getAny(triple.getRight(), triple.getLeft().getKind(), status.getAnyKey()), - syncDeltaBuilder.getObject()); - } } return status; @@ -663,13 +640,6 @@ public List push( LOG.warn("Ignoring invalid derived schema {}", item); } }); - spec.getDerAttrs().forEach(item -> { - if (virSchemaDAO.existsById(item)) { - columns.add(item); - } else { - LOG.warn("Ignoring invalid virtual schema {}", item); - } - }); PushTaskTO pushTask = new PushTaskTO(); pushTask.setMatchingRule(spec.getMatchingRule()); diff --git a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java index 04a730921e6..d4a88b91ff7 100644 --- a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java +++ b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Optional; import java.util.Set; -import java.util.stream.Stream; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; @@ -41,18 +40,15 @@ import org.apache.syncope.core.persistence.api.dao.DuplicateException; import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; import org.apache.syncope.core.persistence.api.dao.NotFoundException; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.ConnInstance; import org.apache.syncope.core.persistence.api.entity.ExternalResource; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.utils.RealmUtils; import org.apache.syncope.core.provisioning.api.Connector; import org.apache.syncope.core.provisioning.api.ConnectorManager; import org.apache.syncope.core.provisioning.api.MappingManager; -import org.apache.syncope.core.provisioning.api.VirAttrHandler; import org.apache.syncope.core.provisioning.api.data.ConnInstanceDataBinder; import org.apache.syncope.core.provisioning.api.data.ResourceDataBinder; import org.apache.syncope.core.provisioning.java.pushpull.OutboundMatcher; @@ -78,10 +74,6 @@ public class ResourceLogic extends AbstractTransactionalLogic { protected final ConnInstanceDAO connInstanceDAO; - protected final VirSchemaDAO virSchemaDAO; - - protected final VirAttrHandler virAttrHandler; - protected final ResourceDataBinder binder; protected final ConnInstanceDataBinder connInstanceDataBinder; @@ -98,8 +90,6 @@ public ResourceLogic( final ExternalResourceDAO resourceDAO, final AnyTypeDAO anyTypeDAO, final ConnInstanceDAO connInstanceDAO, - final VirSchemaDAO virSchemaDAO, - final VirAttrHandler virAttrHandler, final ResourceDataBinder binder, final ConnInstanceDataBinder connInstanceDataBinder, final OutboundMatcher outboundMatcher, @@ -110,8 +100,6 @@ public ResourceLogic( this.resourceDAO = resourceDAO; this.anyTypeDAO = anyTypeDAO; this.connInstanceDAO = connInstanceDAO; - this.virSchemaDAO = virSchemaDAO; - this.virAttrHandler = virAttrHandler; this.binder = binder; this.connInstanceDataBinder = connInstanceDataBinder; this.outboundMatcher = outboundMatcher; @@ -344,8 +332,6 @@ public ConnObject readConnObjectByAnyKey( if (connObjs.size() > 1) { LOG.warn("Expected single match, found {}", connObjs); - } else { - virAttrHandler.setValues(any, connObjs.getFirst()); } return ConnObjectUtils.getConnObjectTO( @@ -373,7 +359,6 @@ public ConnObject readConnObjectByConnObjectKeyValue( connObjectKeyValue, triple.getMiddle(), triple.getRight(), - Optional.empty(), Optional.empty()). map(connectorObject -> ConnObjectUtils.getConnObjectTO( outboundMatcher.getFIQL(connectorObject, triple.getMiddle(), triple.getRight()), @@ -416,11 +401,8 @@ public Pair> searchConnObjects( resource = triple.getMiddle(); objectClass = new ObjectClass(provision.getObjectClass()); - Stream mapItems = Stream.concat( - provision.getMapping().getItems().stream(), - virSchemaDAO.findByResourceAndAnyType(resource.getKey(), triple.getLeft().getKey()). - stream().map(VirSchema::asLinkingMappingItem)); - options = MappingUtils.buildOperationOptions(mapItems, moreAttrsToGet.toArray(String[]::new)); + options = MappingUtils.buildOperationOptions( + provision.getMapping().getItems().stream(), moreAttrsToGet.toArray(String[]::new)); } List connObjects = new ArrayList<>(); diff --git a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/ResourceLogicTest.java b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/ResourceLogicTest.java index 7ce347b7086..2b691415d74 100644 --- a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/ResourceLogicTest.java +++ b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/ResourceLogicTest.java @@ -80,18 +80,18 @@ public static void unsetAuthContext() { } private static ResourceTO buildResourceTO(final String resourceKey) { - ResourceTO resourceTO = new ResourceTO(); + ResourceTO resource = new ResourceTO(); - resourceTO.setKey(resourceKey); - resourceTO.setConnector("5ffbb4ac-a8c3-4b44-b699-11b398a1ba08"); + resource.setKey(resourceKey); + resource.setConnector("5ffbb4ac-a8c3-4b44-b699-11b398a1ba08"); - Provision provisionTO = new Provision(); - provisionTO.setAnyType(AnyTypeKind.USER.name()); - provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME); - resourceTO.getProvisions().add(provisionTO); + Provision provision = new Provision(); + provision.setAnyType(AnyTypeKind.USER.name()); + provision.setObjectClass(ObjectClass.ACCOUNT_NAME); + resource.getProvisions().add(provision); Mapping mapping = new Mapping(); - provisionTO.setMapping(mapping); + provision.setMapping(mapping); Item item = new Item(); item.setExtAttrName("userId"); @@ -112,7 +112,7 @@ private static ResourceTO buildResourceTO(final String resourceKey) { item.setPurpose(MappingPurpose.PROPAGATION); mapping.add(item); - return resourceTO; + return resource; } @Autowired @@ -129,12 +129,12 @@ public void updateChangePurpose() { ResourceTO ws1 = logic.read("ws-target-resource-1"); assertNotNull(ws1); - Mapping ws1NewUMapping = ws1.getProvision(AnyTypeKind.USER.name()).get().getMapping(); + Mapping ws1NewUMapping = ws1.getProvision(AnyTypeKind.USER.name()).orElseThrow().getMapping(); // change purpose from NONE to BOTH ws1NewUMapping.getItems().stream(). filter(itemTO -> "firstname".equals(itemTO.getIntAttrName())). forEach(itemTO -> itemTO.setPurpose(MappingPurpose.BOTH)); - ws1.getProvision(AnyTypeKind.USER.name()).get().setMapping(ws1NewUMapping); + ws1.getProvision(AnyTypeKind.USER.name()).orElseThrow().setMapping(ws1NewUMapping); ws1 = logic.update(ws1); assertNotNull(ws1); @@ -204,17 +204,19 @@ public void setLatestSyncToken() { return connector; }); - ResourceTO resourceTO = logic.create(buildResourceTO("lss")); - assertNotNull(resourceTO); - assertNull(resourceTO.getProvision(AnyTypeKind.USER.name()).get().getSyncToken()); + logic.create(buildResourceTO("lss")); + entityManager.flush(); + + ResourceTO resource = logic.read("lss"); + assertNull(resource.getProvision(AnyTypeKind.USER.name()).orElseThrow().getSyncToken()); ResourceLogic resourceLogic = new ResourceLogic( - resourceDAO, anyTypeDAO, null, null, null, null, null, null, null, connectorManager, null); + resourceDAO, anyTypeDAO, null, null, null, null, null, connectorManager, null); - resourceLogic.setLatestSyncToken(resourceTO.getKey(), AnyTypeKind.USER.name()); + resourceLogic.setLatestSyncToken(resource.getKey(), AnyTypeKind.USER.name()); entityManager.flush(); - resourceTO = logic.read(resourceTO.getKey()); - assertNotNull(resourceTO.getProvision(AnyTypeKind.USER.name()).get().getSyncToken()); + resource = logic.read(resource.getKey()); + assertNotNull(resource.getProvision(AnyTypeKind.USER.name()).orElseThrow().getSyncToken()); } } diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/IdRepoLogicContext.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/IdRepoLogicContext.java index 7e2893e1bf6..685174bbe60 100644 --- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/IdRepoLogicContext.java +++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/IdRepoLogicContext.java @@ -58,7 +58,6 @@ import org.apache.syncope.core.persistence.api.dao.TaskDAO; import org.apache.syncope.core.persistence.api.dao.TaskExecDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.EntityFactory; import org.apache.syncope.core.persistence.api.entity.policy.PolicyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.task.TaskUtilsFactory; @@ -418,12 +417,11 @@ public RoleLogic roleLogic( public SchemaLogic schemaLogic( final PlainSchemaDAO plainSchemaDAO, final DerSchemaDAO derSchemaDAO, - final VirSchemaDAO virSchemaDAO, final AnyTypeClassDAO anyTypeClassDAO, final ImplementationDAO implementationDAO, final SchemaDataBinder binder) { - return new SchemaLogic(plainSchemaDAO, derSchemaDAO, virSchemaDAO, anyTypeClassDAO, implementationDAO, binder); + return new SchemaLogic(plainSchemaDAO, derSchemaDAO, anyTypeClassDAO, implementationDAO, binder); } @ConditionalOnMissingBean diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java index 569cdcab67f..db052c13e5f 100644 --- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java +++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java @@ -32,7 +32,6 @@ import org.apache.syncope.common.lib.to.DerSchemaTO; import org.apache.syncope.common.lib.to.PlainSchemaTO; import org.apache.syncope.common.lib.to.SchemaTO; -import org.apache.syncope.common.lib.to.VirSchemaTO; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.AttrSchemaType; import org.apache.syncope.common.lib.types.ClientExceptionType; @@ -45,12 +44,10 @@ import org.apache.syncope.core.persistence.api.dao.ImplementationDAO; import org.apache.syncope.core.persistence.api.dao.NotFoundException; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.DerSchema; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.Schema; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.provisioning.api.data.SchemaDataBinder; import org.apache.syncope.core.spring.implementation.ImplementationManager; import org.springframework.security.access.prepost.PreAuthorize; @@ -62,8 +59,6 @@ public class SchemaLogic extends AbstractTransactionalLogic { protected final DerSchemaDAO derSchemaDAO; - protected final VirSchemaDAO virSchemaDAO; - protected final AnyTypeClassDAO anyTypeClassDAO; protected final ImplementationDAO implementationDAO; @@ -75,14 +70,12 @@ public class SchemaLogic extends AbstractTransactionalLogic { public SchemaLogic( final PlainSchemaDAO plainSchemaDAO, final DerSchemaDAO derSchemaDAO, - final VirSchemaDAO virSchemaDAO, final AnyTypeClassDAO anyTypeClassDAO, final ImplementationDAO implementationDAO, final SchemaDataBinder binder) { this.plainSchemaDAO = plainSchemaDAO; this.derSchemaDAO = derSchemaDAO; - this.virSchemaDAO = virSchemaDAO; this.anyTypeClassDAO = anyTypeClassDAO; this.implementationDAO = implementationDAO; this.binder = binder; @@ -93,10 +86,6 @@ protected Optional findById(final SchemaType schemaType, f Optional result = Optional.empty(); switch (schemaType) { - case VIRTUAL: - result = (Optional) virSchemaDAO.findById(name); - break; - case DERIVED: result = (Optional) derSchemaDAO.findById(name); break; @@ -126,10 +115,6 @@ public T create(final SchemaType schemaType, final T schema T created; switch (schemaType) { - case VIRTUAL: - created = (T) binder.getVirSchemaTO(binder.create((VirSchemaTO) schemaTO).getKey()); - break; - case DERIVED: created = (T) binder.getDerSchemaTO(binder.create((DerSchemaTO) schemaTO).getKey()); break; @@ -147,10 +132,6 @@ public void delete(final SchemaType schemaType, final String schemaKey) { orElseThrow(() -> new NotFoundException(schemaType + ": " + schemaKey)); switch (schemaType) { - case VIRTUAL: - virSchemaDAO.deleteById(schemaKey); - break; - case DERIVED: derSchemaDAO.deleteById(schemaKey); break; @@ -178,16 +159,6 @@ public List search( List result; switch (schemaType) { - case VIRTUAL: - List virSchemas = classes.isEmpty() - ? keyword == null - ? virSchemaDAO.findAll() - : virSchemaDAO.findByIdLike(keyword) - : virSchemaDAO.findByAnyTypeClasses(classes); - result = virSchemas.stream().map(schema -> (T) binder.getVirSchemaTO(schema.getKey())). - toList(); - break; - case DERIVED: List derSchemas = classes.isEmpty() ? keyword == null @@ -217,10 +188,6 @@ public List search( public T read(final SchemaType schemaType, final String schemaKey) { T read; switch (schemaType) { - case VIRTUAL: - read = (T) binder.getVirSchemaTO(schemaKey); - break; - case DERIVED: read = (T) binder.getDerSchemaTO(schemaKey); break; @@ -239,9 +206,6 @@ public void update(final SchemaType schemaType, final T sch orElseThrow(() -> new NotFoundException(schemaType + ": " + schemaTO.getKey())); switch (schemaType) { - case VIRTUAL -> - binder.update((VirSchemaTO) schemaTO, (VirSchema) schema); - case DERIVED -> binder.update((DerSchemaTO) schemaTO, (DerSchema) schema); @@ -297,12 +261,7 @@ protected SchemaTO resolveReference(final Method method, final Object... args) Optional schema = plainSchemaDAO.findById(key); if (schema.isEmpty()) { schema = derSchemaDAO.findById(key); - if (schema.isEmpty()) { - schema = virSchemaDAO.findById(key); - if (schema.isPresent()) { - result = binder.getVirSchemaTO(key); - } - } else { + if (schema.isPresent()) { result = binder.getDerSchemaTO(key); } } else { diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java index 44f38f43f6d..2c29346672c 100644 --- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java +++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java @@ -80,10 +80,6 @@ public Set read(final String key, final SchemaType schemaType) { result = any.getDerAttrs(); break; - case VIRTUAL: - result = any.getVirAttrs(); - break; - case PLAIN: default: result = any.getPlainAttrs(); @@ -101,10 +97,6 @@ public Attr read(final String key, final SchemaType schemaType, final String sch result = any.getDerAttr(schema); break; - case VIRTUAL: - result = any.getVirAttr(schema); - break; - case PLAIN: default: result = any.getPlainAttr(schema); @@ -165,10 +157,6 @@ protected void addUpdateOrReplaceAttr( UR updateReq = newUpdateReq(key); switch (schemaType) { - case VIRTUAL: - updateReq.getVirAttrs().add(attrTO); - break; - case PLAIN: updateReq.getPlainAttrs().add(new AttrPatch.Builder(attrTO).operation(operation).build()); break; diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java deleted file mode 100644 index 0923a8e5752..00000000000 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.api.dao; - -import java.util.List; -import org.apache.syncope.core.persistence.api.entity.ExternalResource; -import org.apache.syncope.core.persistence.api.entity.VirSchema; - -public interface VirSchemaDAO extends SchemaDAO { - - List findByResource(ExternalResource resource); - - List findByResourceAndAnyType(String resource, String anyType); -} diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyTypeClass.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyTypeClass.java index c7906df050e..4ae65a363e0 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyTypeClass.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyTypeClass.java @@ -29,8 +29,4 @@ public interface AnyTypeClass extends ProvidedKeyEntity { boolean add(DerSchema schema); List getDerSchemas(); - - boolean add(VirSchema schema); - - List getVirSchemas(); } diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/VirSchema.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/VirSchema.java deleted file mode 100644 index a16c9947785..00000000000 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/VirSchema.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.api.entity; - -import org.apache.syncope.common.lib.to.Item; -import org.apache.syncope.common.lib.types.MappingPurpose; - -public interface VirSchema extends Schema { - - void setReadonly(boolean readonly); - - ExternalResource getResource(); - - void setResource(ExternalResource resource); - - AnyType getAnyType(); - - void setAnyType(AnyType anyType); - - String getExtAttrName(); - - void setExtAttrName(String extAttrName); - - default Item asLinkingMappingItem() { - Item item = new Item(); - item.setExtAttrName(getExtAttrName()); - item.setIntAttrName(getKey()); - item.setMandatoryCondition(getMandatoryCondition()); - item.setPurpose(isReadonly() ? MappingPurpose.PULL : MappingPurpose.BOTH); - item.setConnObjectKey(false); - item.setPassword(false); - return item; - } -} diff --git a/core/persistence-jpa-upgrader/src/main/java/org/apache/syncope/core/persistence/jpa/upgrade/GenerateUpgradeSQL.java b/core/persistence-jpa-upgrader/src/main/java/org/apache/syncope/core/persistence/jpa/upgrade/GenerateUpgradeSQL.java index 7e6bc24e601..0f9f7a7a645 100644 --- a/core/persistence-jpa-upgrader/src/main/java/org/apache/syncope/core/persistence/jpa/upgrade/GenerateUpgradeSQL.java +++ b/core/persistence-jpa-upgrader/src/main/java/org/apache/syncope/core/persistence/jpa/upgrade/GenerateUpgradeSQL.java @@ -19,6 +19,7 @@ package org.apache.syncope.core.persistence.jpa.upgrade; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.json.JsonMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import java.io.IOException; @@ -98,20 +99,36 @@ private String connInstances() throws JsonProcessingException { return result.toString(); } - private String resources() { + private String resources() throws JsonProcessingException { StringBuilder result = new StringBuilder(); result.append("ALTER TABLE ExternalResource DROP COLUMN overridecapabilities;\n"); - List> accountPolicyResources = jdbcTemplate.queryForList( - "SELECT accountpolicy_id, resource_id FROM AccountPolicy_ExternalResource"); + List> resources = jdbcTemplate.queryForList( + "SELECT id, provisions FROM ExternalResource WHERE provisions IS NOT NULL"); + for (Map resource : resources) { + JsonNode provisions = MAPPER.readTree(resource.get("provisions").toString()); + for (JsonNode provision : provisions) { + if (provision.has("virSchemas")) { + ((ObjectNode) provision).remove("virSchemas"); + } + if (provision.has("mapping") && provision.get("mapping").has("linkingItems")) { + ((ObjectNode) provision.get("mapping")).remove("linkingItems"); + } + } - accountPolicyResources.forEach(acp -> { result.append(String.format( - "UPDATE ExternalResource SET accountPolicy_id='%s' WHERE id='%s';\n", - acp.get("accountpolicy_id").toString(), - acp.get("resource_id").toString())); - }); + "UPDATE ExternalResource SET provisions='%s' WHERE id='%s';\n", + MAPPER.writeValueAsString(provisions).replace("'", "'"), + resource.get("id").toString())); + } + + List> accountPolicyResources = jdbcTemplate.queryForList( + "SELECT accountpolicy_id, resource_id FROM AccountPolicy_ExternalResource"); + accountPolicyResources.forEach(acp -> result.append(String.format( + "UPDATE ExternalResource SET accountPolicy_id='%s' WHERE id='%s';\n", + acp.get("accountpolicy_id").toString(), + acp.get("resource_id").toString()))); result.append("DROP TABLE AccountPolicy_ExternalResource;\n"); diff --git a/core/persistence-jpa-upgrader/src/main/resources/schema.xml b/core/persistence-jpa-upgrader/src/main/resources/schema.xml index c9805412823..6c16bbee010 100644 --- a/core/persistence-jpa-upgrader/src/main/resources/schema.xml +++ b/core/persistence-jpa-upgrader/src/main/resources/schema.xml @@ -96,10 +96,10 @@ under the License. - - + + @@ -280,6 +280,7 @@ under the License. + @@ -547,6 +548,7 @@ under the License. + @@ -704,6 +706,7 @@ under the License. + @@ -712,10 +715,16 @@ under the License. + + + + + + @@ -727,6 +736,9 @@ under the License. + + + @@ -960,8 +972,10 @@ under the License. + + @@ -969,6 +983,7 @@ under the License. + @@ -976,6 +991,7 @@ under the License. + @@ -1077,6 +1093,7 @@ under the License. + @@ -1168,9 +1185,9 @@ under the License. - + @@ -1408,22 +1425,6 @@ under the License.
- - - - - - - - - - - - - - - -
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java index be7dce4965e..b44799e0de9 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java @@ -75,7 +75,6 @@ import org.apache.syncope.core.persistence.api.dao.TaskDAO; import org.apache.syncope.core.persistence.api.dao.TaskExecDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.dao.WAConfigDAO; import org.apache.syncope.core.persistence.api.dao.keymaster.ConfParamDAO; import org.apache.syncope.core.persistence.api.dao.keymaster.DomainDAO; @@ -183,9 +182,6 @@ import org.apache.syncope.core.persistence.jpa.dao.repo.UserRepo; import org.apache.syncope.core.persistence.jpa.dao.repo.UserRepoExt; import org.apache.syncope.core.persistence.jpa.dao.repo.UserRepoExtImpl; -import org.apache.syncope.core.persistence.jpa.dao.repo.VirSchemaRepo; -import org.apache.syncope.core.persistence.jpa.dao.repo.VirSchemaRepoExt; -import org.apache.syncope.core.persistence.jpa.dao.repo.VirSchemaRepoExtImpl; import org.apache.syncope.core.persistence.jpa.dao.repo.WAConfigRepo; import org.apache.syncope.core.persistence.jpa.entity.task.JPATaskUtilsFactory; import org.apache.syncope.core.persistence.jpa.spring.CommonEntityManagerFactoryConf; @@ -436,7 +432,6 @@ public AnyTypeClassRepoExt anyTypeClassRepoExt( final AnyTypeDAO anyTypeDAO, final PlainSchemaDAO plainSchemaDAO, final DerSchemaDAO derSchemaDAO, - final VirSchemaDAO virSchemaDAO, final @Lazy GroupDAO groupDAO, final ExternalResourceDAO resourceDAO, final EntityManager entityManager) { @@ -445,7 +440,6 @@ public AnyTypeClassRepoExt anyTypeClassRepoExt( anyTypeDAO, plainSchemaDAO, derSchemaDAO, - virSchemaDAO, groupDAO, resourceDAO, entityManager); @@ -863,7 +857,6 @@ public ExternalResourceRepoExt resourceRepoExt( final AnyObjectDAO anyObjectDAO, final UserDAO userDAO, final GroupDAO groupDAO, - final VirSchemaDAO virSchemaDAO, final RealmDAO realmDAO, final EntityManager entityManager) { @@ -872,7 +865,6 @@ public ExternalResourceRepoExt resourceRepoExt( anyObjectDAO, userDAO, groupDAO, - virSchemaDAO, realmDAO, entityManager); } @@ -1025,24 +1017,6 @@ public UserDAO userDAO( return jpaRepositoryFactory.getRepository(UserRepo.class, userRepoExt); } - @ConditionalOnMissingBean - @Bean - public VirSchemaRepoExt virSchemaRepoExt( - final @Lazy ExternalResourceDAO resourceDAO, - final EntityManager entityManager) { - - return new VirSchemaRepoExtImpl(resourceDAO, entityManager); - } - - @ConditionalOnMissingBean - @Bean - public VirSchemaDAO virSchemaDAO( - final JpaRepositoryFactory jpaRepositoryFactory, - final VirSchemaRepoExt virSchemaRepoExt) { - - return jpaRepositoryFactory.getRepository(VirSchemaRepo.class, virSchemaRepoExt); - } - @ConditionalOnMissingBean @Bean public WAConfigDAO waConfigDAO(final JpaRepositoryFactory jpaRepositoryFactory) { diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AbstractAnyRepoExt.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AbstractAnyRepoExt.java index b39c076079c..bd2e29ff3ae 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AbstractAnyRepoExt.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AbstractAnyRepoExt.java @@ -43,7 +43,6 @@ import org.apache.syncope.core.persistence.api.entity.DynRealm; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.Schema; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.user.User; @@ -163,8 +162,6 @@ public AllowedSchemas findAllowedSchemas(final A any, fina result.getForSelf().addAll((Collection) typeClass.getPlainSchemas()); } else if (reference.equals(DerSchema.class)) { result.getForSelf().addAll((Collection) typeClass.getDerSchemas()); - } else if (reference.equals(VirSchema.class)) { - result.getForSelf().addAll((Collection) typeClass.getVirSchemas()); } }); @@ -191,9 +188,6 @@ public AllowedSchemas findAllowedSchemas(final A any, fina } else if (reference.equals(DerSchema.class)) { result.getForMemberships().get(entry.getKey()). addAll((Collection) typeClass.getDerSchemas()); - } else if (reference.equals(VirSchema.class)) { - result.getForMemberships().get(entry.getKey()). - addAll((Collection) typeClass.getVirSchemas()); } })); diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AnyTypeClassRepoExtImpl.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AnyTypeClassRepoExtImpl.java index 60910fda2a1..08550b2b63a 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AnyTypeClassRepoExtImpl.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AnyTypeClassRepoExtImpl.java @@ -25,12 +25,10 @@ import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.DerSchema; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.group.TypeExtension; import org.apache.syncope.core.persistence.jpa.entity.JPAAnyTypeClass; @@ -42,8 +40,6 @@ public class AnyTypeClassRepoExtImpl implements AnyTypeClassRepoExt { protected final DerSchemaDAO derSchemaDAO; - protected final VirSchemaDAO virSchemaDAO; - protected final GroupDAO groupDAO; protected final ExternalResourceDAO resourceDAO; @@ -54,7 +50,6 @@ public AnyTypeClassRepoExtImpl( final AnyTypeDAO anyTypeDAO, final PlainSchemaDAO plainSchemaDAO, final DerSchemaDAO derSchemaDAO, - final VirSchemaDAO virSchemaDAO, final GroupDAO groupDAO, final ExternalResourceDAO resourceDAO, final EntityManager entityManager) { @@ -62,7 +57,6 @@ public AnyTypeClassRepoExtImpl( this.anyTypeDAO = anyTypeDAO; this.plainSchemaDAO = plainSchemaDAO; this.derSchemaDAO = derSchemaDAO; - this.virSchemaDAO = virSchemaDAO; this.groupDAO = groupDAO; this.resourceDAO = resourceDAO; this.entityManager = entityManager; @@ -78,9 +72,6 @@ public AnyTypeClass save(final AnyTypeClass anyTypeClass) { for (DerSchema schema : merge.getDerSchemas()) { schema.setAnyTypeClass(merge); } - for (VirSchema schema : merge.getVirSchemas()) { - schema.setAnyTypeClass(merge); - } return merge; } @@ -98,9 +89,6 @@ public void deleteById(final String key) { for (DerSchema schema : derSchemaDAO.findByAnyTypeClasses(List.of(anyTypeClass))) { schema.setAnyTypeClass(null); } - for (VirSchema schema : virSchemaDAO.findByAnyTypeClasses(List.of(anyTypeClass))) { - schema.setAnyTypeClass(null); - } for (AnyType type : anyTypeDAO.findByClassesContaining(anyTypeClass)) { type.getClasses().remove(anyTypeClass); diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/ExternalResourceRepoExtImpl.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/ExternalResourceRepoExtImpl.java index 184087be017..419f1311ec6 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/ExternalResourceRepoExtImpl.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/ExternalResourceRepoExtImpl.java @@ -31,7 +31,6 @@ import org.apache.syncope.core.persistence.api.dao.RealmDAO; import org.apache.syncope.core.persistence.api.dao.TaskDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy; import org.apache.syncope.core.persistence.api.entity.policy.InboundPolicy; @@ -55,8 +54,6 @@ public class ExternalResourceRepoExtImpl implements ExternalResourceRepoExt { protected final GroupDAO groupDAO; - protected final VirSchemaDAO virSchemaDAO; - protected final RealmDAO realmDAO; protected final EntityManager entityManager; @@ -66,7 +63,6 @@ public ExternalResourceRepoExtImpl( final AnyObjectDAO anyObjectDAO, final UserDAO userDAO, final GroupDAO groupDAO, - final VirSchemaDAO virSchemaDAO, final RealmDAO realmDAO, final EntityManager entityManager) { @@ -74,7 +70,6 @@ public ExternalResourceRepoExtImpl( this.anyObjectDAO = anyObjectDAO; this.userDAO = userDAO; this.groupDAO = groupDAO; - this.virSchemaDAO = virSchemaDAO; this.realmDAO = realmDAO; this.entityManager = entityManager; } @@ -189,8 +184,6 @@ public void deleteById(final String key) { groupDAO.findByResourcesContaining(resource). forEach(group -> group.getResources().remove(resource)); - virSchemaDAO.findByResource(resource).forEach(virSchemaDAO::delete); - if (resource.getConnector() != null && resource.getConnector().getResources() != null && !resource.getConnector().getResources().isEmpty()) { diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/VirSchemaRepo.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/VirSchemaRepo.java deleted file mode 100644 index 0e7705b6426..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/VirSchemaRepo.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.dao.repo; - -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; -import org.apache.syncope.core.persistence.jpa.entity.JPAVirSchema; -import org.springframework.data.repository.ListCrudRepository; - -public interface VirSchemaRepo - extends ListCrudRepository, VirSchemaRepoExt, VirSchemaDAO { - -} diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/VirSchemaRepoExt.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/VirSchemaRepoExt.java deleted file mode 100644 index 067adff77dd..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/VirSchemaRepoExt.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.dao.repo; - -import java.util.Collection; -import java.util.List; -import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; -import org.apache.syncope.core.persistence.api.entity.VirSchema; - -public interface VirSchemaRepoExt { - - List findByAnyTypeClasses(Collection anyTypeClasses); - - List findByResourceAndAnyType(String resource, String anyType); - - VirSchema save(VirSchema schema); - - void deleteById(String key); - - void delete(VirSchema schema); -} diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/VirSchemaRepoExtImpl.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/VirSchemaRepoExtImpl.java deleted file mode 100644 index a4e20890e26..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/VirSchemaRepoExtImpl.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.dao.repo; - -import jakarta.persistence.EntityManager; -import jakarta.persistence.Query; -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; -import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; -import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; -import org.apache.syncope.core.persistence.api.entity.VirSchema; -import org.apache.syncope.core.persistence.jpa.entity.JPAVirSchema; - -public class VirSchemaRepoExtImpl extends AbstractSchemaRepoExt implements VirSchemaRepoExt { - - protected final ExternalResourceDAO resourceDAO; - - public VirSchemaRepoExtImpl(final ExternalResourceDAO resourceDAO, final EntityManager entityManager) { - super(entityManager); - this.resourceDAO = resourceDAO; - } - - @Override - public List findByAnyTypeClasses(final Collection anyTypeClasses) { - return findByAnyTypeClasses(anyTypeClasses, JPAVirSchema.class.getSimpleName(), VirSchema.class); - } - - @Override - public List findByResourceAndAnyType(final String resource, final String anyType) { - Query query = entityManager.createNativeQuery( - "SELECT id FROM " + JPAVirSchema.TABLE + " e WHERE e.resource_id=? AND e.anyType_id=?"); - query.setParameter(1, resource); - query.setParameter(2, anyType); - - @SuppressWarnings("unchecked") - List results = query.getResultList(); - return results.stream(). - map(row -> entityManager.find(JPAVirSchema.class, row.toString())). - filter(Objects::nonNull). - collect(Collectors.toList()); - } - - @Override - public VirSchema save(final VirSchema schema) { - ((JPAVirSchema) schema).map2json(); - VirSchema merged = entityManager.merge(schema); - ((JPAVirSchema) merged).postSave(); - return merged; - - } - - @Override - public void deleteById(final String key) { - Optional.ofNullable(entityManager.find(JPAVirSchema.class, key)).ifPresent(this::delete); - } - - @Override - public void delete(final VirSchema schema) { - resourceDAO.deleteMapping(schema.getKey()); - - Optional.ofNullable(schema.getAnyTypeClass()). - ifPresent(anyTypeClass -> anyTypeClass.getVirSchemas().remove(schema)); - - entityManager.remove(schema); - } -} diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntityFactory.java index 2a293bd46ae..a91b28266a4 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntityFactory.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntityFactory.java @@ -47,7 +47,6 @@ import org.apache.syncope.core.persistence.api.entity.ReportExec; import org.apache.syncope.core.persistence.api.entity.Role; import org.apache.syncope.core.persistence.api.entity.SRARoute; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.am.AttrRepo; import org.apache.syncope.core.persistence.api.entity.am.AuthModule; import org.apache.syncope.core.persistence.api.entity.am.AuthProfile; @@ -215,8 +214,6 @@ public E newEntity(final Class reference) { result = (E) new JPAPlainSchema(); } else if (reference.equals(DerSchema.class)) { result = (E) new JPADerSchema(); - } else if (reference.equals(VirSchema.class)) { - result = (E) new JPAVirSchema(); } else if (reference.equals(Report.class)) { result = (E) new JPAReport(); } else if (reference.equals(ReportExec.class)) { diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java index 4e20bb2536f..b718da1049f 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java @@ -28,7 +28,6 @@ import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.DerSchema; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.VirSchema; @Entity @Table(name = JPAAnyTypeClass.TABLE) @@ -45,9 +44,6 @@ public class JPAAnyTypeClass extends AbstractProvidedKeyEntity implements AnyTyp @OneToMany(fetch = FetchType.EAGER, mappedBy = "anyTypeClass") private List derSchemas = new ArrayList<>(); - @OneToMany(fetch = FetchType.EAGER, mappedBy = "anyTypeClass") - private List virSchemas = new ArrayList<>(); - @Override public boolean add(final PlainSchema schema) { checkType(schema, JPAPlainSchema.class); @@ -69,15 +65,4 @@ public boolean add(final DerSchema schema) { public List getDerSchemas() { return derSchemas; } - - @Override - public boolean add(final VirSchema schema) { - checkType(schema, JPAVirSchema.class); - return this.virSchemas.add((JPAVirSchema) schema); - } - - @Override - public List getVirSchemas() { - return virSchemas; - } } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java deleted file mode 100644 index e1ef936c51a..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.entity; - -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToOne; -import jakarta.persistence.PrimaryKeyJoinColumn; -import jakarta.persistence.Table; -import jakarta.validation.constraints.NotNull; -import org.apache.syncope.common.lib.types.AttrSchemaType; -import org.apache.syncope.core.persistence.api.entity.AnyType; -import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; -import org.apache.syncope.core.persistence.api.entity.ExternalResource; -import org.apache.syncope.core.persistence.api.entity.VirSchema; - -@Entity -@Table(name = JPAVirSchema.TABLE) -@PrimaryKeyJoinColumn(name = "id", referencedColumnName = "id") -public class JPAVirSchema extends AbstractSchema implements VirSchema { - - private static final long serialVersionUID = 3274006935328590141L; - - public static final String TABLE = "VirSchema"; - - @OneToOne(fetch = FetchType.EAGER) - private JPAAnyTypeClass anyTypeClass; - - private Boolean readonly = false; - - @NotNull - @ManyToOne - private JPAExternalResource resource; - - @NotNull - @ManyToOne - private JPAAnyType anyType; - - @NotNull - private String extAttrName; - - @Override - public AnyTypeClass getAnyTypeClass() { - return anyTypeClass; - } - - @Override - public void setAnyTypeClass(final AnyTypeClass anyTypeClass) { - checkType(anyTypeClass, JPAAnyTypeClass.class); - this.anyTypeClass = (JPAAnyTypeClass) anyTypeClass; - } - - @Override - public AttrSchemaType getType() { - return AttrSchemaType.String; - } - - @Override - public String getMandatoryCondition() { - return Boolean.FALSE.toString().toLowerCase(); - } - - @Override - public boolean isMultivalue() { - return true; - } - - @Override - public boolean isUniqueConstraint() { - return false; - } - - @Override - public boolean isReadonly() { - return readonly; - } - - @Override - public void setReadonly(final boolean readonly) { - this.readonly = readonly; - } - - @Override - public ExternalResource getResource() { - return resource; - } - - @Override - public void setResource(final ExternalResource resource) { - checkType(resource, JPAExternalResource.class); - this.resource = (JPAExternalResource) resource; - } - - @Override - public AnyType getAnyType() { - return anyType; - } - - @Override - public void setAnyType(final AnyType anyType) { - checkType(anyType, JPAAnyType.class); - this.anyType = (JPAAnyType) anyType; - } - - @Override - public String getExtAttrName() { - return extAttrName; - } - - @Override - public void setExtAttrName(final String extAttrName) { - this.extAttrName = extAttrName; - } -} diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java index 47057eede69..73428bb16d0 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java @@ -24,7 +24,6 @@ import io.zonky.test.db.postgres.embedded.EmbeddedPostgres; import jakarta.persistence.EntityManager; import java.io.InputStream; -import java.time.Duration; import java.util.Map; import java.util.Properties; import java.util.function.Supplier; @@ -180,13 +179,13 @@ private static boolean classExists(final String name) { OracleContainer masterDomain = new OracleContainer("gvenzl/oracle-free:" + dockerOracleVersion). withDatabaseName("syncope").withPassword("syncope").withUsername("syncope"). - withReuse(true).withStartupTimeout(Duration.ofMinutes(4)); + withReuse(true); masterDomain.start(); JDBC_URL_SUPPLIER = masterDomain::getJdbcUrl; OracleContainer twoDomain = new OracleContainer("gvenzl/oracle-free:" + dockerOracleVersion). withDatabaseName("syncope").withPassword("syncope").withUsername("syncope"). - withReuse(true).withStartupTimeout(Duration.ofMinutes(4)); + withReuse(true); twoDomain.start(); JDBC2_URL_SUPPLIER = twoDomain::getJdbcUrl; } diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyTypeClassTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyTypeClassTest.java index 50824c00ba6..9c671ff804e 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyTypeClassTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyTypeClassTest.java @@ -46,7 +46,6 @@ public void find() { assertFalse(minimalGroup.getPlainSchemas().isEmpty()); assertFalse(minimalGroup.getDerSchemas().isEmpty()); - assertFalse(minimalGroup.getVirSchemas().isEmpty()); } @Test @@ -65,7 +64,6 @@ public void save() { assertNotNull(newClass); assertFalse(newClass.getPlainSchemas().isEmpty()); assertTrue(newClass.getDerSchemas().isEmpty()); - assertTrue(newClass.getVirSchemas().isEmpty()); } @Test diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RemediationTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RemediationTest.java index d59971c79a6..8a97f583046 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RemediationTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RemediationTest.java @@ -70,7 +70,7 @@ public void createMissingPayload() { remediation.setInstant(OffsetDateTime.now()); remediation.setRemoteName("remote"); remediation.setPullTask((PullTask) taskDAO.findById( - TaskType.PULL, "38abbf9e-a1a3-40a1-a15f-7d0ac02f47f1").orElseThrow()); + TaskType.PULL, "81d88f73-d474-4450-9031-605daa4e313f").orElseThrow()); // missing payload try { @@ -92,7 +92,7 @@ public void createWrongPayload() { remediation.setInstant(OffsetDateTime.now()); remediation.setRemoteName("remote"); remediation.setPullTask((PullTask) taskDAO.findById( - TaskType.PULL, "38abbf9e-a1a3-40a1-a15f-7d0ac02f47f1").orElseThrow()); + TaskType.PULL, "81d88f73-d474-4450-9031-605daa4e313f").orElseThrow()); remediation.setPayload(UUID.randomUUID().toString()); // wrong payload for operation @@ -115,7 +115,7 @@ public void create() { remediation.setInstant(OffsetDateTime.now()); remediation.setRemoteName("remote"); remediation.setPullTask((PullTask) taskDAO.findById( - TaskType.PULL, "38abbf9e-a1a3-40a1-a15f-7d0ac02f47f1").orElseThrow()); + TaskType.PULL, "81d88f73-d474-4450-9031-605daa4e313f").orElseThrow()); remediation.setPayload(UUID.randomUUID().toString()); remediation.setOperation(ResourceOperation.DELETE); diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java index ad7a22ce315..948fd6b9114 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java @@ -238,38 +238,6 @@ public void saveInvalidProvision() { }); } - @Test - public void saveVirtualMapping() { - ExternalResource resource = entityFactory.newEntity(ExternalResource.class); - resource.setKey("ws-target-resource-virtual-mapping"); - resource.setPropagationPriority(2); - - Provision provision = new Provision(); - provision.setAnyType(AnyTypeKind.USER.name()); - provision.setObjectClass(ObjectClass.ACCOUNT_NAME); - resource.getProvisions().add(provision); - - Mapping mapping = new Mapping(); - provision.setMapping(mapping); - - Item connObjectKey = new Item(); - connObjectKey.setExtAttrName("username"); - connObjectKey.setIntAttrName("fullname"); - connObjectKey.setPurpose(MappingPurpose.BOTH); - mapping.setConnObjectKeyItem(connObjectKey); - - Item virtualMapItem = new Item(); - virtualMapItem.setIntAttrName("virtualReadOnly"); - virtualMapItem.setExtAttrName("TEST"); - virtualMapItem.setPurpose(MappingPurpose.PROPAGATION); - mapping.add(virtualMapItem); - - ConnInstance connector = resourceDAO.findById("ws-target-resource-1").orElseThrow().getConnector(); - resource.setConnector(connector); - - resourceDAO.save(resource); - } - @Test public void saveWithGroupMappingType() { ExternalResource resource = entityFactory.newEntity(ExternalResource.class); diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java index 5b1aa00c856..2da9bbbf969 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java @@ -126,7 +126,7 @@ public void findAll() { assertEquals(6, taskDAO.findAll(TaskType.PROPAGATION).size()); assertEquals(1, taskDAO.findAll(TaskType.NOTIFICATION).size()); assertEquals(3, taskDAO.findAll(TaskType.SCHEDULED).size()); - assertEquals(10, taskDAO.findAll(TaskType.PULL).size()); + assertEquals(9, taskDAO.findAll(TaskType.PULL).size()); assertEquals(11, taskDAO.findAll(TaskType.PUSH).size()); List authorities = IdRepoEntitlement.values().stream(). diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirSchemaTest.java deleted file mode 100644 index 7a07d93c9a2..00000000000 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirSchemaTest.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.inner; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -import java.util.List; -import org.apache.syncope.common.lib.types.EntityViolationType; -import org.apache.syncope.core.persistence.api.attrvalue.InvalidEntityException; -import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO; -import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; -import org.apache.syncope.core.persistence.api.entity.VirSchema; -import org.apache.syncope.core.persistence.jpa.AbstractTest; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; - -@Transactional -public class VirSchemaTest extends AbstractTest { - - @Autowired - private VirSchemaDAO virSchemaDAO; - - @Autowired - private ExternalResourceDAO resourceDAO; - - @Autowired - private AnyTypeDAO anyTypeDAO; - - @Test - public void findAll() { - List list = virSchemaDAO.findAll(); - assertEquals(3, list.size()); - } - - @Test - public void findByIdLike() { - List schemas = virSchemaDAO.findByIdLike("rvirtuald%"); - assertEquals(1, schemas.size()); - } - - @Test - public void findByName() { - VirSchema attributeSchema = virSchemaDAO.findById("virtualdata").orElseThrow(); - assertNotNull(attributeSchema); - } - - @Test - public void save() { - VirSchema virSchema = entityFactory.newEntity(VirSchema.class); - virSchema.setKey("virtual"); - virSchema.setResource(resourceDAO.findById("resource-csv").orElseThrow()); - virSchema.setAnyType(anyTypeDAO.getUser()); - virSchema.setReadonly(true); - virSchema.setExtAttrName("EXT_ATTR"); - - virSchemaDAO.save(virSchema); - - VirSchema actual = virSchemaDAO.findById("virtual").orElseThrow(); - assertNotNull(actual); - assertTrue(actual.isReadonly()); - assertEquals("EXT_ATTR", actual.getExtAttrName()); - } - - @Test - public void delete() { - VirSchema virtualdata = virSchemaDAO.findById("virtualdata").orElseThrow(); - - virSchemaDAO.deleteById(virtualdata.getKey()); - - assertTrue(virSchemaDAO.findById("virtualdata").isEmpty()); - - // ------------- // - VirSchema rvirtualdata = virSchemaDAO.findById("rvirtualdata").orElseThrow(); - - virSchemaDAO.deleteById(rvirtualdata.getKey()); - - assertTrue(virSchemaDAO.findById("rvirtualdata").isEmpty()); - } - - @Test - public void issueSYNCOPE418() { - VirSchema schema = entityFactory.newEntity(VirSchema.class); - schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit"); - - try { - virSchemaDAO.save(schema); - fail("This should not happen"); - } catch (InvalidEntityException e) { - assertTrue(e.hasViolation(EntityViolationType.InvalidKey)); - } - } -} diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/VirSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/VirSchemaTest.java deleted file mode 100644 index 3a977aa3221..00000000000 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/VirSchemaTest.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.outer; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.apache.syncope.common.lib.to.Item; -import org.apache.syncope.common.lib.types.AnyTypeKind; -import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO; -import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; -import org.apache.syncope.core.persistence.api.entity.ExternalResource; -import org.apache.syncope.core.persistence.api.entity.VirSchema; -import org.apache.syncope.core.persistence.jpa.AbstractTest; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; - -@Transactional -public class VirSchemaTest extends AbstractTest { - - @Autowired - private VirSchemaDAO virSchemaDAO; - - @Autowired - private ExternalResourceDAO resourceDAO; - - @Autowired - private AnyTypeDAO anyTypeDAO; - - @Test - public void deal() { - ExternalResource resource = resourceDAO.findById("ws-target-resource-1").orElseThrow(); - assertTrue(virSchemaDAO.findByResource(resource).isEmpty()); - assertTrue(virSchemaDAO.findByResourceAndAnyType(resource.getKey(), AnyTypeKind.USER.name()).isEmpty()); - - VirSchema virSchema = entityFactory.newEntity(VirSchema.class); - virSchema.setKey("vSchema"); - virSchema.setReadonly(true); - virSchema.setExtAttrName("EXT_ATTR"); - virSchema.setResource(resource); - virSchema.setAnyType(anyTypeDAO.getUser()); - - virSchemaDAO.save(virSchema); - entityManager.flush(); - - virSchema = virSchemaDAO.findById("vSchema").orElseThrow(); - assertTrue(virSchema.isReadonly()); - assertEquals("EXT_ATTR", virSchema.getExtAttrName()); - - assertFalse(virSchemaDAO.findByResource(resource).isEmpty()); - assertTrue(virSchemaDAO.findByResource(resource).contains(virSchema)); - - assertFalse(virSchemaDAO.findByResourceAndAnyType( - resource.getKey(), AnyTypeKind.USER.name()).isEmpty()); - assertTrue(virSchemaDAO.findByResourceAndAnyType( - resource.getKey(), AnyTypeKind.USER.name()).contains(virSchema)); - - Item item = virSchema.asLinkingMappingItem(); - assertNotNull(item); - assertEquals(virSchema.getKey(), item.getIntAttrName()); - } -} diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml index 9dcd769b172..9009ca3c278 100644 --- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml +++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml @@ -567,41 +567,41 @@ under the License. + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"email","extAttrName":"email","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"surname","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"password":true,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"fullname","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"ctype","extAttrName":"type","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"firstname","extAttrName":"name","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"NONE","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"username","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"password":true,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"ctype","extAttrName":"type","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"surname","connObjectKey":false,"password":false,"mandatoryCondition":"type == 'F'","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"cn","extAttrName":"fullname","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"email","extAttrName":"email","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"surname","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"email","extAttrName":"email","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"username","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"email","extAttrName":"email","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"userId","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"fullname","extAttrName":"test3","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"userId","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"password":true,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"username","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"password":true,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"username","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> @@ -609,16 +609,16 @@ under the License. enforceMandatoryCondition="0" inboundPolicy_id="880f8553-069b-4aed-9930-2cd53873f544" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL" - provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":["csv","generic membership","minimal group"],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"id","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"fullname","extAttrName":"id","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"password":true,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"firstname","extAttrName":"name","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"surname","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"userId","extAttrName":"email","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"PULL","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"email","extAttrName":"email","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"PULL","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"csvuserid","extAttrName":"__NAME__","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"groups[root].rderToBePropagated","extAttrName":"theirgroup","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"linkingItems":[],"connObjectKeyItem":{"intAttrName":"csvuserid","extAttrName":"__NAME__","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}},"virSchemas":[]}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":["csv","generic membership","minimal group"],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"id","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"fullname","extAttrName":"id","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"password":true,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"firstname","extAttrName":"name","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"surname","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"userId","extAttrName":"email","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"PULL","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"email","extAttrName":"email","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"PULL","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"csvuserid","extAttrName":"__NAME__","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"groups[root].rderToBePropagated","extAttrName":"theirgroup","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"csvuserid","extAttrName":"__NAME__","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":"{\"value\":null}","ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"userId","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"fullname","extAttrName":"__PASSWORD__","connObjectKey":false,"password":true,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"userId","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":["generic membership","minimal group"],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":"'uid=' + username + ',ou=people,${testds.rootDn}'","items":[{"intAttrName":"username","extAttrName":"cn","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"password":true,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"sn","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"fullname","extAttrName":"cn","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"email","extAttrName":"mail","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"title","extAttrName":"title","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"postalAddress","extAttrName":"postalAddress","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"userId","extAttrName":"mail","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"obscure","extAttrName":"registeredAddress","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"photo","extAttrName":"jpegPhoto","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"username","extAttrName":"cn","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}},{"anyType":"GROUP","objectClass":"__GROUP__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":"'cn=' + name + ',ou=groups,${testds.rootDn}'","items":[{"intAttrName":"name","extAttrName":"cn","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"userOwner","extAttrName":"owner","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"title","extAttrName":"description","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"name","extAttrName":"cn","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> @@ -634,44 +634,39 @@ under the License. enforceMandatoryCondition="1" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL" passwordPolicy_id="986d1236-3ac5-4a19-810c-5ab21d79cba1" - provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"linkingItems":[],"connObjectKeyItem":{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}},"virSchemas":[]}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"email","extAttrName":"EMAIL","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"fullname","extAttrName":"SURNAME","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"PULL","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"firstname","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"SURNAME","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"username","extAttrName":"USERNAME","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"userId","extAttrName":"EMAIL","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"PULL","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"mustChangePassword","extAttrName":"MUSTCHANGEPASSWORD","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"PULL","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"firstname","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> - - + provisions='[{"anyType":"PRINTER","objectClass":"__PRINTER__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"key","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"name","extAttrName":"PRINTERNAME","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"location","extAttrName":"LOCATION","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"key","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + propagationPriority="0" provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"firstname","extAttrName":"firstName","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"key","extAttrName":"key","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"password":true,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"username","extAttrName":"username","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"email","extAttrName":"email","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"surname","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"key","extAttrName":"key","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> @@ -689,18 +684,6 @@ under the License. - - - - - - - - - + template='{"_class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":null,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":["csv"],"derAttrs":[{"schema":"cn","values":[""]}],"resources":["resource-testdb"],"relationships":[],"memberships":[{"groupKey":"f779c0d4-633b-4be5-8f57-32eb478a3ca5","groupName":null}],"dynMemberships":[],"roles":[],"dynRoles":[],"plainAttrs":[{"schema":"ctype","values":["email == 'test8@syncope.apache.org'? 'TYPE_8': 'TYPE_OTHER'"]}]}'/> + template='{"_class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":null,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"resources":[],"plainAttrs":[]}'/> + template='{"_class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":null,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"resources":[],"relationships":[],"memberships":[],"dynMemberships":[],"roles":[],"dynRoles":[],"plainAttrs":[{"schema":"ctype","values":["'type a'"]},{"schema":"userId","values":["'reconciled@syncope.apache.org'"]},{"schema":"fullname","values":["'reconciled fullname'"]},{"schema":"surname","values":["'surname'"]}]}'/> + template='{"_class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":null,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"resources":[],"plainAttrs":[]}'/> @@ -766,15 +749,12 @@ under the License. destinationRealm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28" pullMode="FULL_RECONCILIATION" performCreate="1" performDelete="1" performUpdate="1" syncStatus="0" unmatchingRule="PROVISION" matchingRule="UPDATE" active="1" jobDelegate_id="PullJobDelegate"/> + template='{"_class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":null,"type":"USER","realm":"'/' + title","status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":["minimal group"],"derAttrs":[],"resources":["resource-ldap"],"roles":[],"dynRoles":[],"relationships":[],"memberships":[],"dynMemberships":[],"plainAttrs":[]}'/> + template='{"_class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":null,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"resources":[],"plainAttrs":[{"schema":"show","values":["true"]}]}'/> - + template='{"_class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":null,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"resources":["resource-testdb"],"roles":[],"dynRoles":[],"relationships":[],"memberships":[],"dynMemberships":[],"plainAttrs":[{"schema":"firstname","values":[""]},{"schema":"userId","values":["'test'"]},{"schema":"fullname","values":["'test'"]},{"schema":"surname","values":["'test'"]}]}'/> + template='{"_class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":null,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"resources":[],"plainAttrs":[]}'/> diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/PersistenceContext.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/PersistenceContext.java index 63a1718d5bd..85461094525 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/PersistenceContext.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/PersistenceContext.java @@ -77,7 +77,6 @@ import org.apache.syncope.core.persistence.api.dao.TaskDAO; import org.apache.syncope.core.persistence.api.dao.TaskExecDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.dao.WAConfigDAO; import org.apache.syncope.core.persistence.api.dao.keymaster.ConfParamDAO; import org.apache.syncope.core.persistence.api.dao.keymaster.DomainDAO; @@ -192,9 +191,6 @@ import org.apache.syncope.core.persistence.neo4j.dao.repo.UserRepo; import org.apache.syncope.core.persistence.neo4j.dao.repo.UserRepoExt; import org.apache.syncope.core.persistence.neo4j.dao.repo.UserRepoExtImpl; -import org.apache.syncope.core.persistence.neo4j.dao.repo.VirSchemaRepo; -import org.apache.syncope.core.persistence.neo4j.dao.repo.VirSchemaRepoExt; -import org.apache.syncope.core.persistence.neo4j.dao.repo.VirSchemaRepoExtImpl; import org.apache.syncope.core.persistence.neo4j.dao.repo.WAConfigRepo; import org.apache.syncope.core.persistence.neo4j.entity.EntityCacheKey; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jAnyType; @@ -206,7 +202,6 @@ import org.apache.syncope.core.persistence.neo4j.entity.Neo4jPlainSchema; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jRealm; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jRole; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jVirSchema; import org.apache.syncope.core.persistence.neo4j.entity.anyobject.Neo4jAnyObject; import org.apache.syncope.core.persistence.neo4j.entity.group.Neo4jGroup; import org.apache.syncope.core.persistence.neo4j.entity.task.Neo4jTaskUtilsFactory; @@ -315,8 +310,7 @@ public CacheCleaningTransactionExecutionListener cacheCleaningTransactionExecuti final Cache plainSchemaCache, final Cache realmCache, final Cache roleCache, - final Cache userCache, - final Cache virSchemaCache) { + final Cache userCache) { return new CacheCleaningTransactionExecutionListener( anyTypeCache, @@ -329,8 +323,7 @@ public CacheCleaningTransactionExecutionListener cacheCleaningTransactionExecuti plainSchemaCache, realmCache, roleCache, - userCache, - virSchemaCache); + userCache); } @Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_TRANSACTION_MANAGER_BEAN_NAME) @@ -498,7 +491,6 @@ public AnyObjectRepoExt anyObjectRepoExt( final @Lazy AnyTypeClassDAO anyTypeClassDAO, final @Lazy PlainSchemaDAO plainSchemaDAO, final @Lazy DerSchemaDAO derSchemaDAO, - final @Lazy VirSchemaDAO virSchemaDAO, final @Lazy DynRealmDAO dynRealmDAO, final @Lazy UserDAO userDAO, final @Lazy GroupDAO groupDAO, @@ -514,7 +506,6 @@ public AnyObjectRepoExt anyObjectRepoExt( anyTypeClassDAO, plainSchemaDAO, derSchemaDAO, - virSchemaDAO, dynRealmDAO, userDAO, groupDAO, @@ -569,7 +560,6 @@ public AnyTypeClassRepoExt anyTypeClassRepoExt( final AnyTypeDAO anyTypeDAO, final PlainSchemaDAO plainSchemaDAO, final DerSchemaDAO derSchemaDAO, - final VirSchemaDAO virSchemaDAO, final @Lazy GroupDAO groupDAO, final ExternalResourceDAO resourceDAO, final Neo4jTemplate neo4jTemplate, @@ -583,7 +573,6 @@ public AnyTypeClassRepoExt anyTypeClassRepoExt( anyTypeDAO, plainSchemaDAO, derSchemaDAO, - virSchemaDAO, groupDAO, resourceDAO, neo4jTemplate, @@ -865,8 +854,7 @@ public EntityCacheDAO entityCacheDAO( final Cache plainSchemaCache, final Cache realmCache, final Cache roleCache, - final Cache userCache, - final Cache virSchemaCache) { + final Cache userCache) { return new Neo4jEntityCacheDAO( anyTypeCache, @@ -879,8 +867,7 @@ public EntityCacheDAO entityCacheDAO( plainSchemaCache, realmCache, roleCache, - userCache, - virSchemaCache); + userCache); } @ConditionalOnMissingBean @@ -921,7 +908,6 @@ public GroupRepoExt groupRepoExt( final @Lazy AnyTypeClassDAO anyTypeClassDAO, final @Lazy PlainSchemaDAO plainSchemaDAO, final @Lazy DerSchemaDAO derSchemaDAO, - final @Lazy VirSchemaDAO virSchemaDAO, final @Lazy DynRealmDAO dynRealmDAO, final AnyMatchDAO anyMatchDAO, final @Lazy UserDAO userDAO, @@ -941,7 +927,6 @@ public GroupRepoExt groupRepoExt( anyTypeClassDAO, plainSchemaDAO, derSchemaDAO, - virSchemaDAO, dynRealmDAO, anyMatchDAO, userDAO, @@ -1253,7 +1238,6 @@ public ExternalResourceRepoExt resourceRepoExt( final AnyObjectDAO anyObjectDAO, final UserDAO userDAO, final GroupDAO groupDAO, - final VirSchemaDAO virSchemaDAO, final RealmDAO realmDAO, final Neo4jTemplate neo4jTemplate, final Neo4jClient neo4jClient, @@ -1265,7 +1249,6 @@ public ExternalResourceRepoExt resourceRepoExt( anyObjectDAO, userDAO, groupDAO, - virSchemaDAO, realmDAO, neo4jTemplate, neo4jClient, @@ -1435,7 +1418,6 @@ public UserRepoExt userRepoExt( final @Lazy AnyTypeClassDAO anyTypeClassDAO, final @Lazy PlainSchemaDAO plainSchemaDAO, final @Lazy DerSchemaDAO derSchemaDAO, - final @Lazy VirSchemaDAO virSchemaDAO, final @Lazy DynRealmDAO dynRealmDAO, final RoleDAO roleDAO, final AccessTokenDAO accessTokenDAO, @@ -1454,7 +1436,6 @@ public UserRepoExt userRepoExt( anyTypeClassDAO, plainSchemaDAO, derSchemaDAO, - virSchemaDAO, dynRealmDAO, roleDAO, accessTokenDAO, @@ -1478,43 +1459,6 @@ public UserDAO userDAO( return neo4jRepositoryFactory.getRepository(UserRepo.class, userRepoExt); } - @ConditionalOnMissingBean(name = VirSchemaRepoExt.CACHE) - @Bean(name = VirSchemaRepoExt.CACHE) - public Cache virSchemaCache(final CacheManager cacheManager) { - return cacheManager.createCache(VirSchemaRepoExt.CACHE, - new MutableConfiguration(). - setTypes(EntityCacheKey.class, Neo4jVirSchema.class). - setStoreByValue(false). - setReadThrough(true). - setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(Duration.ETERNAL))); - } - - @ConditionalOnMissingBean - @Bean - public VirSchemaRepoExt virSchemaRepoExt( - final @Lazy ExternalResourceDAO resourceDAO, - final Neo4jTemplate neo4jTemplate, - final Neo4jClient neo4jClient, - final NodeValidator nodeValidator, - final Cache virSchemaCache) { - - return new VirSchemaRepoExtImpl( - resourceDAO, - neo4jTemplate, - neo4jClient, - nodeValidator, - virSchemaCache); - } - - @ConditionalOnMissingBean - @Bean - public VirSchemaDAO virSchemaDAO( - final SyncopeNeo4jRepositoryFactory neo4jRepositoryFactory, - final VirSchemaRepoExt virSchemaRepoExt) { - - return neo4jRepositoryFactory.getRepository(VirSchemaRepo.class, virSchemaRepoExt); - } - @ConditionalOnMissingBean @Bean public WAConfigDAO waConfigDAO(final SyncopeNeo4jRepositoryFactory neo4jRepositoryFactory) { diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/content/ContentLoaderHandler.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/content/ContentLoaderHandler.java index b6330bcd1f9..491911aac94 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/content/ContentLoaderHandler.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/content/ContentLoaderHandler.java @@ -33,7 +33,6 @@ import org.apache.syncope.core.persistence.neo4j.entity.Neo4jImplementationRelationship; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jPlainSchema; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jSchema; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jVirSchema; import org.apache.syncope.core.persistence.neo4j.entity.policy.Neo4jAccessPolicy; import org.apache.syncope.core.persistence.neo4j.entity.policy.Neo4jAccountPolicy; import org.apache.syncope.core.persistence.neo4j.entity.policy.Neo4jAttrReleasePolicy; @@ -85,9 +84,6 @@ protected static String nodelabels(final String primaryLabel) { case Neo4jDerSchema.NODE -> { return Neo4jDerSchema.NODE + ":" + Neo4jSchema.NODE; } - case Neo4jVirSchema.NODE -> { - return Neo4jVirSchema.NODE + ":" + Neo4jSchema.NODE; - } case Neo4jAccessPolicy.NODE -> { return Neo4jAccessPolicy.NODE + ":" + Neo4jPolicy.NODE; @@ -181,8 +177,8 @@ protected Optional parseNode(final NodeDescription nodeDesc, final Attr props.put("id", originalValue); } else { String name = nodeDesc.getGraphProperties().stream(). - map(GraphPropertyDescription::getPropertyName). - filter(propertyName -> propertyName.equalsIgnoreCase(originalName)). + map(GraphPropertyDescription::getPropertyName). + filter(propertyName -> propertyName.equalsIgnoreCase(originalName)). findFirst().orElseGet(() -> originalName.startsWith("plainAttrs.") ? originalName : null); if (name == null) { LOG.error("Property {} not matching for {}", originalName, nodeDesc.getPrimaryLabel()); diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/Neo4jEntityCacheDAO.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/Neo4jEntityCacheDAO.java index 3f58e6d0912..44a76bfdc90 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/Neo4jEntityCacheDAO.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/Neo4jEntityCacheDAO.java @@ -34,7 +34,6 @@ import org.apache.syncope.core.persistence.neo4j.entity.Neo4jPlainSchema; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jRealm; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jRole; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jVirSchema; import org.apache.syncope.core.persistence.neo4j.entity.anyobject.Neo4jAnyObject; import org.apache.syncope.core.persistence.neo4j.entity.group.Neo4jGroup; import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jUser; @@ -54,8 +53,7 @@ public Neo4jEntityCacheDAO( final Cache plainSchemaCache, final Cache realmCache, final Cache roleCache, - final Cache userCache, - final Cache virSchemaCache) { + final Cache userCache) { caches = new HashMap<>(); caches.put(Neo4jAnyTypeClass.class, anyTypeCache); @@ -69,7 +67,6 @@ public Neo4jEntityCacheDAO( caches.put(Neo4jRealm.class, realmCache); caches.put(Neo4jRole.class, roleCache); caches.put(Neo4jUser.class, userCache); - caches.put(Neo4jVirSchema.class, virSchemaCache); } @Override diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AbstractAnyRepoExt.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AbstractAnyRepoExt.java index 2f3c5196292..fe61c79e94e 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AbstractAnyRepoExt.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AbstractAnyRepoExt.java @@ -37,7 +37,6 @@ import org.apache.syncope.core.persistence.api.dao.DynRealmDAO; import org.apache.syncope.core.persistence.api.dao.NotFoundException; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; @@ -47,7 +46,6 @@ import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.Schema; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.user.User; @@ -97,8 +95,6 @@ protected static List split(final String attrValue, final List l protected final DerSchemaDAO derSchemaDAO; - protected final VirSchemaDAO virSchemaDAO; - protected final DynRealmDAO dynRealmDAO; protected final AnyFinder anyFinder; @@ -110,7 +106,6 @@ protected AbstractAnyRepoExt( final AnyTypeClassDAO anyTypeClassDAO, final PlainSchemaDAO plainSchemaDAO, final DerSchemaDAO derSchemaDAO, - final VirSchemaDAO virSchemaDAO, final DynRealmDAO dynRealmDAO, final AnyFinder anyFinder, final AnyUtils anyUtils, @@ -122,7 +117,6 @@ protected AbstractAnyRepoExt( this.anyTypeClassDAO = anyTypeClassDAO; this.plainSchemaDAO = plainSchemaDAO; this.derSchemaDAO = derSchemaDAO; - this.virSchemaDAO = virSchemaDAO; this.dynRealmDAO = dynRealmDAO; this.anyFinder = anyFinder; this.anyUtils = anyUtils; @@ -204,11 +198,6 @@ public AllowedSchemas findAllowedSchemas(final A any, fina map(schema -> derSchemaDAO.findById(schema.getKey())). flatMap(Optional::stream). forEach(schema -> result.getForSelf().add((S) schema)); - } else if (reference.equals(VirSchema.class)) { - atc.getVirSchemas().stream(). - map(schema -> virSchemaDAO.findById(schema.getKey())). - flatMap(Optional::stream). - forEach(schema -> result.getForSelf().add((S) schema)); } }); @@ -258,11 +247,6 @@ public AllowedSchemas findAllowedSchemas(final A any, fina map(schema -> derSchemaDAO.findById(schema.getKey())). flatMap(Optional::stream). forEach(schema -> result.getForMemberships().get(entry.getKey()).add((S) schema)); - } else if (reference.equals(VirSchema.class)) { - atc.getVirSchemas().stream(). - map(schema -> virSchemaDAO.findById(schema.getKey())). - flatMap(Optional::stream). - forEach(schema -> result.getForMemberships().get(entry.getKey()).add((S) schema)); } })); diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AbstractSchemaRepoExt.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AbstractSchemaRepoExt.java index 425ff3ca684..210272b8ea4 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AbstractSchemaRepoExt.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AbstractSchemaRepoExt.java @@ -32,7 +32,6 @@ import org.apache.syncope.core.persistence.neo4j.entity.Neo4jDerSchema; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jPlainSchema; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jSchema; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jVirSchema; import org.apache.syncope.core.persistence.neo4j.spring.NodeValidator; import org.springframework.data.neo4j.core.Neo4jClient; import org.springframework.data.neo4j.core.Neo4jTemplate; @@ -82,9 +81,6 @@ protected List findByAnyTypeClasses( } else if (domainType.equals(Neo4jDerSchema.class)) { label = Neo4jDerSchema.NODE; relationship = Neo4jAnyTypeClass.ANY_TYPE_CLASS_DER_REL; - } else if (domainType.equals(Neo4jVirSchema.class)) { - label = Neo4jVirSchema.NODE; - relationship = Neo4jAnyTypeClass.ANY_TYPE_CLASS_VIR_REL; } List clauses = new ArrayList<>(); diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AnyObjectRepoExtImpl.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AnyObjectRepoExtImpl.java index d74708bf46e..53158cf9519 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AnyObjectRepoExtImpl.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AnyObjectRepoExtImpl.java @@ -39,7 +39,6 @@ import org.apache.syncope.core.persistence.api.dao.GroupDAO; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; @@ -86,7 +85,6 @@ public AnyObjectRepoExtImpl( final AnyTypeClassDAO anyTypeClassDAO, final PlainSchemaDAO plainSchemaDAO, final DerSchemaDAO derSchemaDAO, - final VirSchemaDAO virSchemaDAO, final DynRealmDAO dynRealmDAO, final UserDAO userDAO, final GroupDAO groupDAO, @@ -101,7 +99,6 @@ public AnyObjectRepoExtImpl( anyTypeClassDAO, plainSchemaDAO, derSchemaDAO, - virSchemaDAO, dynRealmDAO, anyFinder, anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT), diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AnyTypeClassRepoExtImpl.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AnyTypeClassRepoExtImpl.java index 8669192b97c..7fc5f1cc581 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AnyTypeClassRepoExtImpl.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AnyTypeClassRepoExtImpl.java @@ -26,12 +26,10 @@ import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.DerSchema; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.group.TypeExtension; import org.apache.syncope.core.persistence.neo4j.dao.AbstractDAO; import org.apache.syncope.core.persistence.neo4j.entity.EntityCacheKey; @@ -40,7 +38,6 @@ import org.apache.syncope.core.persistence.neo4j.entity.Neo4jDerSchema; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jExternalResource; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jPlainSchema; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jVirSchema; import org.apache.syncope.core.persistence.neo4j.entity.group.Neo4jGroup; import org.apache.syncope.core.persistence.neo4j.spring.NodeValidator; import org.springframework.data.neo4j.core.Neo4jClient; @@ -55,8 +52,6 @@ public class AnyTypeClassRepoExtImpl extends AbstractDAO implements AnyTypeClass protected final DerSchemaDAO derSchemaDAO; - protected final VirSchemaDAO virSchemaDAO; - protected final GroupDAO groupDAO; protected final ExternalResourceDAO resourceDAO; @@ -73,7 +68,6 @@ public AnyTypeClassRepoExtImpl( final AnyTypeDAO anyTypeDAO, final PlainSchemaDAO plainSchemaDAO, final DerSchemaDAO derSchemaDAO, - final VirSchemaDAO virSchemaDAO, final GroupDAO groupDAO, final ExternalResourceDAO resourceDAO, final Neo4jTemplate neo4jTemplate, @@ -88,7 +82,6 @@ public AnyTypeClassRepoExtImpl( this.anyTypeDAO = anyTypeDAO; this.plainSchemaDAO = plainSchemaDAO; this.derSchemaDAO = derSchemaDAO; - this.virSchemaDAO = virSchemaDAO; this.groupDAO = groupDAO; this.resourceDAO = resourceDAO; this.nodeValidator = nodeValidator; @@ -121,13 +114,6 @@ public AnyTypeClass save(final AnyTypeClass anyTypeClass) { schema.getKey(), anyTypeClass.getKey(), Neo4jAnyTypeClass.ANY_TYPE_CLASS_DER_REL)); - before.getVirSchemas().stream().filter(schema -> !anyTypeClass.getVirSchemas().contains(schema)). - forEach(schema -> deleteRelationship( - Neo4jVirSchema.NODE, - Neo4jAnyTypeClass.NODE, - schema.getKey(), - anyTypeClass.getKey(), - Neo4jAnyTypeClass.ANY_TYPE_CLASS_VIR_REL)); }); AnyTypeClass merged = neo4jTemplate.save(nodeValidator.validate(anyTypeClass)); @@ -140,10 +126,6 @@ public AnyTypeClass save(final AnyTypeClass anyTypeClass) { schema.setAnyTypeClass(merged); derSchemaDAO.save(schema); } - for (VirSchema schema : merged.getVirSchemas()) { - schema.setAnyTypeClass(merged); - virSchemaDAO.save(schema); - } for (AnyType anyType : anyTypeDAO.findByClassesContaining(merged)) { anyType.getClasses().removeIf(c -> c.getKey().equals(merged.getKey())); @@ -170,10 +152,6 @@ public void deleteById(final String key) { schema.setAnyTypeClass(null); derSchemaDAO.save(schema); } - for (VirSchema schema : virSchemaDAO.findByAnyTypeClasses(List.of(anyTypeClass))) { - schema.setAnyTypeClass(null); - virSchemaDAO.save(schema); - } for (AnyType anyType : anyTypeDAO.findByClassesContaining(anyTypeClass)) { anyType.getClasses().remove(anyTypeClass); diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/ExternalResourceRepoExtImpl.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/ExternalResourceRepoExtImpl.java index 47c76c4a2d2..2f1c1254246 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/ExternalResourceRepoExtImpl.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/ExternalResourceRepoExtImpl.java @@ -31,7 +31,6 @@ import org.apache.syncope.core.persistence.api.dao.RealmDAO; import org.apache.syncope.core.persistence.api.dao.TaskDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.Implementation; import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy; @@ -70,8 +69,6 @@ public class ExternalResourceRepoExtImpl extends AbstractDAO implements External protected final GroupDAO groupDAO; - protected final VirSchemaDAO virSchemaDAO; - protected final RealmDAO realmDAO; protected final NodeValidator nodeValidator; @@ -83,7 +80,6 @@ public ExternalResourceRepoExtImpl( final AnyObjectDAO anyObjectDAO, final UserDAO userDAO, final GroupDAO groupDAO, - final VirSchemaDAO virSchemaDAO, final RealmDAO realmDAO, final Neo4jTemplate neo4jTemplate, final Neo4jClient neo4jClient, @@ -95,7 +91,6 @@ public ExternalResourceRepoExtImpl( this.anyObjectDAO = anyObjectDAO; this.userDAO = userDAO; this.groupDAO = groupDAO; - this.virSchemaDAO = virSchemaDAO; this.realmDAO = realmDAO; this.nodeValidator = nodeValidator; this.cache = cache; @@ -316,8 +311,6 @@ public void deleteById(final String key) { groupDAO.findByResourcesContaining(resource). forEach(group -> group.getResources().remove(resource)); - virSchemaDAO.findByResource(resource).forEach(virSchemaDAO::delete); - if (resource.getConnector() != null && resource.getConnector().getResources() != null && !resource.getConnector().getResources().isEmpty()) { diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/GroupRepoExtImpl.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/GroupRepoExtImpl.java index 93cbd53ace6..4aa022737d5 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/GroupRepoExtImpl.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/GroupRepoExtImpl.java @@ -42,7 +42,6 @@ import org.apache.syncope.core.persistence.api.dao.DynRealmDAO; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.dao.search.SearchCond; import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyType; @@ -110,7 +109,6 @@ public GroupRepoExtImpl( final AnyTypeClassDAO anyTypeClassDAO, final PlainSchemaDAO plainSchemaDAO, final DerSchemaDAO derSchemaDAO, - final VirSchemaDAO virSchemaDAO, final DynRealmDAO dynRealmDAO, final AnyMatchDAO anyMatchDAO, final UserDAO userDAO, @@ -128,7 +126,6 @@ public GroupRepoExtImpl( anyTypeClassDAO, plainSchemaDAO, derSchemaDAO, - virSchemaDAO, dynRealmDAO, anyFinder, anyUtilsFactory.getInstance(AnyTypeKind.GROUP), @@ -247,7 +244,7 @@ public List findOwnedByGroup(final String groupKey) { @Override public Collection findAllResourceKeys(final String key) { return findById(key).map(Any::getResources). - orElseGet(List::of). + orElseGet(List::of). stream().map(ExternalResource::getKey).toList(); } diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/UserRepoExtImpl.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/UserRepoExtImpl.java index 4def4011226..c50ada88720 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/UserRepoExtImpl.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/UserRepoExtImpl.java @@ -41,7 +41,6 @@ import org.apache.syncope.core.persistence.api.dao.GroupDAO; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.dao.RoleDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.Attributable; import org.apache.syncope.core.persistence.api.entity.ExternalResource; @@ -98,7 +97,6 @@ public UserRepoExtImpl( final AnyTypeClassDAO anyTypeClassDAO, final PlainSchemaDAO plainSchemaDAO, final DerSchemaDAO derSchemaDAO, - final VirSchemaDAO virSchemaDAO, final DynRealmDAO dynRealmDAO, final RoleDAO roleDAO, final AccessTokenDAO accessTokenDAO, @@ -117,7 +115,6 @@ public UserRepoExtImpl( anyTypeClassDAO, plainSchemaDAO, derSchemaDAO, - virSchemaDAO, dynRealmDAO, anyFinder, anyUtilsFactory.getInstance(AnyTypeKind.USER), diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/VirSchemaRepo.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/VirSchemaRepo.java deleted file mode 100644 index bb68492819a..00000000000 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/VirSchemaRepo.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.neo4j.dao.repo; - -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jVirSchema; -import org.springframework.data.repository.ListCrudRepository; - -public interface VirSchemaRepo - extends ListCrudRepository, VirSchemaRepoExt, VirSchemaDAO { - -} diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/VirSchemaRepoExt.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/VirSchemaRepoExt.java deleted file mode 100644 index ae60284f8b3..00000000000 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/VirSchemaRepoExt.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.neo4j.dao.repo; - -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; -import org.apache.syncope.core.persistence.api.entity.ExternalResource; -import org.apache.syncope.core.persistence.api.entity.VirSchema; - -public interface VirSchemaRepoExt { - - String CACHE = "virSchemaCache"; - - Optional findById(String key); - - List findByIdLike(String keyword); - - List findByAnyTypeClasses(Collection anyTypeClasses); - - List findByResource(ExternalResource resource); - - List findByResourceAndAnyType(String resource, String anyType); - - VirSchema save(VirSchema schema); - - void deleteById(String key); - - void delete(VirSchema schema); -} diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/VirSchemaRepoExtImpl.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/VirSchemaRepoExtImpl.java deleted file mode 100644 index 743ed5cef2d..00000000000 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/VirSchemaRepoExtImpl.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.neo4j.dao.repo; - -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import javax.cache.Cache; -import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; -import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; -import org.apache.syncope.core.persistence.api.entity.ExternalResource; -import org.apache.syncope.core.persistence.api.entity.Schema; -import org.apache.syncope.core.persistence.api.entity.VirSchema; -import org.apache.syncope.core.persistence.neo4j.entity.EntityCacheKey; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jAnyType; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jExternalResource; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jSchema; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jVirSchema; -import org.apache.syncope.core.persistence.neo4j.spring.NodeValidator; -import org.springframework.data.neo4j.core.Neo4jClient; -import org.springframework.data.neo4j.core.Neo4jTemplate; -import org.springframework.transaction.annotation.Transactional; - -public class VirSchemaRepoExtImpl extends AbstractSchemaRepoExt implements VirSchemaRepoExt { - - protected final ExternalResourceDAO resourceDAO; - - protected final Cache virSchemaCache; - - public VirSchemaRepoExtImpl( - final ExternalResourceDAO resourceDAO, - final Neo4jTemplate neo4jTemplate, - final Neo4jClient neo4jClient, - final NodeValidator nodeValidator, - final Cache virSchemaCache) { - - super(neo4jTemplate, neo4jClient, nodeValidator); - this.resourceDAO = resourceDAO; - this.virSchemaCache = virSchemaCache; - } - - @SuppressWarnings("unchecked") - @Override - protected Cache cache() { - return (Cache) virSchemaCache; - } - - @Transactional(readOnly = true) - @Override - public Optional findById(final String key) { - return findById(key, Neo4jVirSchema.class, virSchemaCache); - } - - @Transactional(readOnly = true) - @Override - public List findByIdLike(final String keyword) { - return findByIdLike(Neo4jVirSchema.NODE, Neo4jVirSchema.class, keyword); - } - - @Override - public List findByAnyTypeClasses(final Collection anyTypeClasses) { - return findByAnyTypeClasses(anyTypeClasses, Neo4jVirSchema.class, VirSchema.class); - } - - @Override - public List findByResource(final ExternalResource resource) { - return findByRelationship( - Neo4jVirSchema.NODE, - Neo4jExternalResource.NODE, - resource.getKey(), - Neo4jVirSchema.VIRSCHEMA_RESOURCE_REL, - Neo4jVirSchema.class, - virSchemaCache); - } - - @Override - public List findByResourceAndAnyType(final String resource, final String anyType) { - return toList(neo4jClient.query( - "MATCH (a:" + Neo4jAnyType.NODE + " {id: $anyTypeId})-" - + "[:" + Neo4jVirSchema.VIRSCHEMA_ANYTYPE_REL + "]-" - + "(n:" + Neo4jVirSchema.NODE + ")-" - + "[:" + Neo4jVirSchema.VIRSCHEMA_RESOURCE_REL + "]-" - + "(r:" + Neo4jExternalResource.NODE + " {id: $resourceId}) " - + "RETURN n.id").bindAll(Map.of("resourceId", resource, "anyTypeId", anyType)).fetch().all(), - "n.id", - Neo4jVirSchema.class, - virSchemaCache); - } - - @Override - public VirSchema save(final VirSchema schema) { - ((Neo4jSchema) schema).map2json(); - VirSchema saved = neo4jTemplate.save(nodeValidator.validate(schema)); - ((Neo4jSchema) saved).postSave(); - - virSchemaCache.put(EntityCacheKey.of(schema.getKey()), (Neo4jVirSchema) saved); - - return saved; - } - - @Override - public void deleteById(final String key) { - findById(key).ifPresent(this::delete); - } - - @Override - public void delete(final VirSchema schema) { - resourceDAO.deleteMapping(schema.getKey()); - - Optional.ofNullable(schema.getAnyTypeClass()).ifPresent(atc -> atc.getVirSchemas().remove(schema)); - - virSchemaCache.remove(EntityCacheKey.of(schema.getKey())); - - neo4jTemplate.deleteById(schema.getKey(), Neo4jVirSchema.class); - } -} diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jAnyTypeClass.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jAnyTypeClass.java index 49b5c3656c6..30ca771e62f 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jAnyTypeClass.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jAnyTypeClass.java @@ -23,7 +23,6 @@ import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.DerSchema; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.springframework.data.neo4j.core.schema.Node; import org.springframework.data.neo4j.core.schema.Relationship; @@ -38,17 +37,12 @@ public class Neo4jAnyTypeClass extends AbstractProvidedKeyNode implements AnyTyp public static final String ANY_TYPE_CLASS_DER_REL = "ANY_TYPE_CLASS_DER"; - public static final String ANY_TYPE_CLASS_VIR_REL = "ANY_TYPE_CLASS_VIR"; - @Relationship(type = ANY_TYPE_CLASS_PLAIN_REL, direction = Relationship.Direction.INCOMING) private List plainSchemas = new ArrayList<>(); @Relationship(type = ANY_TYPE_CLASS_DER_REL, direction = Relationship.Direction.INCOMING) private List derSchemas = new ArrayList<>(); - @Relationship(type = ANY_TYPE_CLASS_VIR_REL, direction = Relationship.Direction.INCOMING) - private List virSchemas = new ArrayList<>(); - @Override public boolean add(final PlainSchema schema) { checkType(schema, Neo4jPlainSchema.class); @@ -70,15 +64,4 @@ public boolean add(final DerSchema schema) { public List getDerSchemas() { return derSchemas; } - - @Override - public boolean add(final VirSchema schema) { - checkType(schema, Neo4jVirSchema.class); - return this.virSchemas.add((Neo4jVirSchema) schema); - } - - @Override - public List getVirSchemas() { - return virSchemas; - } } diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jEntityFactory.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jEntityFactory.java index 88267f646c7..5a79855f470 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jEntityFactory.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jEntityFactory.java @@ -48,7 +48,6 @@ import org.apache.syncope.core.persistence.api.entity.ReportExec; import org.apache.syncope.core.persistence.api.entity.Role; import org.apache.syncope.core.persistence.api.entity.SRARoute; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.am.AttrRepo; import org.apache.syncope.core.persistence.api.entity.am.AuthModule; import org.apache.syncope.core.persistence.api.entity.am.AuthProfile; @@ -216,8 +215,6 @@ public E newEntity(final Class reference) { result = (E) new Neo4jPlainSchema(); } else if (reference.equals(DerSchema.class)) { result = (E) new Neo4jDerSchema(); - } else if (reference.equals(VirSchema.class)) { - result = (E) new Neo4jVirSchema(); } else if (reference.equals(Report.class)) { result = (E) new Neo4jReport(); } else if (reference.equals(ReportExec.class)) { diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jVirSchema.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jVirSchema.java deleted file mode 100644 index 671e560ea2b..00000000000 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jVirSchema.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.neo4j.entity; - -import jakarta.validation.constraints.NotNull; -import org.apache.syncope.common.lib.types.AttrSchemaType; -import org.apache.syncope.core.persistence.api.entity.AnyType; -import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; -import org.apache.syncope.core.persistence.api.entity.ExternalResource; -import org.apache.syncope.core.persistence.api.entity.VirSchema; -import org.springframework.data.neo4j.core.schema.Node; -import org.springframework.data.neo4j.core.schema.Relationship; - -@Node(Neo4jVirSchema.NODE) -public class Neo4jVirSchema extends Neo4jSchema implements VirSchema { - - private static final long serialVersionUID = -4136127093718028088L; - - public static final String NODE = "VirSchema"; - - public static final String VIRSCHEMA_RESOURCE_REL = "VIRSCHEMA_RESOURCE"; - - public static final String VIRSCHEMA_ANYTYPE_REL = "VIRSCHEMA_ANYTYPE"; - - @NotNull - private String extAttrName; - - private Boolean readonly = false; - - @Relationship(type = Neo4jAnyTypeClass.ANY_TYPE_CLASS_VIR_REL, direction = Relationship.Direction.OUTGOING) - private Neo4jAnyTypeClass anyTypeClass; - - @NotNull - @Relationship(type = VIRSCHEMA_RESOURCE_REL, direction = Relationship.Direction.OUTGOING) - private Neo4jExternalResource resource; - - @NotNull - @Relationship(type = VIRSCHEMA_ANYTYPE_REL, direction = Relationship.Direction.OUTGOING) - private Neo4jAnyType anyType; - - @Override - public String getExtAttrName() { - return extAttrName; - } - - @Override - public void setExtAttrName(final String extAttrName) { - this.extAttrName = extAttrName; - } - - @Override - public boolean isReadonly() { - return readonly; - } - - @Override - public void setReadonly(final boolean readonly) { - this.readonly = readonly; - } - - @Override - public AttrSchemaType getType() { - return AttrSchemaType.String; - } - - @Override - public String getMandatoryCondition() { - return Boolean.FALSE.toString().toLowerCase(); - } - - @Override - public boolean isMultivalue() { - return true; - } - - @Override - public boolean isUniqueConstraint() { - return false; - } - - @Override - public AnyTypeClass getAnyTypeClass() { - return anyTypeClass; - } - - @Override - public void setAnyTypeClass(final AnyTypeClass anyTypeClass) { - checkType(anyTypeClass, Neo4jAnyTypeClass.class); - this.anyTypeClass = (Neo4jAnyTypeClass) anyTypeClass; - } - - @Override - public ExternalResource getResource() { - return resource; - } - - @Override - public void setResource(final ExternalResource resource) { - checkType(resource, Neo4jExternalResource.class); - this.resource = (Neo4jExternalResource) resource; - } - - @Override - public AnyType getAnyType() { - return anyType; - } - - @Override - public void setAnyType(final AnyType anyType) { - checkType(anyType, Neo4jAnyType.class); - this.anyType = (Neo4jAnyType) anyType; - } -} diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/spring/CacheCleaningTransactionExecutionListener.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/spring/CacheCleaningTransactionExecutionListener.java index 1dc21fe2df4..930e43aafb9 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/spring/CacheCleaningTransactionExecutionListener.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/spring/CacheCleaningTransactionExecutionListener.java @@ -28,7 +28,6 @@ import org.apache.syncope.core.persistence.neo4j.entity.Neo4jPlainSchema; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jRealm; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jRole; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jVirSchema; import org.apache.syncope.core.persistence.neo4j.entity.anyobject.Neo4jAnyObject; import org.apache.syncope.core.persistence.neo4j.entity.group.Neo4jGroup; import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jUser; @@ -59,8 +58,6 @@ public class CacheCleaningTransactionExecutionListener implements TransactionExe protected final Cache userCache; - protected final Cache virSchemaCache; - public CacheCleaningTransactionExecutionListener( final Cache anyTypeCache, final Cache anyObjectCache, @@ -72,8 +69,7 @@ public CacheCleaningTransactionExecutionListener( final Cache plainSchemaCache, final Cache realmCache, final Cache roleCache, - final Cache userCache, - final Cache virSchemaCache) { + final Cache userCache) { this.anyTypeCache = anyTypeCache; this.anyObjectCache = anyObjectCache; @@ -86,7 +82,6 @@ public CacheCleaningTransactionExecutionListener( this.realmCache = realmCache; this.roleCache = roleCache; this.userCache = userCache; - this.virSchemaCache = virSchemaCache; } @Override @@ -105,7 +100,6 @@ public void afterRollback( } else if (transaction.getTransactionName().contains("Schema")) { derSchemaCache.removeAll(); plainSchemaCache.removeAll(); - virSchemaCache.removeAll(); } else if (transaction.getTransactionName().contains("Resource")) { externalResourceCache.removeAll(); } else if (transaction.getTransactionName().contains("Group")) { diff --git a/core/persistence-neo4j/src/main/resources/META-INF/indexes.xml b/core/persistence-neo4j/src/main/resources/META-INF/indexes.xml index c59cc41b1c0..0bbfcb932de 100644 --- a/core/persistence-neo4j/src/main/resources/META-INF/indexes.xml +++ b/core/persistence-neo4j/src/main/resources/META-INF/indexes.xml @@ -57,7 +57,6 @@ under the License. CREATE CONSTRAINT Schema_id FOR (n:Schema) REQUIRE n.id IS UNIQUE CREATE INDEX PlainSchema_id FOR (n:PlainSchema) ON (n.id) CREATE INDEX DerSchema_id FOR (n:DerSchema) ON (n.id) - CREATE INDEX VirSchema_id FOR (n:VirSchema) ON (n.id) CREATE CONSTRAINT SRARoute_name FOR (n:SRARoute) REQUIRE n.name IS UNIQUE diff --git a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/AnyTypeClassTest.java b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/AnyTypeClassTest.java index 5feea372e6c..8b0a7d904ab 100644 --- a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/AnyTypeClassTest.java +++ b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/AnyTypeClassTest.java @@ -48,7 +48,6 @@ public void find() { assertFalse(minimalGroup.getPlainSchemas().isEmpty()); assertFalse(minimalGroup.getDerSchemas().isEmpty()); - assertFalse(minimalGroup.getVirSchemas().isEmpty()); } @Test @@ -72,7 +71,6 @@ public void save() { assertNotNull(newClass); assertFalse(newClass.getPlainSchemas().isEmpty()); assertTrue(newClass.getDerSchemas().isEmpty()); - assertTrue(newClass.getVirSchemas().isEmpty()); firstname = plainSchemaDAO.findById("firstname").orElseThrow(); assertEquals(newClass, firstname.getAnyTypeClass()); diff --git a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/RemediationTest.java b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/RemediationTest.java index 2c9b8c21a80..c91297f3ff5 100644 --- a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/RemediationTest.java +++ b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/RemediationTest.java @@ -70,7 +70,7 @@ public void createMissingPayload() { remediation.setInstant(OffsetDateTime.now()); remediation.setRemoteName("remote"); remediation.setPullTask((PullTask) taskDAO.findById( - TaskType.PULL, "38abbf9e-a1a3-40a1-a15f-7d0ac02f47f1").orElseThrow()); + TaskType.PULL, "81d88f73-d474-4450-9031-605daa4e313f").orElseThrow()); // missing payload try { @@ -92,7 +92,7 @@ public void createWrongPayload() { remediation.setInstant(OffsetDateTime.now()); remediation.setRemoteName("remote"); remediation.setPullTask((PullTask) taskDAO.findById( - TaskType.PULL, "38abbf9e-a1a3-40a1-a15f-7d0ac02f47f1").orElseThrow()); + TaskType.PULL, "81d88f73-d474-4450-9031-605daa4e313f").orElseThrow()); remediation.setPayload(UUID.randomUUID().toString()); // wrong payload for operation @@ -115,7 +115,7 @@ public void create() { remediation.setInstant(OffsetDateTime.now()); remediation.setRemoteName("remote"); remediation.setPullTask((PullTask) taskDAO.findById( - TaskType.PULL, "38abbf9e-a1a3-40a1-a15f-7d0ac02f47f1").orElseThrow()); + TaskType.PULL, "81d88f73-d474-4450-9031-605daa4e313f").orElseThrow()); remediation.setPayload(UUID.randomUUID().toString()); remediation.setOperation(ResourceOperation.DELETE); diff --git a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/ResourceTest.java b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/ResourceTest.java index b2f181ca89e..754ac0a3cd5 100644 --- a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/ResourceTest.java +++ b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/ResourceTest.java @@ -237,38 +237,6 @@ public void saveInvalidProvision() { }); } - @Test - public void saveVirtualMapping() { - ExternalResource resource = entityFactory.newEntity(ExternalResource.class); - resource.setKey("ws-target-resource-virtual-mapping"); - resource.setPropagationPriority(2); - - Provision provision = new Provision(); - provision.setAnyType(AnyTypeKind.USER.name()); - provision.setObjectClass(ObjectClass.ACCOUNT_NAME); - resource.getProvisions().add(provision); - - Mapping mapping = new Mapping(); - provision.setMapping(mapping); - - Item connObjectKey = new Item(); - connObjectKey.setExtAttrName("username"); - connObjectKey.setIntAttrName("fullname"); - connObjectKey.setPurpose(MappingPurpose.BOTH); - mapping.setConnObjectKeyItem(connObjectKey); - - Item virtualMapItem = new Item(); - virtualMapItem.setIntAttrName("virtualReadOnly"); - virtualMapItem.setExtAttrName("TEST"); - virtualMapItem.setPurpose(MappingPurpose.PROPAGATION); - mapping.add(virtualMapItem); - - ConnInstance connector = resourceDAO.findById("ws-target-resource-1").orElseThrow().getConnector(); - resource.setConnector(connector); - - resourceDAO.save(resource); - } - @Test public void saveWithGroupMappingType() { ExternalResource resource = entityFactory.newEntity(ExternalResource.class); diff --git a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/TaskTest.java b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/TaskTest.java index b9a3477d9cf..fb1d5bb677c 100644 --- a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/TaskTest.java +++ b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/TaskTest.java @@ -126,7 +126,7 @@ public void findAll() { assertEquals(6, taskDAO.findAll(TaskType.PROPAGATION).size()); assertEquals(1, taskDAO.findAll(TaskType.NOTIFICATION).size()); assertEquals(3, taskDAO.findAll(TaskType.SCHEDULED).size()); - assertEquals(10, taskDAO.findAll(TaskType.PULL).size()); + assertEquals(9, taskDAO.findAll(TaskType.PULL).size()); assertEquals(11, taskDAO.findAll(TaskType.PUSH).size()); List authorities = IdRepoEntitlement.values().stream(). diff --git a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/VirSchemaTest.java b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/VirSchemaTest.java deleted file mode 100644 index f2fe53ad014..00000000000 --- a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/VirSchemaTest.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.neo4j.inner; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -import java.util.List; -import org.apache.syncope.common.lib.types.EntityViolationType; -import org.apache.syncope.core.persistence.api.attrvalue.InvalidEntityException; -import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO; -import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; -import org.apache.syncope.core.persistence.api.entity.VirSchema; -import org.apache.syncope.core.persistence.neo4j.AbstractTest; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; - -@Transactional -public class VirSchemaTest extends AbstractTest { - - @Autowired - private VirSchemaDAO virSchemaDAO; - - @Autowired - private ExternalResourceDAO resourceDAO; - - @Autowired - private AnyTypeDAO anyTypeDAO; - - @Test - public void findAll() { - List list = virSchemaDAO.findAll(); - assertEquals(3, list.size()); - } - - @Test - public void findByIdLike() { - List schemas = virSchemaDAO.findByIdLike("rvirtuald%"); - assertEquals(1, schemas.size()); - } - - @Test - public void findByName() { - VirSchema attributeSchema = virSchemaDAO.findById("virtualdata").orElseThrow(); - assertNotNull(attributeSchema); - } - - @Test - public void save() { - VirSchema virSchema = entityFactory.newEntity(VirSchema.class); - virSchema.setKey("virtual"); - virSchema.setResource(resourceDAO.findById("resource-csv").orElseThrow()); - virSchema.setAnyType(anyTypeDAO.getUser()); - virSchema.setReadonly(true); - virSchema.setExtAttrName("EXT_ATTR"); - - virSchemaDAO.save(virSchema); - - VirSchema actual = virSchemaDAO.findById("virtual").orElseThrow(); - assertNotNull(actual); - assertTrue(actual.isReadonly()); - assertEquals("EXT_ATTR", actual.getExtAttrName()); - } - - @Test - public void delete() { - VirSchema virtualdata = virSchemaDAO.findById("virtualdata").orElseThrow(); - - virSchemaDAO.deleteById(virtualdata.getKey()); - - assertTrue(virSchemaDAO.findById("virtualdata").isEmpty()); - - // ------------- // - VirSchema rvirtualdata = virSchemaDAO.findById("rvirtualdata").orElseThrow(); - - virSchemaDAO.deleteById(rvirtualdata.getKey()); - - assertTrue(virSchemaDAO.findById("rvirtualdata").isEmpty()); - } - - @Test - public void issueSYNCOPE418() { - VirSchema schema = entityFactory.newEntity(VirSchema.class); - schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit"); - - try { - virSchemaDAO.save(schema); - fail("This should not happen"); - } catch (InvalidEntityException e) { - assertTrue(e.hasViolation(EntityViolationType.InvalidKey)); - } - } -} diff --git a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/outer/VirSchemaTest.java b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/outer/VirSchemaTest.java deleted file mode 100644 index ab9af6ffafe..00000000000 --- a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/outer/VirSchemaTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.neo4j.outer; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.apache.syncope.common.lib.to.Item; -import org.apache.syncope.common.lib.types.AnyTypeKind; -import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO; -import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; -import org.apache.syncope.core.persistence.api.entity.ExternalResource; -import org.apache.syncope.core.persistence.api.entity.VirSchema; -import org.apache.syncope.core.persistence.neo4j.AbstractTest; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; - -@Transactional -public class VirSchemaTest extends AbstractTest { - - @Autowired - private VirSchemaDAO virSchemaDAO; - - @Autowired - private ExternalResourceDAO resourceDAO; - - @Autowired - private AnyTypeDAO anyTypeDAO; - - @Test - public void deal() { - ExternalResource resource = resourceDAO.findById("ws-target-resource-1").orElseThrow(); - assertTrue(virSchemaDAO.findByResource(resource).isEmpty()); - assertTrue(virSchemaDAO.findByResourceAndAnyType(resource.getKey(), AnyTypeKind.USER.name()).isEmpty()); - - VirSchema virSchema = entityFactory.newEntity(VirSchema.class); - virSchema.setKey("vSchema"); - virSchema.setReadonly(true); - virSchema.setExtAttrName("EXT_ATTR"); - virSchema.setResource(resource); - virSchema.setAnyType(anyTypeDAO.getUser()); - - virSchemaDAO.save(virSchema); - - virSchema = virSchemaDAO.findById("vSchema").orElseThrow(); - assertTrue(virSchema.isReadonly()); - assertEquals("EXT_ATTR", virSchema.getExtAttrName()); - - assertFalse(virSchemaDAO.findByResource(resource).isEmpty()); - assertTrue(virSchemaDAO.findByResource(resource).contains(virSchema)); - - assertFalse(virSchemaDAO.findByResourceAndAnyType( - resource.getKey(), AnyTypeKind.USER.name()).isEmpty()); - assertTrue(virSchemaDAO.findByResourceAndAnyType( - resource.getKey(), AnyTypeKind.USER.name()).contains(virSchema)); - - Item item = virSchema.asLinkingMappingItem(); - assertNotNull(item); - assertEquals(virSchema.getKey(), item.getIntAttrName()); - } -} diff --git a/core/persistence-neo4j/src/test/resources/domains/MasterContent.xml b/core/persistence-neo4j/src/test/resources/domains/MasterContent.xml index c5465463a38..0d8c78b01a4 100644 --- a/core/persistence-neo4j/src/test/resources/domains/MasterContent.xml +++ b/core/persistence-neo4j/src/test/resources/domains/MasterContent.xml @@ -583,58 +583,58 @@ under the License. + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"email","extAttrName":"email","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"surname","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"password":true,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"fullname","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"ctype","extAttrName":"type","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"firstname","extAttrName":"name","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"NONE","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"username","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"password":true,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"ctype","extAttrName":"type","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"surname","connObjectKey":false,"password":false,"mandatoryCondition":"type == 'F'","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"cn","extAttrName":"fullname","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"email","extAttrName":"email","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"surname","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"email","extAttrName":"email","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"username","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"email","extAttrName":"email","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"userId","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"fullname","extAttrName":"test3","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"userId","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"password":true,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"username","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"password":true,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"username","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":["csv","generic membership","minimal group"],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"username","extAttrName":"id","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"fullname","extAttrName":"id","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"password":true,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"firstname","extAttrName":"name","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"surname","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"userId","extAttrName":"email","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"PULL","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"email","extAttrName":"email","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"PULL","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"csvuserid","extAttrName":"__NAME__","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"groups[root].rderToBePropagated","extAttrName":"theirgroup","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"csvuserid","extAttrName":"__NAME__","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":"{\"value\":null}","ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"userId","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"fullname","extAttrName":"__PASSWORD__","connObjectKey":false,"password":true,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"userId","extAttrName":"userId","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":["generic membership","minimal group"],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":"'uid=' + username + ',ou=people,${testds.rootDn}'","items":[{"intAttrName":"username","extAttrName":"cn","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"password":true,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"sn","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"fullname","extAttrName":"cn","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"email","extAttrName":"mail","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"title","extAttrName":"title","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"postalAddress","extAttrName":"postalAddress","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"userId","extAttrName":"mail","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"obscure","extAttrName":"registeredAddress","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"photo","extAttrName":"jpegPhoto","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"username","extAttrName":"cn","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}},{"anyType":"GROUP","objectClass":"__GROUP__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":"'cn=' + name + ',ou=groups,${testds.rootDn}'","items":[{"intAttrName":"name","extAttrName":"cn","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"userOwner","extAttrName":"owner","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"title","extAttrName":"description","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"name","extAttrName":"cn","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"fullname","extAttrName":"fullname","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"PROPAGATION","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"email","extAttrName":"EMAIL","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"fullname","extAttrName":"SURNAME","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"PULL","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"firstname","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"SURNAME","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"username","extAttrName":"USERNAME","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"userId","extAttrName":"EMAIL","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"PULL","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"mustChangePassword","extAttrName":"MUSTCHANGEPASSWORD","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"PULL","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"firstname","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> - - + provisions='[{"anyType":"PRINTER","objectClass":"__PRINTER__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"key","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"name","extAttrName":"PRINTERNAME","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"location","extAttrName":"LOCATION","connObjectKey":false,"password":false,"mandatoryCondition":"false","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"key","extAttrName":"ID","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> + propagationPriority="0" provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"firstname","extAttrName":"firstName","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"key","extAttrName":"key","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"password":true,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"username","extAttrName":"username","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"email","extAttrName":"email","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"surname","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"connObjectKeyItem":{"intAttrName":"key","extAttrName":"key","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}}}]'/> @@ -700,21 +696,6 @@ under the License. - - - - - - - - - - - - - - - + template='{"_class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":null,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":["csv"],"derAttrs":[{"schema":"cn","values":[""]}],"resources":["resource-testdb"],"relationships":[],"memberships":[{"groupKey":"f779c0d4-633b-4be5-8f57-32eb478a3ca5","groupName":null}],"dynMemberships":[],"roles":[],"dynRoles":[],"plainAttrs":[{"schema":"ctype","values":["email == 'test8@syncope.apache.org'? 'TYPE_8': 'TYPE_OTHER'"]}]}'/> + template='{"_class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":null,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"resources":[],"plainAttrs":[]}'/> + template='{"_class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":null,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"resources":[],"relationships":[],"memberships":[],"dynMemberships":[],"roles":[],"dynRoles":[],"plainAttrs":[{"schema":"ctype","values":["'type a'"]},{"schema":"userId","values":["'reconciled@syncope.apache.org'"]},{"schema":"fullname","values":["'reconciled fullname'"]},{"schema":"surname","values":["'surname'"]}]}'/> + template='{"_class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":null,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"resources":[],"plainAttrs":[]}'/> + template='{"_class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":null,"type":"USER","realm":"'/' + title","status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":["minimal group"],"derAttrs":[],"resources":["resource-ldap"],"roles":[],"dynRoles":[],"relationships":[],"memberships":[],"dynMemberships":[],"plainAttrs":[]}'/> + template='{"_class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":null,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"resources":[],"plainAttrs":[{"schema":"show","values":["true"]}]}'/> - - - + template='{"_class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":null,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"resources":["resource-testdb"],"roles":[],"dynRoles":[],"relationships":[],"memberships":[],"dynMemberships":[],"plainAttrs":[{"schema":"firstname","values":[""]},{"schema":"userId","values":["'test'"]},{"schema":"fullname","values":["'test'"]},{"schema":"surname","values":["'test'"]}]}'/> + template='{"_class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":null,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"resources":[],"plainAttrs":[]}'/> find(final String key) { if (schema == null) { schema = derSchemaDAO.findById(key).orElse(null); if (schema == null) { - schema = virSchemaDAO.findById(key).orElse(null); - if (schema == null) { - return null; - } - return Pair.of(schema, SchemaType.VIRTUAL); + return null; } return Pair.of(schema, SchemaType.DERIVED); } diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/VirAttrHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/VirAttrHandler.java deleted file mode 100644 index 613b6ae1b7a..00000000000 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/VirAttrHandler.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.provisioning.api; - -import java.util.List; -import java.util.Map; -import org.apache.syncope.core.persistence.api.entity.Any; -import org.apache.syncope.core.persistence.api.entity.Membership; -import org.apache.syncope.core.persistence.api.entity.VirSchema; -import org.identityconnectors.framework.common.objects.ConnectorObject; - -public interface VirAttrHandler { - - String CACHE = "virAttrCache"; - - /** - * Updates cache with values from external resource. - * - * @param any any object - * @param connObj connector object from external resource - */ - void setValues(Any any, ConnectorObject connObj); - - /** - * Query external resource (or cache, if configured) associated to the given any for values associated to the given - * virtual schema, not related to any membership. - * - * @param any any object - * @param schema virtual schema - * @return virtual attribute values, either for local cache or external resource, if resource is owned by the given - * any and associated to the given virtual schema; empty list otherwise. - */ - List getValues(Any any, VirSchema schema); - - /** - * Query external resource (or cache, if configured) associated to the given any for values associated to the given - * virtual schema, for the given membership. - * - * @param any any object - * @param membership membership - * @param schema virtual schema - * @return virtual attribute values, either for local cache or external resource, if resource is owned by the given - * any and associated to the given virtual schema; empty list otherwise. - */ - List getValues(Any any, Membership membership, VirSchema schema); - - /** - * Query external resources (or cache, if configured) associated to the given any for values associated to all - * {@link VirSchema} instances in the {@link org.apache.syncope.core.persistence.api.entity.AnyTypeClass} - * associated to the given any, with no membership. - * - * @param any any object - * @return virtual attribute values, either for local cache or external resources - */ - Map> getValues(Any any); - - /** - * Query external resources (or cache, if configured) associated to the given any for values associated to all - * {@link VirSchema} instances in the {@link org.apache.syncope.core.persistence.api.entity.AnyTypeClass} - * associated to the given any, for the given membership. - * - * @param any any object - * @param membership membership - * @return virtual attribute values, either for local cache or external resources - */ - Map> getValues(Any any, Membership membership); - -} diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ItemTransformer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ItemTransformer.java index cb31ab94dd1..8cbd2dcba2f 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ItemTransformer.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/ItemTransformer.java @@ -30,8 +30,6 @@ /** * Transforms values to be propagated to (or pulling from) external resources right before they leave (or enter) * the Syncope internal storage. - * - * These transformations are not applied to virtual attribute values. */ public interface ItemTransformer { diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SchemaDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SchemaDataBinder.java index 1368fec685d..7ce80b9b640 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SchemaDataBinder.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SchemaDataBinder.java @@ -20,10 +20,8 @@ import org.apache.syncope.common.lib.to.DerSchemaTO; import org.apache.syncope.common.lib.to.PlainSchemaTO; -import org.apache.syncope.common.lib.to.VirSchemaTO; import org.apache.syncope.core.persistence.api.entity.DerSchema; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.VirSchema; public interface SchemaDataBinder { @@ -31,17 +29,11 @@ public interface SchemaDataBinder { DerSchema create(DerSchemaTO schemaTO); - VirSchema create(VirSchemaTO schemaTO); - PlainSchema update(PlainSchemaTO schemaTO, PlainSchema schema); DerSchema update(DerSchemaTO schemaTO, DerSchema derSchema); - VirSchema update(VirSchemaTO schemaTO, VirSchema virSchema); - PlainSchemaTO getPlainSchemaTO(String key); DerSchemaTO getDerSchemaTO(String key); - - VirSchemaTO getVirSchemaTO(String key); } diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java index 346ef2f4f59..458c5f3fd9e 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationManager.java @@ -24,7 +24,6 @@ import java.util.Set; import java.util.stream.Stream; import org.apache.commons.lang3.tuple.Pair; -import org.apache.syncope.common.lib.Attr; import org.apache.syncope.common.lib.request.AnyUR; import org.apache.syncope.common.lib.request.UserUR; import org.apache.syncope.common.lib.to.Item; @@ -61,7 +60,6 @@ public interface PropagationManager { * @param key any key * @param enable whether any should be enabled or not * @param propByRes operation to be performed per resource - * @param vAttrs virtual attributes to be set * @param excludedResources external resources performing not to be considered for propagation * @return list of propagation tasks */ @@ -70,7 +68,6 @@ List getCreateTasks( String key, Boolean enable, PropagationByResource propByRes, - Collection vAttrs, Collection excludedResources); /** @@ -81,7 +78,6 @@ List getCreateTasks( * @param enable whether user must be enabled or not * @param propByRes operation to be performed per resource * @param propByLinkedAccount operation to be performed for linked accounts - * @param vAttrs virtual attributes to be set * @param excludedResources external resources not to be considered for propagation * @return list of propagation tasks */ @@ -91,7 +87,6 @@ List getUserCreateTasks( Boolean enable, PropagationByResource propByRes, PropagationByResource> propByLinkedAccount, - Collection vAttrs, Collection excludedResources); /** @@ -104,7 +99,6 @@ List getUserCreateTasks( * @param enable whether any should be enabled or not, may be null to leave unchanged * @param propByRes operation to be performed per resource * @param propByLinkedAccount operation to be performed for linked accounts - * @param vAttrs virtual attributes to be set * @param excludedResources external resource keys not to be considered for propagation * @return list of propagation tasks */ @@ -116,7 +110,6 @@ List getUpdateTasks( Boolean enable, PropagationByResource propByRes, PropagationByResource> propByLinkedAccount, - Collection vAttrs, Collection excludedResources); /** @@ -186,7 +179,7 @@ List createTasks( * @param kind any type kind * @param key any key * @param password to be set (for users) - * @param changePwdRes the resources in which the password must be included in the propagation attributes (for + * @param changePwdRes the resources in which the password must be included in the propagation attributes (for * users) * @param enable whether any should be enabled or not, may be null to leave unchanged * @param excludedResources external resource keys not to be considered for propagation diff --git a/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/IntAttrNameParserTest.java b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/IntAttrNameParserTest.java index 412135797e0..5823218fb34 100644 --- a/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/IntAttrNameParserTest.java +++ b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/IntAttrNameParserTest.java @@ -41,12 +41,10 @@ import org.apache.syncope.common.lib.types.SchemaType; import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.AnyUtils; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.DerSchema; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.utils.RealmUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -67,9 +65,6 @@ public class IntAttrNameParserTest extends AbstractTest { @Mock private DerSchemaDAO derSchemaDAO; - @Mock - private VirSchemaDAO virSchemaDAO; - @Mock private AnyUtilsFactory anyUtilsFactory; @@ -135,23 +130,8 @@ public void initMocks() throws NoSuchFieldException { } } }); - lenient().when(virSchemaDAO.findById(anyString())).thenAnswer(ic -> { - String schemaName = ic.getArgument(0); - switch (schemaName) { - case "rvirtualdata" -> { - VirSchema schema = mock(VirSchema.class); - lenient().when(schema.getKey()).thenReturn(ic.getArgument(0)); - return Optional.of(schema); - } - default -> { - return Optional.empty(); - } - } - }); - - intAttrNameParser = new IntAttrNameParser( - plainSchemaDAO, derSchemaDAO, virSchemaDAO, anyUtilsFactory, realmUtils); + intAttrNameParser = new IntAttrNameParser(plainSchemaDAO, derSchemaDAO, anyUtilsFactory, realmUtils); } @Test @@ -247,20 +227,6 @@ public void ownSchema() throws ParseException { assertNull(intAttrName.getRelationshipAnyType()); assertNull(intAttrName.getRelationshipType()); assertNull(intAttrName.getRelatedUser()); - - intAttrName = intAttrNameParser.parse("rvirtualdata", AnyTypeKind.ANY_OBJECT); - assertNotNull(intAttrName); - assertEquals(AnyTypeKind.ANY_OBJECT, intAttrName.getAnyTypeKind()); - assertNull(intAttrName.getField()); - assertEquals("rvirtualdata", intAttrName.getSchema().getKey()); - assertEquals(SchemaType.VIRTUAL, intAttrName.getSchemaType()); - assertTrue(intAttrName.getSchema() instanceof VirSchema); - assertNull(intAttrName.getEnclosingGroup()); - assertNull(intAttrName.getMembershipOfGroup()); - assertNull(intAttrName.getRelatedAnyObject()); - assertNull(intAttrName.getRelationshipAnyType()); - assertNull(intAttrName.getRelationshipType()); - assertNull(intAttrName.getRelatedUser()); } @Test diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java index 78528fd098c..9be41824f97 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java @@ -31,7 +31,6 @@ import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager; import org.apache.syncope.core.provisioning.api.PropagationByResource; -import org.apache.syncope.core.provisioning.api.VirAttrHandler; import org.apache.syncope.core.provisioning.api.WorkflowResult; import org.apache.syncope.core.provisioning.api.propagation.PropagationManager; import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter; @@ -52,20 +51,16 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin protected final AnyObjectDAO anyObjectDAO; - protected final VirAttrHandler virtAttrHandler; - public DefaultAnyObjectProvisioningManager( final AnyObjectWorkflowAdapter awfAdapter, final PropagationManager propagationManager, final PropagationTaskExecutor taskExecutor, - final AnyObjectDAO anyObjectDAO, - final VirAttrHandler virtAttrHandler) { + final AnyObjectDAO anyObjectDAO) { this.awfAdapter = awfAdapter; this.propagationManager = propagationManager; this.taskExecutor = taskExecutor; this.anyObjectDAO = anyObjectDAO; - this.virtAttrHandler = virtAttrHandler; } @Override @@ -94,7 +89,6 @@ public Pair> create( created.getResult(), null, created.getPropByRes(), - anyObjectCR.getVirAttrs(), excludedResources); PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, creator); @@ -129,7 +123,6 @@ public Pair> update( null, updated.getPropByRes(), null, - anyObjectUR.getVirAttrs(), excludedResources), beforeAttrs); PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, updater); @@ -202,7 +195,6 @@ public List provision( null, propByRes, null, - null, null); PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, executor); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java index d772d0df1a6..e2d7241542f 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java @@ -33,7 +33,6 @@ import org.apache.syncope.core.persistence.api.dao.GroupDAO; import org.apache.syncope.core.provisioning.api.GroupProvisioningManager; import org.apache.syncope.core.provisioning.api.PropagationByResource; -import org.apache.syncope.core.provisioning.api.VirAttrHandler; import org.apache.syncope.core.provisioning.api.WorkflowResult; import org.apache.syncope.core.provisioning.api.data.GroupDataBinder; import org.apache.syncope.core.provisioning.api.propagation.PropagationManager; @@ -57,22 +56,18 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager protected final GroupDAO groupDAO; - protected final VirAttrHandler virtAttrHandler; - public DefaultGroupProvisioningManager( final GroupWorkflowAdapter gwfAdapter, final PropagationManager propagationManager, final PropagationTaskExecutor taskExecutor, final GroupDataBinder groupDataBinder, - final GroupDAO groupDAO, - final VirAttrHandler virtAttrHandler) { + final GroupDAO groupDAO) { this.gwfAdapter = gwfAdapter; this.propagationManager = propagationManager; this.taskExecutor = taskExecutor; this.groupDataBinder = groupDataBinder; this.groupDAO = groupDAO; - this.virtAttrHandler = virtAttrHandler; } @Override @@ -86,7 +81,6 @@ public Pair> create( created.getResult(), null, created.getPropByRes(), - groupCR.getVirAttrs(), Set.of()); PropagationReporter propagationReporter = taskExecutor.execute(tasks, nullPriorityAsync, creator); @@ -114,7 +108,6 @@ public Pair> create( created.getResult(), null, created.getPropByRes(), - groupCR.getVirAttrs(), excludedResources); PropagationReporter propagationReporter = taskExecutor.execute(tasks, nullPriorityAsync, creator); @@ -149,7 +142,6 @@ public Pair> update( null, updated.getPropByRes(), null, - groupUR.getVirAttrs(), excludedResources), beforeAttrs); PropagationReporter propagationReporter = taskExecutor.execute(tasks, nullPriorityAsync, updater); @@ -237,7 +229,6 @@ public List provision( null, propByRes, null, - null, null); PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, executor); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java index 6384e346252..222fff943e5 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java @@ -24,11 +24,9 @@ import java.util.Base64; import java.util.HashSet; import java.util.List; -import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; -import javax.cache.Cache; import org.apache.commons.jexl3.JexlContext; import org.apache.commons.jexl3.MapContext; import org.apache.commons.lang3.BooleanUtils; @@ -73,7 +71,6 @@ import org.apache.syncope.core.persistence.api.entity.Relatable; import org.apache.syncope.core.persistence.api.entity.Relationship; import org.apache.syncope.core.persistence.api.entity.RelationshipType; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.user.Account; @@ -86,11 +83,8 @@ import org.apache.syncope.core.provisioning.api.IntAttrNameParser; import org.apache.syncope.core.provisioning.api.MappingManager; import org.apache.syncope.core.provisioning.api.PlainAttrGetter; -import org.apache.syncope.core.provisioning.api.VirAttrHandler; import org.apache.syncope.core.provisioning.api.data.ItemTransformer; import org.apache.syncope.core.provisioning.api.jexl.JexlUtils; -import org.apache.syncope.core.provisioning.java.cache.VirAttrCacheKey; -import org.apache.syncope.core.provisioning.java.cache.VirAttrCacheValue; import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils; import org.apache.syncope.core.provisioning.java.utils.MappingUtils; import org.identityconnectors.framework.common.FrameworkUtil; @@ -192,10 +186,6 @@ protected static PlainAttrValue clonePlainAttrValue(final PlainAttrValue src) { protected final DerAttrHandler derAttrHandler; - protected final VirAttrHandler virAttrHandler; - - protected final Cache virAttrCache; - protected final IntAttrNameParser intAttrNameParser; protected final EncryptorManager encryptorManager; @@ -209,8 +199,6 @@ public DefaultMappingManager( final RealmSearchDAO realmSearchDAO, final ImplementationDAO implementationDAO, final DerAttrHandler derAttrHandler, - final VirAttrHandler virAttrHandler, - final Cache virAttrCache, final IntAttrNameParser intAttrNameParser, final EncryptorManager encryptorManager) { @@ -222,8 +210,6 @@ public DefaultMappingManager( this.realmSearchDAO = realmSearchDAO; this.implementationDAO = implementationDAO; this.derAttrHandler = derAttrHandler; - this.virAttrHandler = virAttrHandler; - this.virAttrCache = virAttrCache; this.intAttrNameParser = intAttrNameParser; this.encryptorManager = encryptorManager; } @@ -523,9 +509,6 @@ public Pair prepareAttr( AttrSchemaType schemaType = intAttrName.getSchema() instanceof PlainSchema ? intAttrName.getSchema().getType() : AttrSchemaType.String; - boolean readOnlyVirSchema = intAttrName.getSchema() instanceof VirSchema - ? intAttrName.getSchema().isReadonly() - : false; Pair> intValues = getIntValues( resource, provision, item, intAttrName, schemaType, any, usernameAccountGetter, plainAttrGetter); @@ -542,39 +525,35 @@ public Pair prepareAttr( * Values {}""", item, intAttrName.getSchema(), schemaType.getType().getName(), schemaType, values); - Pair result; - if (readOnlyVirSchema) { - result = null; - } else { - List objValues = new ArrayList<>(); + List objValues = new ArrayList<>(); - for (PlainAttrValue value : values) { - if (FrameworkUtil.isSupportedAttributeType(schemaType.getType())) { - objValues.add(value.getValue()); + for (PlainAttrValue value : values) { + if (FrameworkUtil.isSupportedAttributeType(schemaType.getType())) { + objValues.add(value.getValue()); + } else { + PlainSchema plainSchema = intAttrName.getSchema() instanceof final PlainSchema schema + ? schema + : null; + if (plainSchema == null || plainSchema.getType() != schemaType) { + objValues.add(value.getValueAsString(schemaType)); } else { - PlainSchema plainSchema = intAttrName.getSchema() instanceof final PlainSchema schema - ? schema - : null; - if (plainSchema == null || plainSchema.getType() != schemaType) { - objValues.add(value.getValueAsString(schemaType)); - } else { - objValues.add(value.getValueAsString(plainSchema)); - } + objValues.add(value.getValueAsString(plainSchema)); } } + } - if (item.isConnObjectKey()) { - result = Pair.of(objValues.isEmpty() ? null : objValues.getFirst().toString(), null); - } else if (item.isPassword() && any instanceof User) { - result = getPasswordAttrValue(passwordAccountGetter.apply((User) any), password). - map(passwordAttrValue -> Pair.of( - (String) null, AttributeBuilder.buildPassword(passwordAttrValue.toCharArray()))). - orElse(null); - } else { - result = Pair.of(null, objValues.isEmpty() - ? AttributeBuilder.build(item.getExtAttrName()) - : AttributeBuilder.build(item.getExtAttrName(), objValues)); - } + Pair result; + if (item.isConnObjectKey()) { + result = Pair.of(objValues.isEmpty() ? null : objValues.getFirst().toString(), null); + } else if (item.isPassword() && any instanceof User) { + result = getPasswordAttrValue(passwordAccountGetter.apply((User) any), password). + map(passwordAttrValue -> Pair.of( + (String) null, AttributeBuilder.buildPassword(passwordAttrValue.toCharArray()))). + orElse(null); + } else { + result = Pair.of(null, objValues.isEmpty() + ? AttributeBuilder.build(item.getExtAttrName()) + : AttributeBuilder.build(item.getExtAttrName(), objValues)); } return result; @@ -597,9 +576,6 @@ public Pair prepareAttr( AttrSchemaType schemaType = intAttrName.getSchema() instanceof PlainSchema ? intAttrName.getSchema().getType() : AttrSchemaType.String; - boolean readOnlyVirSchema = intAttrName.getSchema() instanceof VirSchema - ? intAttrName.getSchema().isReadonly() - : false; Pair> intValues = getIntValues( resource, item, intAttrName, schemaType, realm); @@ -616,34 +592,30 @@ public Pair prepareAttr( * Values {}""", item, intAttrName.getSchema(), schemaType.getType().getName(), schemaType, values); - Pair result; - if (readOnlyVirSchema) { - result = null; - } else { - List objValues = new ArrayList<>(); + List objValues = new ArrayList<>(); - for (PlainAttrValue value : values) { - if (FrameworkUtil.isSupportedAttributeType(schemaType.getType())) { - objValues.add(value.getValue()); + for (PlainAttrValue value : values) { + if (FrameworkUtil.isSupportedAttributeType(schemaType.getType())) { + objValues.add(value.getValue()); + } else { + PlainSchema plainSchema = intAttrName.getSchema() instanceof final PlainSchema schema + ? schema + : null; + if (plainSchema == null || plainSchema.getType() != schemaType) { + objValues.add(value.getValueAsString(schemaType)); } else { - PlainSchema plainSchema = intAttrName.getSchema() instanceof final PlainSchema schema - ? schema - : null; - if (plainSchema == null || plainSchema.getType() != schemaType) { - objValues.add(value.getValueAsString(schemaType)); - } else { - objValues.add(value.getValueAsString(plainSchema)); - } + objValues.add(value.getValueAsString(plainSchema)); } } + } - if (item.isConnObjectKey()) { - result = Pair.of(objValues.isEmpty() ? null : objValues.getFirst().toString(), null); - } else { - result = Pair.of(null, objValues.isEmpty() - ? AttributeBuilder.build(item.getExtAttrName()) - : AttributeBuilder.build(item.getExtAttrName(), objValues)); - } + Pair result; + if (item.isConnObjectKey()) { + result = Pair.of(objValues.isEmpty() ? null : objValues.getFirst().toString(), null); + } else { + result = Pair.of(null, objValues.isEmpty() + ? AttributeBuilder.build(item.getExtAttrName()) + : AttributeBuilder.build(item.getExtAttrName(), objValues)); } return result; @@ -844,26 +816,6 @@ public Pair> getIntValues( } } - case VIRTUAL -> { - // virtual attributes don't get transformed - transform = false; - - VirAttrCacheKey cacheKey = VirAttrCacheKey.of( - ref.getType().getKey(), ref.getKey(), intAttrName.getSchema().getKey()); - virAttrCache.remove(cacheKey); - LOG.debug("Evicted from cache: {}", cacheKey); - - VirSchema virSchema = (VirSchema) intAttrName.getSchema(); - List virValues = membership == null - ? virAttrHandler.getValues(ref, virSchema) - : virAttrHandler.getValues(ref, membership, virSchema); - virValues.forEach(virValue -> { - PlainAttrValue attrValue = new PlainAttrValue(); - attrValue.setStringValue(virValue); - values.add(attrValue); - }); - } - default -> { } } @@ -1186,27 +1138,6 @@ public void setIntValues(final Item item, final Attribute attr, final AnyTO anyT } } - case VIRTUAL -> { - Attr attrTO = new Attr(); - attrTO.setSchema(intAttrName.getSchema().getKey()); - // virtual attributes don't get transformed, iterate over original attr.getValue() - if (attr.getValue() != null && !attr.getValue().isEmpty()) { - attr.getValue().stream(). - filter(Objects::nonNull). - forEachOrdered(value -> attrTO.getValues().add(value.toString())); - } - if (groupableTO == null || group == null) { - anyTO.getVirAttrs().add(attrTO); - } else { - MembershipTO membership = groupableTO.getMembership(group.getKey()).orElseGet(() -> { - MembershipTO newMemb = new MembershipTO.Builder(group.getKey()).build(); - groupableTO.getMemberships().add(newMemb); - return newMemb; - }); - membership.getVirAttrs().add(attrTO); - } - } - default -> { } } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java index cf848f18b35..dedba380450 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java @@ -41,7 +41,6 @@ import org.apache.syncope.core.provisioning.api.PropagationByResource; import org.apache.syncope.core.provisioning.api.UserProvisioningManager; import org.apache.syncope.core.provisioning.api.UserWorkflowResult; -import org.apache.syncope.core.provisioning.api.VirAttrHandler; import org.apache.syncope.core.provisioning.api.propagation.PropagationManager; import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter; import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor; @@ -65,20 +64,16 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager { protected final UserDAO userDAO; - protected final VirAttrHandler virtAttrHandler; - public DefaultUserProvisioningManager( final UserWorkflowAdapter uwfAdapter, final PropagationManager propagationManager, final PropagationTaskExecutor taskExecutor, - final UserDAO userDAO, - final VirAttrHandler virtAttrHandler) { + final UserDAO userDAO) { this.uwfAdapter = uwfAdapter; this.propagationManager = propagationManager; this.taskExecutor = taskExecutor; this.userDAO = userDAO; - this.virtAttrHandler = virtAttrHandler; } @Override @@ -108,7 +103,6 @@ public Pair> create( created.getResult().getRight(), created.getPropByRes(), created.getPropByLinkedAccount(), - userCR.getVirAttrs(), excludedResources); PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, creator); @@ -188,8 +182,8 @@ public Pair> update( propagationManager.getUserUpdateTasks( updated, updated.getResult().getLeft().getPassword() != null - ? updated.getResult().getLeft().getPassword().getResources() - : List.of(), + ? updated.getResult().getLeft().getPassword().getResources() + : List.of(), excludedResources), beforeAttrs); PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, updater); @@ -296,7 +290,6 @@ protected List propagateStatus( statusR.getType() != StatusRType.SUSPEND, propByRes, null, - null, null); PropagationReporter propagationReporter = taskExecutor.execute(taskInfos, nullPriorityAsync, updater); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultVirAttrHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultVirAttrHandler.java deleted file mode 100644 index c5bde775f2e..00000000000 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultVirAttrHandler.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.provisioning.java; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Stream; -import javax.cache.Cache; -import org.apache.commons.lang3.tuple.Pair; -import org.apache.syncope.common.lib.to.Item; -import org.apache.syncope.common.lib.to.Provision; -import org.apache.syncope.core.persistence.api.dao.AllowedSchemas; -import org.apache.syncope.core.persistence.api.entity.Any; -import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; -import org.apache.syncope.core.persistence.api.entity.ExternalResource; -import org.apache.syncope.core.persistence.api.entity.Membership; -import org.apache.syncope.core.persistence.api.entity.VirSchema; -import org.apache.syncope.core.provisioning.api.ConnectorManager; -import org.apache.syncope.core.provisioning.api.VirAttrHandler; -import org.apache.syncope.core.provisioning.java.cache.VirAttrCacheKey; -import org.apache.syncope.core.provisioning.java.cache.VirAttrCacheValue; -import org.apache.syncope.core.provisioning.java.pushpull.OutboundMatcher; -import org.identityconnectors.framework.common.objects.Attribute; -import org.identityconnectors.framework.common.objects.ConnectorObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.transaction.annotation.Transactional; - -@Transactional(readOnly = true) -public class DefaultVirAttrHandler implements VirAttrHandler { - - protected static final Logger LOG = LoggerFactory.getLogger(VirAttrHandler.class); - - protected final ConnectorManager connectorManager; - - protected final Cache virAttrCache; - - protected final OutboundMatcher outboundMatcher; - - protected final AnyUtilsFactory anyUtilsFactory; - - public DefaultVirAttrHandler( - final ConnectorManager connectorManager, - final Cache virAttrCache, - final OutboundMatcher outboundMatcher, - final AnyUtilsFactory anyUtilsFactory) { - - this.connectorManager = connectorManager; - this.virAttrCache = virAttrCache; - this.outboundMatcher = outboundMatcher; - this.anyUtilsFactory = anyUtilsFactory; - } - - @Override - public void setValues(final Any any, final ConnectorObject connObj) { - if (any == null) { - LOG.debug("Null any passed, ignoring"); - return; - } - - AllowedSchemas schemas = - anyUtilsFactory.getInstance(any).dao().findAllowedSchemas(any, VirSchema.class); - Stream.concat( - schemas.getForSelf().stream(), - schemas.getForMemberships().values().stream().flatMap(Set::stream)).forEach(schema -> { - - VirAttrCacheKey cacheKey = VirAttrCacheKey.of(any.getType().getKey(), any.getKey(), schema.getKey()); - - Optional.ofNullable(connObj.getAttributeByName(schema.getExtAttrName())).ifPresentOrElse( - attr -> { - VirAttrCacheValue cacheValue = VirAttrCacheValue.of(attr.getValue()); - virAttrCache.put(cacheKey, cacheValue); - LOG.debug("Set in cache: {}={}", cacheKey, cacheValue); - }, - () -> { - virAttrCache.remove(cacheKey); - LOG.debug("Evicted from cache: {}", cacheKey); - }); - }); - } - - protected Map> getValues(final Any any, final Set schemas) { - Set resources = anyUtilsFactory.getInstance(any).getAllResources(any); - - Map> result = new HashMap<>(); - - Map, Set> toRead = new HashMap<>(); - - schemas.stream().filter(schema -> resources.contains(schema.getResource())).forEach(schema -> { - VirAttrCacheKey cacheKey = VirAttrCacheKey.of(any.getType().getKey(), any.getKey(), schema.getKey()); - VirAttrCacheValue cacheValue = virAttrCache.get(cacheKey); - - if (cacheValue != null) { - LOG.debug("Found in cache: {}={}", cacheKey, cacheValue); - result.put(schema, cacheValue.values()); - } else if (schema.getAnyType().equals(any.getType())) { - schema.getResource().getProvisionByAnyType(any.getType().getKey()). - ifPresent(provision -> toRead.computeIfAbsent( - Pair.of(schema.getResource(), provision), k -> new HashSet<>()).add(schema)); - } - }); - - toRead.forEach((pair, schemasToRead) -> { - LOG.debug("About to read from {}: {}", pair, schemasToRead); - - outboundMatcher.match( - connectorManager.getConnector(pair.getLeft()), - any, - pair.getLeft(), - pair.getRight(), - Optional.empty(), - schemasToRead.stream().map(VirSchema::asLinkingMappingItem).toArray(Item[]::new)). - forEach(connObj -> schemasToRead.forEach(schema -> { - - Attribute attr = connObj.getAttributeByName(schema.getExtAttrName()); - if (attr != null) { - VirAttrCacheKey cacheKey = - VirAttrCacheKey.of(any.getType().getKey(), any.getKey(), schema.getKey()); - VirAttrCacheValue cacheValue = VirAttrCacheValue.of(attr.getValue()); - virAttrCache.put(cacheKey, cacheValue); - LOG.debug("Set in cache: {}={}", cacheKey, cacheValue); - - result.put(schema, cacheValue.values()); - } - })); - }); - - return result; - } - - @Override - public List getValues(final Any any, final VirSchema schema) { - if (!anyUtilsFactory.getInstance(any).dao(). - findAllowedSchemas(any, VirSchema.class).forSelfContains(schema)) { - - LOG.debug("{} not allowed for {}", schema, any); - return List.of(); - } - - List result = getValues(any, Set.of(schema)).get(schema); - return result == null ? List.of() : result; - } - - @Override - public List getValues(final Any any, final Membership membership, final VirSchema schema) { - if (!anyUtilsFactory.getInstance(any).dao(). - findAllowedSchemas(any, VirSchema.class).getForMembership(membership.getRightEnd()).contains(schema)) { - - LOG.debug("{} not allowed for {}", schema, any); - return List.of(); - } - - List result = getValues(any, Set.of(schema)).get(schema); - return result == null ? List.of() : result; - } - - @Override - public Map> getValues(final Any any) { - return getValues( - any, - anyUtilsFactory.getInstance(any).dao().findAllowedSchemas(any, VirSchema.class).getForSelf()); - } - - @Override - public Map> getValues(final Any any, final Membership membership) { - return getValues( - any, - anyUtilsFactory.getInstance(any).dao().findAllowedSchemas(any, VirSchema.class). - getForMembership(membership.getRightEnd())); - } -} diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java index 4aaed30505d..580783622c7 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java @@ -20,11 +20,6 @@ import java.util.List; import java.util.concurrent.Executor; -import javax.cache.Cache; -import javax.cache.CacheManager; -import javax.cache.configuration.MutableConfiguration; -import javax.cache.expiry.CreatedExpiryPolicy; -import javax.cache.expiry.Duration; import org.apache.syncope.common.keymaster.client.api.ConfParamOps; import org.apache.syncope.core.persistence.api.DomainHolder; import org.apache.syncope.core.persistence.api.EncryptorManager; @@ -60,7 +55,6 @@ import org.apache.syncope.core.persistence.api.dao.TaskDAO; import org.apache.syncope.core.persistence.api.dao.TaskExecDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.dao.WAConfigDAO; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.EntityFactory; @@ -77,7 +71,6 @@ import org.apache.syncope.core.provisioning.api.IntAttrNameParser; import org.apache.syncope.core.provisioning.api.MappingManager; import org.apache.syncope.core.provisioning.api.UserProvisioningManager; -import org.apache.syncope.core.provisioning.api.VirAttrHandler; import org.apache.syncope.core.provisioning.api.data.AccessTokenDataBinder; import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder; import org.apache.syncope.core.provisioning.api.data.AnyTypeClassDataBinder; @@ -116,8 +109,6 @@ import org.apache.syncope.core.provisioning.api.notification.NotificationManager; import org.apache.syncope.core.provisioning.api.propagation.PropagationManager; import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor; -import org.apache.syncope.core.provisioning.java.cache.VirAttrCacheKey; -import org.apache.syncope.core.provisioning.java.cache.VirAttrCacheValue; import org.apache.syncope.core.provisioning.java.data.AccessTokenDataBinderImpl; import org.apache.syncope.core.provisioning.java.data.AnyObjectDataBinderImpl; import org.apache.syncope.core.provisioning.java.data.AnyTypeClassDataBinderImpl; @@ -180,7 +171,6 @@ import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Primary; import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.mail.javamail.JavaMailSender; @@ -344,9 +334,7 @@ public InboundMatcher inboundMatcher( final AnySearchDAO anySearchDAO, final RealmDAO realmDAO, final RealmSearchDAO realmSearchDAO, - final VirSchemaDAO virSchemaDAO, final ImplementationDAO implementationDAO, - final VirAttrHandler virAttrHandler, final IntAttrNameParser intAttrNameParser) { return new InboundMatcher( @@ -356,9 +344,7 @@ public InboundMatcher inboundMatcher( anySearchDAO, realmDAO, realmSearchDAO, - virSchemaDAO, implementationDAO, - virAttrHandler, intAttrNameParser, anyUtilsFactory); } @@ -368,11 +354,9 @@ public InboundMatcher inboundMatcher( public OutboundMatcher outboundMatcher( final AnyUtilsFactory anyUtilsFactory, final MappingManager mappingManager, - final UserDAO userDAO, - final VirSchemaDAO virSchemaDAO, - final VirAttrHandler virAttrHandler) { + final UserDAO userDAO) { - return new OutboundMatcher(mappingManager, userDAO, anyUtilsFactory, virSchemaDAO, virAttrHandler); + return new OutboundMatcher(mappingManager, userDAO, anyUtilsFactory); } @ConditionalOnMissingBean @@ -381,17 +365,6 @@ public DerAttrHandler derAttrHandler(final AnyUtilsFactory anyUtilsFactory) { return new DefaultDerAttrHandler(anyUtilsFactory); } - @ConditionalOnMissingBean - @Bean - public VirAttrHandler virAttrHandler( - final AnyUtilsFactory anyUtilsFactory, - final ConnectorManager connectorManager, - final Cache virAttrCache, - @Lazy final OutboundMatcher outboundMatcher) { - - return new DefaultVirAttrHandler(connectorManager, virAttrCache, outboundMatcher, anyUtilsFactory); - } - @ConditionalOnMissingBean @Bean public MappingManager mappingManager( @@ -403,8 +376,6 @@ public MappingManager mappingManager( final RealmSearchDAO realmSearchDAO, final ImplementationDAO implementationDAO, final DerAttrHandler derAttrHandler, - final VirAttrHandler virAttrHandler, - final Cache virAttrCache, final IntAttrNameParser intAttrNameParser, final EncryptorManager encryptorManager) { @@ -417,8 +388,6 @@ public MappingManager mappingManager( realmSearchDAO, implementationDAO, derAttrHandler, - virAttrHandler, - virAttrCache, intAttrNameParser, encryptorManager); } @@ -457,14 +426,12 @@ public ConnObjectUtils connObjectUtils( public PropagationManager propagationManager( final EntityFactory entityFactory, final AnyUtilsFactory anyUtilsFactory, - final VirSchemaDAO virSchemaDAO, final ExternalResourceDAO resourceDAO, final ConnObjectUtils connObjectUtils, final MappingManager mappingManager, final DerAttrHandler derAttrHandler) { return new DefaultPropagationManager( - virSchemaDAO, resourceDAO, entityFactory, connObjectUtils, @@ -485,10 +452,9 @@ public IntAttrNameParser intAttrNameParser( final AnyUtilsFactory anyUtilsFactory, final RealmUtils realmUtils, final PlainSchemaDAO plainSchemaDAO, - final DerSchemaDAO derSchemaDAO, - final VirSchemaDAO virSchemaDAO) { + final DerSchemaDAO derSchemaDAO) { - return new IntAttrNameParser(plainSchemaDAO, derSchemaDAO, virSchemaDAO, anyUtilsFactory, realmUtils); + return new IntAttrNameParser(plainSchemaDAO, derSchemaDAO, anyUtilsFactory, realmUtils); } @ConditionalOnMissingBean @@ -533,15 +499,13 @@ public UserProvisioningManager userProvisioningManager( final UserWorkflowAdapter uwfAdapter, final PropagationManager propagationManager, final PropagationTaskExecutor taskExecutor, - final UserDAO userDAO, - final VirAttrHandler virtAttrHandler) { + final UserDAO userDAO) { return new DefaultUserProvisioningManager( uwfAdapter, propagationManager, taskExecutor, - userDAO, - virtAttrHandler); + userDAO); } @ConditionalOnMissingBean @@ -551,16 +515,14 @@ public GroupProvisioningManager groupProvisioningManager( final PropagationManager propagationManager, final PropagationTaskExecutor taskExecutor, final GroupDataBinder groupDataBinder, - final GroupDAO groupDAO, - final VirAttrHandler virtAttrHandler) { + final GroupDAO groupDAO) { return new DefaultGroupProvisioningManager( gwfAdapter, propagationManager, taskExecutor, groupDataBinder, - groupDAO, - virtAttrHandler); + groupDAO); } @ConditionalOnMissingBean @@ -569,26 +531,13 @@ public AnyObjectProvisioningManager anyObjectProvisioningManager( final AnyObjectWorkflowAdapter awfAdapter, final PropagationManager propagationManager, final PropagationTaskExecutor taskExecutor, - final AnyObjectDAO anyObjectDAO, - final VirAttrHandler virtAttrHandler) { + final AnyObjectDAO anyObjectDAO) { return new DefaultAnyObjectProvisioningManager( awfAdapter, propagationManager, taskExecutor, - anyObjectDAO, - virtAttrHandler); - } - - @ConditionalOnMissingBean(name = VirAttrHandler.CACHE) - @Bean(name = VirAttrHandler.CACHE) - public Cache virAttrCache(final CacheManager cacheManager) { - return cacheManager.createCache(VirAttrHandler.CACHE, - new MutableConfiguration(). - setTypes(VirAttrCacheKey.class, VirAttrCacheValue.class). - setStoreByValue(false). - setReadThrough(true). - setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(Duration.FIVE_MINUTES))); + anyObjectDAO); } @ConditionalOnMissingBean @@ -597,7 +546,6 @@ public NotificationManager notificationManager( final EntityFactory entityFactory, final SearchCondVisitor searchCondVisitor, final DerSchemaDAO derSchemaDAO, - final VirSchemaDAO virSchemaDAO, final NotificationDAO notificationDAO, final AnyObjectDAO anyObjectDAO, final UserDAO userDAO, @@ -610,12 +558,10 @@ public NotificationManager notificationManager( final AnyObjectDataBinder anyObjectDataBinder, final ConfParamOps confParamOps, final DerAttrHandler derAttrHandler, - final VirAttrHandler virAttrHandler, final IntAttrNameParser intAttrNameParser) { return new DefaultNotificationManager( derSchemaDAO, - virSchemaDAO, notificationDAO, anyObjectDAO, userDAO, @@ -624,7 +570,6 @@ public NotificationManager notificationManager( anyMatchDAO, taskDAO, derAttrHandler, - virAttrHandler, userDataBinder, groupDataBinder, anyObjectDataBinder, @@ -748,7 +693,6 @@ public AnyObjectDataBinder anyObjectDataBinder( final ExternalResourceDAO resourceDAO, final RelationshipTypeDAO relationshipTypeDAO, final DerAttrHandler derAttrHandler, - final VirAttrHandler virAttrHandler, final MappingManager mappingManager, final IntAttrNameParser intAttrNameParser, final OutboundMatcher outboundMatcher, @@ -767,7 +711,6 @@ public AnyObjectDataBinder anyObjectDataBinder( entityFactory, anyUtilsFactory, derAttrHandler, - virAttrHandler, mappingManager, intAttrNameParser, outboundMatcher, @@ -780,10 +723,9 @@ public AnyTypeClassDataBinder anyTypeClassDataBinder( final EntityFactory entityFactory, final PlainSchemaDAO plainSchemaDAO, final DerSchemaDAO derSchemaDAO, - final VirSchemaDAO virSchemaDAO, final AnyTypeDAO anyTypeDAO) { - return new AnyTypeClassDataBinderImpl(plainSchemaDAO, derSchemaDAO, virSchemaDAO, anyTypeDAO, entityFactory); + return new AnyTypeClassDataBinderImpl(plainSchemaDAO, derSchemaDAO, anyTypeDAO, entityFactory); } @ConditionalOnMissingBean @@ -897,7 +839,6 @@ public GroupDataBinder groupDataBinder( final ExternalResourceDAO resourceDAO, final RelationshipTypeDAO relationshipTypeDAO, final DerAttrHandler derAttrHandler, - final VirAttrHandler virAttrHandler, final MappingManager mappingManager, final IntAttrNameParser intAttrNameParser, final OutboundMatcher outboundMatcher, @@ -916,7 +857,6 @@ public GroupDataBinder groupDataBinder( entityFactory, anyUtilsFactory, derAttrHandler, - virAttrHandler, mappingManager, intAttrNameParser, outboundMatcher, @@ -1029,7 +969,6 @@ public ResourceDataBinder resourceDataBinder( final AnyTypeDAO anyTypeDAO, final ConnInstanceDAO connInstanceDAO, final PolicyDAO policyDAO, - final VirSchemaDAO virSchemaDAO, final AnyTypeClassDAO anyTypeClassDAO, final ImplementationDAO implementationDAO, final PlainSchemaDAO plainSchemaDAO, @@ -1040,7 +979,6 @@ public ResourceDataBinder resourceDataBinder( anyTypeDAO, connInstanceDAO, policyDAO, - virSchemaDAO, anyTypeClassDAO, implementationDAO, plainSchemaDAO, @@ -1092,7 +1030,6 @@ public SchemaDataBinder schemaDataBinder( final AnyTypeClassDAO anyTypeClassDAO, final PlainSchemaDAO plainSchemaDAO, final DerSchemaDAO derSchemaDAO, - final VirSchemaDAO virSchemaDAO, final ExternalResourceDAO resourceDAO, final AnyTypeDAO anyTypeDAO, final ImplementationDAO implementationDAO) { @@ -1101,7 +1038,6 @@ public SchemaDataBinder schemaDataBinder( anyTypeClassDAO, plainSchemaDAO, derSchemaDAO, - virSchemaDAO, resourceDAO, anyTypeDAO, implementationDAO, @@ -1154,7 +1090,6 @@ public UserDataBinder userDataBinder( final ExternalResourceDAO resourceDAO, final RelationshipTypeDAO relationshipTypeDAO, final DerAttrHandler derAttrHandler, - final VirAttrHandler virAttrHandler, final MappingManager mappingManager, final IntAttrNameParser intAttrNameParser, final OutboundMatcher outboundMatcher, @@ -1178,7 +1113,6 @@ public UserDataBinder userDataBinder( entityFactory, anyUtilsFactory, derAttrHandler, - virAttrHandler, mappingManager, intAttrNameParser, outboundMatcher, diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/VirAttrCacheKey.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/VirAttrCacheKey.java deleted file mode 100644 index 6f95226a2c8..00000000000 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/VirAttrCacheKey.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.provisioning.java.cache; - -import org.apache.syncope.core.spring.security.AuthContextUtils; - -public record VirAttrCacheKey(String domain, String anyType, String any, String schema) { - - public static VirAttrCacheKey of(final String anyType, final String any, final String schema) { - return new VirAttrCacheKey(AuthContextUtils.getDomain(), anyType, any, schema); - } -} diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/VirAttrCacheValue.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/VirAttrCacheValue.java deleted file mode 100644 index 2f421b1fc51..00000000000 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/VirAttrCacheValue.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.provisioning.java.cache; - -import java.util.Collection; -import java.util.List; -import java.util.Optional; - -public record VirAttrCacheValue(List values) { - - public static VirAttrCacheValue of(final Collection values) { - return new VirAttrCacheValue(Optional.ofNullable(values). - map(v -> v.stream().map(Object::toString).toList()). - orElseGet(List::of)); - } -} diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyDataBinder.java index ff1140aee13..1ddf57dcef9 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyDataBinder.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyDataBinder.java @@ -68,7 +68,6 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.user.User; @@ -79,7 +78,6 @@ import org.apache.syncope.core.provisioning.api.MappingManager; import org.apache.syncope.core.provisioning.api.PlainAttrGetter; import org.apache.syncope.core.provisioning.api.PropagationByResource; -import org.apache.syncope.core.provisioning.api.VirAttrHandler; import org.apache.syncope.core.provisioning.api.jexl.JexlUtils; import org.apache.syncope.core.provisioning.java.pushpull.OutboundMatcher; import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils; @@ -98,7 +96,6 @@ protected static void fillTO( final Collection auxClasses, final Collection plainAttrs, final Map derAttrs, - final Map> virAttrs, final Collection resources) { anyTO.setRealm(realmFullPath); @@ -111,9 +108,6 @@ protected static void fillTO( derAttrs.forEach((schema, value) -> anyTO.getDerAttrs(). add(new Attr.Builder(schema.getKey()).value(value).build())); - virAttrs.forEach((schema, values) -> anyTO.getVirAttrs(). - add(new Attr.Builder(schema.getKey()).values(values).build())); - anyTO.getResources().addAll(resources.stream().map(ExternalResource::getKey).collect(Collectors.toSet())); } @@ -136,7 +130,6 @@ protected static RelationshipTO getRelationshipTO( protected static MembershipTO getMembershipTO( final Collection plainAttrs, final Map derAttrs, - final Map> virAttrs, final Membership membership) { MembershipTO membershipTO = new MembershipTO.Builder(membership.getRightEnd().getKey()). @@ -148,9 +141,6 @@ protected static MembershipTO getMembershipTO( derAttrs.forEach((schema, value) -> membershipTO.getDerAttrs(). add(new Attr.Builder(schema.getKey()).value(value).build())); - virAttrs.forEach((schema, values) -> membershipTO.getVirAttrs(). - add(new Attr.Builder(schema.getKey()).values(values).build())); - return membershipTO; } @@ -174,8 +164,6 @@ protected static MembershipTO getMembershipTO( protected final AnyUtilsFactory anyUtilsFactory; - protected final VirAttrHandler virAttrHandler; - protected final OutboundMatcher outboundMatcher; protected AnyDataBinder( @@ -191,7 +179,6 @@ protected AnyDataBinder( final EntityFactory entityFactory, final AnyUtilsFactory anyUtilsFactory, final DerAttrHandler derAttrHandler, - final VirAttrHandler virAttrHandler, final MappingManager mappingManager, final IntAttrNameParser intAttrNameParser, final OutboundMatcher outboundMatcher, @@ -208,7 +195,6 @@ protected AnyDataBinder( this.relationshipTypeDAO = relationshipTypeDAO; this.entityFactory = entityFactory; this.anyUtilsFactory = anyUtilsFactory; - this.virAttrHandler = virAttrHandler; this.outboundMatcher = outboundMatcher; } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java index 5b43c184862..d9e00562098 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java @@ -64,7 +64,6 @@ import org.apache.syncope.core.provisioning.api.IntAttrNameParser; import org.apache.syncope.core.provisioning.api.MappingManager; import org.apache.syncope.core.provisioning.api.PropagationByResource; -import org.apache.syncope.core.provisioning.api.VirAttrHandler; import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder; import org.apache.syncope.core.provisioning.java.pushpull.OutboundMatcher; import org.springframework.transaction.annotation.Transactional; @@ -85,7 +84,6 @@ public AnyObjectDataBinderImpl( final EntityFactory entityFactory, final AnyUtilsFactory anyUtilsFactory, final DerAttrHandler derAttrHandler, - final VirAttrHandler virAttrHandler, final MappingManager mappingManager, final IntAttrNameParser intAttrNameParser, final OutboundMatcher outboundMatcher, @@ -103,7 +101,6 @@ public AnyObjectDataBinderImpl( entityFactory, anyUtilsFactory, derAttrHandler, - virAttrHandler, mappingManager, intAttrNameParser, outboundMatcher, @@ -138,7 +135,6 @@ public AnyObjectTO getAnyObjectTO(final AnyObject anyObject, final boolean detai anyObject.getAuxClasses(), anyObject.getPlainAttrs(), derAttrHandler.getValues(anyObject), - details ? virAttrHandler.getValues(anyObject) : Map.of(), anyObjectDAO.findAllResources(anyObject)); // dynamic realms @@ -163,7 +159,6 @@ public AnyObjectTO getAnyObjectTO(final AnyObject anyObject, final boolean detai anyObject.getMemberships().stream().map(membership -> getMembershipTO( anyObject.getPlainAttrs(membership), derAttrHandler.getValues(anyObject, membership), - virAttrHandler.getValues(anyObject, membership), membership)).toList()); // dynamic memberships diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeClassDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeClassDataBinderImpl.java index 0738ac36443..badc2b027e6 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeClassDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeClassDataBinderImpl.java @@ -23,13 +23,11 @@ import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO; import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.DerSchema; import org.apache.syncope.core.persistence.api.entity.EntityFactory; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.provisioning.api.data.AnyTypeClassDataBinder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,8 +40,6 @@ public class AnyTypeClassDataBinderImpl implements AnyTypeClassDataBinder { protected final DerSchemaDAO derSchemaDAO; - protected final VirSchemaDAO virSchemaDAO; - protected final AnyTypeDAO anyTypeDAO; protected final EntityFactory entityFactory; @@ -51,13 +47,11 @@ public class AnyTypeClassDataBinderImpl implements AnyTypeClassDataBinder { public AnyTypeClassDataBinderImpl( final PlainSchemaDAO plainSchemaDAO, final DerSchemaDAO derSchemaDAO, - final VirSchemaDAO virSchemaDAO, final AnyTypeDAO anyTypeDAO, final EntityFactory entityFactory) { this.plainSchemaDAO = plainSchemaDAO; this.derSchemaDAO = derSchemaDAO; - this.virSchemaDAO = virSchemaDAO; this.anyTypeDAO = anyTypeDAO; this.entityFactory = entityFactory; } @@ -108,23 +102,6 @@ public void update(final AnyTypeClass anyTypeClass, final AnyTypeClassTO anyType derSchemaDAO.save(schema); } }); - - virSchemaDAO.findByAnyTypeClasses(List.of(anyTypeClass)).forEach(schema -> { - schema.setAnyTypeClass(null); - virSchemaDAO.save(schema); - }); - - anyTypeClass.getVirSchemas().clear(); - anyTypeClassTO.getVirSchemas().forEach(key -> { - VirSchema schema = virSchemaDAO.findById(key).orElse(null); - if (schema == null || schema.getAnyTypeClass() != null) { - LOG.debug("Invalid or already in use: {} {}, ignoring...", VirSchema.class.getSimpleName(), key); - } else { - anyTypeClass.add(schema); - schema.setAnyTypeClass(anyTypeClass); - virSchemaDAO.save(schema); - } - }); } @Override @@ -141,8 +118,6 @@ public AnyTypeClassTO getAnyTypeClassTO(final AnyTypeClass anyTypeClass) { anyTypeClass.getPlainSchemas().stream().map(PlainSchema::getKey).toList()); anyTypeClassTO.getDerSchemas().addAll( anyTypeClass.getDerSchemas().stream().map(DerSchema::getKey).toList()); - anyTypeClassTO.getVirSchemas().addAll( - anyTypeClass.getVirSchemas().stream().map(VirSchema::getKey).toList()); return anyTypeClassTO; } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java index 0e144e7f9fe..e8c11d92ce6 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java @@ -73,7 +73,6 @@ import org.apache.syncope.core.provisioning.api.IntAttrNameParser; import org.apache.syncope.core.provisioning.api.MappingManager; import org.apache.syncope.core.provisioning.api.PropagationByResource; -import org.apache.syncope.core.provisioning.api.VirAttrHandler; import org.apache.syncope.core.provisioning.api.data.GroupDataBinder; import org.apache.syncope.core.provisioning.java.pushpull.OutboundMatcher; import org.springframework.transaction.annotation.Transactional; @@ -96,7 +95,6 @@ public GroupDataBinderImpl( final EntityFactory entityFactory, final AnyUtilsFactory anyUtilsFactory, final DerAttrHandler derAttrHandler, - final VirAttrHandler virAttrHandler, final MappingManager mappingManager, final IntAttrNameParser intAttrNameParser, final OutboundMatcher outboundMatcher, @@ -115,7 +113,6 @@ public GroupDataBinderImpl( entityFactory, anyUtilsFactory, derAttrHandler, - virAttrHandler, mappingManager, intAttrNameParser, outboundMatcher, @@ -505,7 +502,6 @@ public GroupTO getGroupTO(final Group group, final boolean details) { group.getAuxClasses(), group.getPlainAttrs(), derAttrHandler.getValues(group), - details ? virAttrHandler.getValues(group) : Map.of(), group.getResources()); // dynamic realms diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java index 546a4f16153..3e5ee710973 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/JEXLItemTransformerImpl.java @@ -178,7 +178,6 @@ public List beforePull( if (entityTO instanceof AnyTO anyTO) { JexlUtils.addAttrsToContext(anyTO.getPlainAttrs(), jexlContext); JexlUtils.addAttrsToContext(anyTO.getDerAttrs(), jexlContext); - JexlUtils.addAttrsToContext(anyTO.getVirAttrs(), jexlContext); } newValues.add(JexlUtils.evaluateExpr(pullJEXL, jexlContext)); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java index bc74dbba623..3f2dc2c94db 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java @@ -44,7 +44,6 @@ import org.apache.syncope.core.persistence.api.dao.NotFoundException; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.dao.PolicyDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.ConnInstance; @@ -53,7 +52,6 @@ import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.Implementation; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy; import org.apache.syncope.core.persistence.api.entity.policy.InboundPolicy; import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy; @@ -78,8 +76,6 @@ public class ResourceDataBinderImpl implements ResourceDataBinder { protected final PolicyDAO policyDAO; - protected final VirSchemaDAO virSchemaDAO; - protected final AnyTypeClassDAO anyTypeClassDAO; protected final ImplementationDAO implementationDAO; @@ -96,7 +92,6 @@ public ResourceDataBinderImpl( final AnyTypeDAO anyTypeDAO, final ConnInstanceDAO connInstanceDAO, final PolicyDAO policyDAO, - final VirSchemaDAO virSchemaDAO, final AnyTypeClassDAO anyTypeClassDAO, final ImplementationDAO implementationDAO, final PlainSchemaDAO plainSchemaDAO, @@ -107,7 +102,6 @@ public ResourceDataBinderImpl( this.anyTypeDAO = anyTypeDAO; this.connInstanceDAO = connInstanceDAO; this.policyDAO = policyDAO; - this.virSchemaDAO = virSchemaDAO; this.anyTypeClassDAO = anyTypeClassDAO; this.implementationDAO = implementationDAO; this.plainSchemaDAO = plainSchemaDAO; @@ -146,12 +140,12 @@ public ExternalResource update(final ExternalResource resource, final ResourceTO LOG.debug("Invalid {} specified {}, ignoring...", AnyType.class.getSimpleName(), provisionTO.getAnyType()); } else { - Provision provision = resource.getProvisionByAnyType(anyType.getKey()).orElse(null); - if (provision == null) { - provision = new Provision(); - provision.setAnyType(anyType.getKey()); - resource.getProvisions().add(provision); - } + Provision provision = resource.getProvisionByAnyType(anyType.getKey()).orElseGet(() -> { + Provision p = new Provision(); + p.setAnyType(anyType.getKey()); + resource.getProvisions().add(p); + return p; + }); if (provisionTO.getObjectClass() == null) { SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidProvision); @@ -209,8 +203,6 @@ public ExternalResource update(final ExternalResource resource, final ResourceTO map(PlainSchema::getKey).toList()); allowedSchemas.getDerSchemas().addAll(anyTypeClass.getDerSchemas().stream(). map(DerSchema::getKey).toList()); - allowedSchemas.getVirSchemas().addAll(anyTypeClass.getVirSchemas().stream(). - map(VirSchema::getKey).toList()); }); populateMapping( @@ -220,16 +212,6 @@ public ExternalResource update(final ExternalResource resource, final ResourceTO anyType.getKind(), allowedSchemas); } - - if (provisionTO.getVirSchemas().isEmpty()) { - virSchemaDAO.findByResourceAndAnyType(resource.getKey(), anyType.getKey()). - forEach(virSchemaDAO::delete); - } else { - provisionTO.getVirSchemas().forEach(schemaName -> virSchemaDAO.findById(schemaName).ifPresentOrElse( - schema -> schema.setResource(resource), - () -> LOG.debug("Invalid {} specified: {}, ignoring...", - VirSchema.class.getSimpleName(), schemaName))); - } } }); @@ -237,9 +219,6 @@ public ExternalResource update(final ExternalResource resource, final ResourceTO for (Iterator itor = resource.getProvisions().iterator(); itor.hasNext();) { Provision provision = itor.next(); if (resourceTO.getProvision(provision.getAnyType()).isEmpty()) { - virSchemaDAO.findByResourceAndAnyType(resource.getKey(), provision.getAnyType()). - forEach(virSchemaDAO::delete); - itor.remove(); } } @@ -433,10 +412,6 @@ protected void populateMapping( allowed = allowedSchemas.getDerSchemas().contains(intAttrName.getSchema().getKey()); break; - case VIRTUAL: - allowed = allowedSchemas.getVirSchemas().contains(intAttrName.getSchema().getKey()); - break; - default: } } @@ -471,10 +446,6 @@ protected void populateMapping( removeIf(implementation -> !itemTO.getTransformers().contains(implementation)); if (item.isConnObjectKey()) { - if (intAttrName.getSchemaType() == SchemaType.VIRTUAL) { - invalidMapping.getElements(). - add("Virtual attributes cannot be set as ConnObjectKey"); - } if ("password".equals(intAttrName.getField())) { invalidMapping.getElements().add( "Password attributes cannot be set as ConnObjectKey"); @@ -505,18 +476,6 @@ protected void populateMapping( invalidMapping.getElements().add( "Only " + MappingPurpose.PROPAGATION.name() + " allowed for derived"); } - if (intAttrName.getSchemaType() == SchemaType.VIRTUAL) { - if (item.getPurpose() != MappingPurpose.PROPAGATION) { - invalidMapping.getElements().add( - "Only " + MappingPurpose.PROPAGATION.name() + " allowed for virtual"); - } - - VirSchema schema = virSchemaDAO.findById(item.getIntAttrName()).orElse(null); - if (schema != null && schema.getResource().equals(resource)) { - invalidMapping.getElements().add( - "No need to map virtual schema on linking resource"); - } - } if (intAttrName.getRelatedUser() != null && item.getPurpose() != MappingPurpose.PROPAGATION) { @@ -602,12 +561,6 @@ public ResourceTO getResourceTO(final ExternalResource resource) { resourceTO.getProvisions().add(provisionTO); }); - resourceTO.getProvisions(). - forEach(provision -> virSchemaDAO.findByResourceAndAnyType(resource.getKey(), provision.getAnyType()). - forEach(virSchema -> { - provision.getVirSchemas().add(virSchema.getKey()); - provision.getMapping().getLinkingItems().add(virSchema.asLinkingMappingItem()); - })); if (resource.getOrgUnit() != null) { OrgUnit orgUnit = resource.getOrgUnit(); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java index 39489825a5a..371d440bb73 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SchemaDataBinderImpl.java @@ -26,7 +26,6 @@ import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.to.DerSchemaTO; import org.apache.syncope.common.lib.to.PlainSchemaTO; -import org.apache.syncope.common.lib.to.VirSchemaTO; import org.apache.syncope.common.lib.types.ClientExceptionType; import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO; import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO; @@ -35,16 +34,12 @@ import org.apache.syncope.core.persistence.api.dao.ImplementationDAO; import org.apache.syncope.core.persistence.api.dao.NotFoundException; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; -import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.DerSchema; import org.apache.syncope.core.persistence.api.entity.EntityFactory; -import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.Implementation; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.provisioning.api.data.SchemaDataBinder; import org.apache.syncope.core.provisioning.api.jexl.JexlUtils; import org.slf4j.Logger; @@ -60,8 +55,6 @@ public class SchemaDataBinderImpl implements SchemaDataBinder { protected final DerSchemaDAO derSchemaDAO; - protected final VirSchemaDAO virSchemaDAO; - protected final ExternalResourceDAO resourceDAO; protected final AnyTypeDAO anyTypeDAO; @@ -76,7 +69,6 @@ public SchemaDataBinderImpl( final AnyTypeClassDAO anyTypeClassDAO, final PlainSchemaDAO plainSchemaDAO, final DerSchemaDAO derSchemaDAO, - final VirSchemaDAO virSchemaDAO, final ExternalResourceDAO resourceDAO, final AnyTypeDAO anyTypeDAO, final ImplementationDAO implementationDAO, @@ -86,7 +78,6 @@ public SchemaDataBinderImpl( this.anyTypeClassDAO = anyTypeClassDAO; this.plainSchemaDAO = plainSchemaDAO; this.derSchemaDAO = derSchemaDAO; - this.virSchemaDAO = virSchemaDAO; this.resourceDAO = resourceDAO; this.anyTypeDAO = anyTypeDAO; this.implementationDAO = implementationDAO; @@ -301,87 +292,4 @@ public DerSchemaTO getDerSchemaTO(final String key) { schemaTO.setAnyTypeClass(schema.getAnyTypeClass() == null ? null : schema.getAnyTypeClass().getKey()); return schemaTO; } - - // --------------- VIRTUAL ----------------- - protected VirSchema fill(final VirSchema schema, final VirSchemaTO schemaTO) { - schema.setKey(schemaTO.getKey()); - schema.setExtAttrName(schemaTO.getExtAttrName()); - schema.setReadonly(schemaTO.isReadonly()); - - schema.getLabels().clear(); - schema.getLabels().putAll(schemaTO.getLabels()); - - ExternalResource resource = resourceDAO.findById(schemaTO.getResource()).orElseThrow(() -> { - SyncopeClientException sce = SyncopeClientException.build( - ClientExceptionType.InvalidSchemaDefinition); - sce.getElements().add("Resource " + schemaTO.getResource() + " not found"); - return sce; - }); - AnyType anyType = anyTypeDAO.findById(schemaTO.getAnyType()).orElseThrow(() -> { - SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSchemaDefinition); - sce.getElements().add("AnyType " + schemaTO.getAnyType() + " not found"); - return sce; - }); - resource.getProvisionByAnyType(anyType.getKey()).orElseThrow(() -> { - SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSchemaDefinition); - sce.getElements().add("Provision for AnyType" + schemaTO.getAnyType() - + " not found in " + schemaTO.getResource()); - return sce; - }); - schema.setResource(resource); - schema.setAnyType(anyType); - - VirSchema saved = virSchemaDAO.save(schema); - - Mutable atc = new MutableObject<>(); - if (schemaTO.getAnyTypeClass() != null - && (saved.getAnyTypeClass() == null - || !schemaTO.getAnyTypeClass().equals(saved.getAnyTypeClass().getKey()))) { - - anyTypeClassDAO.findById(schemaTO.getAnyTypeClass()).ifPresentOrElse( - anyTypeClass -> { - anyTypeClass.add(saved); - saved.setAnyTypeClass(anyTypeClass); - - atc.setValue(anyTypeClass); - }, - () -> LOG.debug("Invalid {}{}, ignoring...", - AnyTypeClass.class.getSimpleName(), schemaTO.getAnyTypeClass())); - } else if (schemaTO.getAnyTypeClass() == null && saved.getAnyTypeClass() != null) { - saved.getAnyTypeClass().getVirSchemas().remove(saved); - saved.setAnyTypeClass(null); - - atc.setValue(saved.getAnyTypeClass()); - } - - VirSchema filled = virSchemaDAO.save(saved); - Optional.ofNullable(atc.getValue()).ifPresent(anyTypeClassDAO::save); - return filled; - } - - @Override - public VirSchema create(final VirSchemaTO schemaTO) { - return fill(entityFactory.newEntity(VirSchema.class), schemaTO); - } - - @Override - public VirSchema update(final VirSchemaTO schemaTO, final VirSchema schema) { - return fill(schema, schemaTO); - } - - @Override - public VirSchemaTO getVirSchemaTO(final String key) { - VirSchema schema = virSchemaDAO.findById(key). - orElseThrow(() -> new NotFoundException("VirSchema " + key)); - - VirSchemaTO schemaTO = new VirSchemaTO(); - schemaTO.setKey(schema.getKey()); - schemaTO.setExtAttrName(schema.getExtAttrName()); - schemaTO.setReadonly(schema.isReadonly()); - schemaTO.getLabels().putAll(schema.getLabels()); - schemaTO.setAnyTypeClass(schema.getAnyTypeClass() == null ? null : schema.getAnyTypeClass().getKey()); - schemaTO.setResource(schema.getResource().getKey()); - schemaTO.setAnyType(schema.getAnyType().getKey()); - return schemaTO; - } } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java index e06e8c93d9c..f182ab4c393 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java @@ -85,7 +85,6 @@ import org.apache.syncope.core.provisioning.api.IntAttrNameParser; import org.apache.syncope.core.provisioning.api.MappingManager; import org.apache.syncope.core.provisioning.api.PropagationByResource; -import org.apache.syncope.core.provisioning.api.VirAttrHandler; import org.apache.syncope.core.provisioning.api.data.UserDataBinder; import org.apache.syncope.core.provisioning.java.pushpull.OutboundMatcher; import org.apache.syncope.core.spring.security.AuthContextUtils; @@ -120,7 +119,6 @@ public UserDataBinderImpl( final EntityFactory entityFactory, final AnyUtilsFactory anyUtilsFactory, final DerAttrHandler derAttrHandler, - final VirAttrHandler virAttrHandler, final MappingManager mappingManager, final IntAttrNameParser intAttrNameParser, final OutboundMatcher outboundMatcher, @@ -144,7 +142,6 @@ public UserDataBinderImpl( entityFactory, anyUtilsFactory, derAttrHandler, - virAttrHandler, mappingManager, intAttrNameParser, outboundMatcher, @@ -759,7 +756,6 @@ public UserTO getUserTO(final User user, final boolean details) { user.getAuxClasses(), user.getPlainAttrs(), derAttrHandler.getValues(user), - details ? virAttrHandler.getValues(user) : Map.of(), userDAO.findAllResources(user)); // dynamic realms @@ -781,7 +777,6 @@ public UserTO getUserTO(final User user, final boolean details) { userTO.getMemberships().addAll(user.getMemberships().stream(). map(membership -> getMembershipTO(user.getPlainAttrs(membership), derAttrHandler.getValues(user, membership), - virAttrHandler.getValues(user, membership), membership)).toList()); // dynamic memberships diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManager.java index 35910be4903..953f98af747 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManager.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManager.java @@ -48,7 +48,6 @@ import org.apache.syncope.core.persistence.api.dao.NotificationDAO; import org.apache.syncope.core.persistence.api.dao.TaskDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.EntityFactory; @@ -65,7 +64,6 @@ import org.apache.syncope.core.provisioning.api.DerAttrHandler; import org.apache.syncope.core.provisioning.api.IntAttrName; import org.apache.syncope.core.provisioning.api.IntAttrNameParser; -import org.apache.syncope.core.provisioning.api.VirAttrHandler; import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder; import org.apache.syncope.core.provisioning.api.data.GroupDataBinder; import org.apache.syncope.core.provisioning.api.data.UserDataBinder; @@ -86,8 +84,6 @@ public class DefaultNotificationManager implements NotificationManager { protected final DerSchemaDAO derSchemaDAO; - protected final VirSchemaDAO virSchemaDAO; - protected final NotificationDAO notificationDAO; protected final AnyObjectDAO anyObjectDAO; @@ -104,8 +100,6 @@ public class DefaultNotificationManager implements NotificationManager { protected final DerAttrHandler derAttrHandler; - protected final VirAttrHandler virAttrHandler; - protected final UserDataBinder userDataBinder; protected final GroupDataBinder groupDataBinder; @@ -124,7 +118,6 @@ public class DefaultNotificationManager implements NotificationManager { public DefaultNotificationManager( final DerSchemaDAO derSchemaDAO, - final VirSchemaDAO virSchemaDAO, final NotificationDAO notificationDAO, final AnyObjectDAO anyObjectDAO, final UserDAO userDAO, @@ -133,7 +126,6 @@ public DefaultNotificationManager( final AnyMatchDAO anyMatchDAO, final TaskDAO taskDAO, final DerAttrHandler derAttrHandler, - final VirAttrHandler virAttrHandler, final UserDataBinder userDataBinder, final GroupDataBinder groupDataBinder, final AnyObjectDataBinder anyObjectDataBinder, @@ -143,7 +135,6 @@ public DefaultNotificationManager( final SearchCondVisitor searchCondVisitor) { this.derSchemaDAO = derSchemaDAO; - this.virSchemaDAO = virSchemaDAO; this.notificationDAO = notificationDAO; this.anyObjectDAO = anyObjectDAO; this.userDAO = userDAO; @@ -152,7 +143,6 @@ public DefaultNotificationManager( this.anyMatchDAO = anyMatchDAO; this.taskDAO = taskDAO; this.derAttrHandler = derAttrHandler; - this.virAttrHandler = virAttrHandler; this.userDataBinder = userDataBinder; this.groupDataBinder = groupDataBinder; this.anyObjectDataBinder = anyObjectDataBinder; @@ -184,8 +174,6 @@ protected NotificationTask getNotificationTask( jexlVars.put("syncopeConf", confParamOps.list(SyncopeConstants.MASTER_DOMAIN)); jexlVars.put("events", notification.getEvents()); - Optional.ofNullable(any).ifPresent(virAttrHandler::getValues); - List recipients = new ArrayList<>(); Optional.ofNullable(notification.getRecipientsFIQL()). @@ -198,18 +186,14 @@ protected NotificationTask getNotificationTask( Set recipientEmails = new HashSet<>(); List recipientTOs = new ArrayList<>(recipients.size()); - recipients.forEach(recipient -> { - virAttrHandler.getValues(recipient); - - Optional.ofNullable(getRecipientEmail(notification.getRecipientAttrName(), recipient)). - ifPresentOrElse( - email -> { - recipientEmails.add(email); - recipientTOs.add(userDataBinder.getUserTO(recipient, true)); - }, - () -> LOG.warn("{} cannot be notified: {} not found", - recipient, notification.getRecipientAttrName())); - }); + recipients.forEach(recipient -> Optional.ofNullable( + getRecipientEmail(notification.getRecipientAttrName(), recipient)).ifPresentOrElse( + email -> { + recipientEmails.add(email); + recipientTOs.add(userDataBinder.getUserTO(recipient, true)); + }, + () -> LOG.warn("{} cannot be notified: {} not found", + recipient, notification.getRecipientAttrName()))); jexlVars.put("recipients", recipientTOs); Optional.ofNullable(notification.getStaticRecipients()).ifPresent(recipientEmails::addAll); @@ -419,17 +403,6 @@ protected String getRecipientEmail(final String recipientAttrName, final User us orElse(null); } - case VIRTUAL -> { - email = virSchemaDAO.findById(recipientAttrName). - map(virSchema -> { - List virAttrValues = membership == null - ? virAttrHandler.getValues(user, virSchema) - : virAttrHandler.getValues(user, membership, virSchema); - return virAttrValues.isEmpty() ? null : virAttrValues.getFirst(); - }). - orElse(null); - } - default -> { } } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationManager.java index 6e4001fe0ab..83281bddc17 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationManager.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationManager.java @@ -31,7 +31,6 @@ import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; -import org.apache.syncope.common.lib.Attr; import org.apache.syncope.common.lib.request.AbstractPatchItem; import org.apache.syncope.common.lib.request.AnyUR; import org.apache.syncope.common.lib.request.PasswordPatch; @@ -43,13 +42,11 @@ import org.apache.syncope.common.lib.types.ResourceOperation; import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; import org.apache.syncope.core.persistence.api.dao.NotFoundException; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.EntityFactory; import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.Realm; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.policy.PropagationPolicy; import org.apache.syncope.core.persistence.api.entity.task.PropagationData; import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; @@ -85,8 +82,6 @@ public class DefaultPropagationManager implements PropagationManager { protected static final Logger LOG = LoggerFactory.getLogger(PropagationManager.class); - protected final VirSchemaDAO virSchemaDAO; - protected final ExternalResourceDAO resourceDAO; protected final EntityFactory entityFactory; @@ -100,7 +95,6 @@ public class DefaultPropagationManager implements PropagationManager { protected final AnyUtilsFactory anyUtilsFactory; public DefaultPropagationManager( - final VirSchemaDAO virSchemaDAO, final ExternalResourceDAO resourceDAO, final EntityFactory entityFactory, final ConnObjectUtils connObjectUtils, @@ -108,7 +102,6 @@ public DefaultPropagationManager( final DerAttrHandler derAttrHandler, final AnyUtilsFactory anyUtilsFactory) { - this.virSchemaDAO = virSchemaDAO; this.resourceDAO = resourceDAO; this.entityFactory = entityFactory; this.connObjectUtils = connObjectUtils; @@ -123,7 +116,6 @@ public List getCreateTasks( final String key, final Boolean enable, final PropagationByResource propByRes, - final Collection vAttrs, final Collection excludedResources) { return getCreateTasks( @@ -132,7 +124,6 @@ public List getCreateTasks( enable, propByRes, null, - vAttrs, excludedResources); } @@ -143,7 +134,6 @@ public List getUserCreateTasks( final Boolean enable, final PropagationByResource propByRes, final PropagationByResource> propByLinkedAccount, - final Collection vAttrs, final Collection excludedResources) { return getCreateTasks( @@ -152,7 +142,6 @@ public List getUserCreateTasks( enable, propByRes, propByLinkedAccount, - vAttrs, excludedResources); } @@ -162,7 +151,6 @@ protected List getCreateTasks( final Boolean enable, final PropagationByResource propByRes, final PropagationByResource> propByLinkedAccount, - final Collection vAttrs, final Collection excludedResources) { if ((propByRes == null || propByRes.isEmpty()) @@ -189,7 +177,7 @@ protected List getCreateTasks( if (propByLinkedAccount != null) { propByLinkedAccount.asMap().forEach((resource, resourceOperation) -> changePwdRes.add(resource.getKey())); } - return createTasks(any, password, changePwdRes, enable, propByRes, propByLinkedAccount, vAttrs); + return createTasks(any, password, changePwdRes, enable, propByRes, propByLinkedAccount); } @Override @@ -201,7 +189,6 @@ public List getUpdateTasks( final Boolean enable, final PropagationByResource propByRes, final PropagationByResource> propByLinkedAccount, - final Collection vAttrs, final Collection excludedResources) { return getUpdateTasks( @@ -212,7 +199,6 @@ public List getUpdateTasks( enable, propByRes, propByLinkedAccount, - vAttrs, excludedResources); } @@ -231,7 +217,6 @@ public List getUserUpdateTasks( wfResult.getResult().getRight(), wfResult.getPropByRes(), wfResult.getPropByLinkedAccount(), - wfResult.getResult().getLeft().getVirAttrs(), excludedResources); } @@ -304,7 +289,6 @@ protected List getUpdateTasks( final Boolean enable, final PropagationByResource propByRes, final PropagationByResource> propByLinkedAccount, - final Collection vAttrs, final Collection excludedResources) { if (excludedResources != null) { @@ -328,8 +312,7 @@ protected List getUpdateTasks( changePwdRes, enable, Optional.ofNullable(propByRes).orElseGet(PropagationByResource::new), - propByLinkedAccount, - vAttrs); + propByLinkedAccount); tasks.forEach(task -> task.setUpdateRequest(anyUR)); return tasks; } @@ -376,7 +359,7 @@ protected List getDeleteTasks( } } - return createTasks(any, null, List.of(), false, localPropByRes, propByLinkedAccount, null); + return createTasks(any, null, List.of(), false, localPropByRes, propByLinkedAccount); } @Override @@ -433,7 +416,6 @@ public PropagationTaskInfo newTask( * @param enable whether user must be enabled or not * @param propByRes operation to be performed per resource * @param propByLinkedAccount operation to be performed on linked accounts - * @param vAttrs virtual attributes to be set * @return list of propagation tasks created */ protected List createTasks( @@ -442,8 +424,7 @@ protected List createTasks( final List changePwdRes, final Boolean enable, final PropagationByResource propByRes, - final PropagationByResource> propByLinkedAccount, - final Collection vAttrs) { + final PropagationByResource> propByLinkedAccount) { LOG.debug("Provisioning {}:\n{}", any, propByRes); @@ -451,41 +432,6 @@ protected List createTasks( propByRes.purge(); LOG.debug("After purge {}:\n{}", any, propByRes); - // Virtual attributes - Set virtualResources = new HashSet<>(); - virtualResources.addAll(propByRes.get(ResourceOperation.CREATE)); - virtualResources.addAll(propByRes.get(ResourceOperation.UPDATE)); - virtualResources.addAll(anyUtilsFactory.getInstance(any).dao().findAllResourceKeys(any.getKey())); - - Map> vAttrMap = new HashMap<>(); - if (vAttrs != null) { - vAttrs.forEach(vAttr -> { - VirSchema schema = virSchemaDAO.findById(vAttr.getSchema()).orElse(null); - if (schema == null) { - LOG.warn("Ignoring invalid {} {}", VirSchema.class.getSimpleName(), vAttr.getSchema()); - } else if (schema.isReadonly()) { - LOG.warn("Ignoring read-only {} {}", VirSchema.class.getSimpleName(), vAttr.getSchema()); - } else if (anyUtilsFactory.getInstance(any).dao(). - findAllowedSchemas(any, VirSchema.class).contains(schema) - && virtualResources.contains(schema.getResource().getKey())) { - - Set values = vAttrMap.get(schema.getResource().getKey()); - if (values == null) { - values = new HashSet<>(); - vAttrMap.put(schema.getResource().getKey(), values); - } - values.add(AttributeBuilder.build(schema.getExtAttrName(), vAttr.getValues())); - - if (!propByRes.contains(ResourceOperation.CREATE, schema.getResource().getKey())) { - propByRes.add(ResourceOperation.UPDATE, schema.getResource().getKey()); - } - } else { - LOG.warn("{} not owned by or {} not allowed for {}", schema.getResource(), schema, any); - } - }); - } - LOG.debug("With virtual attributes {}:\n{}\n{}", any, propByRes, vAttrMap); - List tasks = new ArrayList<>(); propByRes.asMap().forEach((resourceKey, operation) -> { @@ -508,9 +454,6 @@ protected List createTasks( Pair> preparedAttrs = mappingManager.prepareAttrsFromAny(any, password, changePwdRes.contains(resourceKey), enable, resource, provision); - if (vAttrMap.containsKey(resourceKey)) { - preparedAttrs.getRight().addAll(vAttrMap.get(resourceKey)); - } PropagationTaskInfo task = newTask( derAttrHandler, diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullExecutor.java index 32b4d28f47d..de5eb45d2fa 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullExecutor.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullExecutor.java @@ -33,7 +33,6 @@ import org.apache.syncope.core.persistence.api.dao.GroupDAO; import org.apache.syncope.core.persistence.api.dao.NotFoundException; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.Implementation; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask; @@ -64,9 +63,6 @@ abstract class AbstractPullExecutor> @Autowired protected PlainSchemaDAO plainSchemaDAO; - @Autowired - protected VirSchemaDAO virSchemaDAO; - @Autowired protected InboundMatcher inboundMatcher; diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java index 0df3ad8e01c..aef8093fc85 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java @@ -21,7 +21,6 @@ import java.time.OffsetDateTime; import java.util.List; import java.util.Set; -import javax.cache.Cache; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.syncope.common.lib.AnyOperations; @@ -45,7 +44,6 @@ import org.apache.syncope.core.persistence.api.dao.RemediationDAO; import org.apache.syncope.core.persistence.api.dao.TaskDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.EntityFactory; import org.apache.syncope.core.persistence.api.entity.Remediation; import org.apache.syncope.core.persistence.api.entity.task.PullTask; @@ -59,12 +57,9 @@ import org.apache.syncope.core.provisioning.api.pushpull.InboundActions; import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullResultHandler; import org.apache.syncope.core.provisioning.api.rules.InboundMatch; -import org.apache.syncope.core.provisioning.java.cache.VirAttrCacheKey; -import org.apache.syncope.core.provisioning.java.cache.VirAttrCacheValue; import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.core.spring.security.DelegatedAdministrationException; -import org.identityconnectors.framework.common.objects.Attribute; import org.identityconnectors.framework.common.objects.SyncDelta; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Propagation; @@ -104,12 +99,6 @@ protected static OpEvent.Outcome and(final OpEvent.Outcome left, final OpEvent.O @Autowired protected RemediationDAO remediationDAO; - @Autowired - protected VirSchemaDAO virSchemaDAO; - - @Autowired - protected Cache virAttrCache; - @Autowired protected EntityFactory entityFactory; @@ -770,23 +759,6 @@ protected OpEvent.Outcome handleAnys( // do nothing } } else { - // update VirAttrCache - virSchemaDAO.findByResourceAndAnyType( - profile.getTask().getResource().getKey(), - matches.getFirst().getAny().getType().getKey()). - forEach(vs -> { - Attribute attr = delta.getObject().getAttributeByName(vs.getExtAttrName()); - matches.forEach(match -> { - VirAttrCacheKey cacheKey = VirAttrCacheKey.of( - provision.getAnyType(), match.getAny().getKey(), vs.getKey()); - if (attr == null) { - virAttrCache.remove(cacheKey); - } else { - virAttrCache.put(cacheKey, VirAttrCacheValue.of(attr.getValue())); - } - }); - }); - switch (profile.getTask().getMatchingRule()) { case UPDATE: result = update(delta, matches, provision); @@ -818,7 +790,7 @@ protected OpEvent.Outcome handleAnys( case DELETE: // Skip DELETE in case of InboundCorrelationRule.NO_MATCH result = matches.getFirst().getAny() == null - ? OpEvent.Outcome.SUCCESS : delete(delta, matches, provision); + ? OpEvent.Outcome.SUCCESS : delete(delta, matches, provision); break; default: diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java index 8d3140be681..12981c28f5b 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java @@ -135,7 +135,7 @@ protected void update( final Boolean enable, final ConnectorObject beforeObj, final ProvisioningReport result) { - + List ownedResources = getAnyUtils().getAllResources(any).stream(). map(ExternalResource::getKey).toList(); @@ -154,7 +154,6 @@ protected void update( enable, propByRes, null, - null, noPropResources); if (!taskInfos.isEmpty()) { taskInfos.getFirst().setBeforeObj(Optional.of(beforeObj)); @@ -202,7 +201,6 @@ protected void provision(final Any any, final Boolean enable, final Provisioning any.getKey(), enable, propByRes, - before.getVirAttrs(), noPropResources); if (!taskInfos.isEmpty()) { taskInfos.getFirst().setBeforeObj(Optional.empty()); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java index 10bbf3f6c19..24421002ba0 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java @@ -93,7 +93,6 @@ protected void provision(final Any any, final Boolean enabled, final Provisionin enabled, propByRes, propByLinkedAccount, - before.getVirAttrs(), noPropResources), false, profile.getExecutor()); @@ -131,7 +130,6 @@ protected void update( enable, propByRes, propByLinkedAccount, - null, noPropResources); if (!taskInfos.isEmpty()) { taskInfos.getFirst().setBeforeObj(Optional.of(beforeObj)); @@ -230,7 +228,6 @@ protected void doHandle(final LinkedAccount account, final Provision provision) account.getConnObjectKeyValue(), profile.getTask().getResource(), provision, - Optional.empty(), Optional.empty())); LOG.debug("Match found for linked account {} as {}: {}", account, provision.getObjectClass(), connObj); @@ -371,7 +368,6 @@ protected void provision( enable, new PropagationByResource<>(), propByLinkedAccount, - null, null); if (!taskInfos.isEmpty()) { taskInfos.getFirst().setBeforeObj(Optional.empty()); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/InboundMatcher.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/InboundMatcher.java index d872ac4b9c3..6970737e007 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/InboundMatcher.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/InboundMatcher.java @@ -25,7 +25,6 @@ import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; -import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.common.lib.SyncopeConstants; import org.apache.syncope.common.lib.to.Item; @@ -40,7 +39,6 @@ import org.apache.syncope.core.persistence.api.dao.RealmDAO; import org.apache.syncope.core.persistence.api.dao.RealmSearchDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.dao.search.AnyCond; import org.apache.syncope.core.persistence.api.dao.search.AttrCond; import org.apache.syncope.core.persistence.api.dao.search.SearchCond; @@ -52,12 +50,10 @@ import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.Implementation; import org.apache.syncope.core.persistence.api.entity.Realm; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.policy.InboundCorrelationRuleEntity; import org.apache.syncope.core.provisioning.api.Connector; import org.apache.syncope.core.provisioning.api.IntAttrName; import org.apache.syncope.core.provisioning.api.IntAttrNameParser; -import org.apache.syncope.core.provisioning.api.VirAttrHandler; import org.apache.syncope.core.provisioning.api.data.ItemTransformer; import org.apache.syncope.core.provisioning.api.rules.InboundCorrelationRule; import org.apache.syncope.core.provisioning.api.rules.InboundMatch; @@ -99,12 +95,8 @@ public class InboundMatcher { protected final RealmSearchDAO realmSearchDAO; - protected final VirSchemaDAO virSchemaDAO; - protected final ImplementationDAO implementationDAO; - protected final VirAttrHandler virAttrHandler; - protected final IntAttrNameParser intAttrNameParser; protected final AnyUtilsFactory anyUtilsFactory; @@ -118,9 +110,7 @@ public InboundMatcher( final AnySearchDAO anySearchDAO, final RealmDAO realmDAO, final RealmSearchDAO realmSearchDAO, - final VirSchemaDAO virSchemaDAO, final ImplementationDAO implementationDAO, - final VirAttrHandler virAttrHandler, final IntAttrNameParser intAttrNameParser, final AnyUtilsFactory anyUtilsFactory) { @@ -130,9 +120,7 @@ public InboundMatcher( this.anySearchDAO = anySearchDAO; this.realmDAO = realmDAO; this.realmSearchDAO = realmSearchDAO; - this.virSchemaDAO = virSchemaDAO; this.implementationDAO = implementationDAO; - this.virAttrHandler = virAttrHandler; this.intAttrNameParser = intAttrNameParser; this.anyUtilsFactory = anyUtilsFactory; } @@ -162,11 +150,6 @@ public Optional match( } // then, attempt to lookup the provided connObjectLinkValue onto the connector - Stream mapItems = Stream.concat( - provision.getMapping().getItems().stream(), - virSchemaDAO.findByResourceAndAnyType(resource.getKey(), anyType.getKey()).stream(). - map(VirSchema::asLinkingMappingItem)); - List found = new ArrayList<>(); try { @@ -187,7 +170,7 @@ public void handleResult(final SearchResult result) { public boolean handle(final ConnectorObject connectorObject) { return found.add(connectorObject); } - }, MappingUtils.buildOperationOptions(mapItems)); + }, MappingUtils.buildOperationOptions(provision.getMapping().getItems().stream())); } catch (Throwable t) { LOG.warn("While searching for {} ...", connObjectLinkValue, t); } @@ -222,7 +205,6 @@ public boolean handle(final ConnectorObject connectorObject) { } result = matches.stream().filter(match -> match.getAny() != null).findFirst(); - result.ifPresent(inboundMatch -> virAttrHandler.setValues(inboundMatch.getAny(), connObj)); } } catch (IllegalArgumentException e) { LOG.warn(e.getMessage()); @@ -439,10 +421,6 @@ public List match( LOG.error("Could not match {} with any existing {}", syncDelta, provision.getAnyType(), e); } - if (result.size() == 1 && result.getFirst().getMatchTarget() == MatchType.ANY) { - virAttrHandler.setValues(result.getFirst().getAny(), syncDelta.getObject()); - } - return result; } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LiveSyncJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LiveSyncJobDelegate.java index d7b235c0ac0..3eba396d4ca 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LiveSyncJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LiveSyncJobDelegate.java @@ -24,9 +24,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; -import org.apache.syncope.common.lib.to.Item; import org.apache.syncope.common.lib.to.OrgUnit; import org.apache.syncope.common.lib.to.Provision; import org.apache.syncope.common.lib.types.AnyTypeKind; @@ -41,7 +39,6 @@ import org.apache.syncope.core.persistence.api.entity.AnyUtils; import org.apache.syncope.core.persistence.api.entity.Implementation; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.policy.InboundPolicy; import org.apache.syncope.core.persistence.api.entity.task.AnyTemplatePullTask; import org.apache.syncope.core.persistence.api.entity.task.LiveSyncTask; @@ -223,13 +220,9 @@ public String getContext() { Set moreAttrsToGet = new HashSet<>(); profile.getActions().forEach(a -> moreAttrsToGet.addAll(a.moreAttrsToGet(profile, provision))); - Stream mapItems = Stream.concat( - MappingUtils.getInboundItems(provision.getMapping().getItems().stream()), - virSchemaDAO.findByResourceAndAnyType( - task.getResource().getKey(), anyType.getKey()).stream(). - map(VirSchema::asLinkingMappingItem)); OperationOptions options = MappingUtils.buildOperationOptions( - mapItems, moreAttrsToGet.toArray(String[]::new)); + MappingUtils.getInboundItems(provision.getMapping().getItems().stream()), + moreAttrsToGet.toArray(String[]::new)); infos.add(new LiveSyncInfo( provision, diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java index 19c90a401d0..038df153f03 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java @@ -19,7 +19,6 @@ package org.apache.syncope.core.provisioning.java.pushpull; import java.util.ArrayList; -import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -27,22 +26,18 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Stream; -import org.apache.commons.lang3.ArrayUtils; import org.apache.syncope.common.lib.to.Item; import org.apache.syncope.common.lib.to.Provision; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.Implementation; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.policy.PushCorrelationRuleEntity; import org.apache.syncope.core.provisioning.api.Connector; import org.apache.syncope.core.provisioning.api.MappingManager; import org.apache.syncope.core.provisioning.api.TimeoutException; -import org.apache.syncope.core.provisioning.api.VirAttrHandler; import org.apache.syncope.core.provisioning.api.propagation.PropagationActions; import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskInfo; import org.apache.syncope.core.provisioning.api.rules.PushCorrelationRule; @@ -68,10 +63,6 @@ public class OutboundMatcher { protected final AnyUtilsFactory anyUtilsFactory; - protected final VirSchemaDAO virSchemaDAO; - - protected final VirAttrHandler virAttrHandler; - protected final Map perContextActions = new ConcurrentHashMap<>(); protected final Map perContextPushCorrelationRules = new ConcurrentHashMap<>(); @@ -79,15 +70,11 @@ public class OutboundMatcher { public OutboundMatcher( final MappingManager mappingManager, final UserDAO userDAO, - final AnyUtilsFactory anyUtilsFactory, - final VirSchemaDAO virSchemaDAO, - final VirAttrHandler virAttrHandler) { + final AnyUtilsFactory anyUtilsFactory) { this.mappingManager = mappingManager; this.userDAO = userDAO; this.anyUtilsFactory = anyUtilsFactory; - this.virSchemaDAO = virSchemaDAO; - this.virAttrHandler = virAttrHandler; } protected Optional rule(final ExternalResource resource, final Provision provision) { @@ -149,8 +136,7 @@ public List match( rule.get().getFilter(any, taskInfo.getResource(), provision), taskInfo.getResource(), provision, - Optional.of(moreAttrsToGet.toArray(String[]::new)), - Optional.empty())); + Optional.of(moreAttrsToGet.toArray(String[]::new)))); } else { MappingUtils.getConnObjectKeyItem(provision).flatMap(connObjectKeyItem -> matchByConnObjectKeyValue( connector, @@ -158,17 +144,12 @@ public List match( connObjectKeyValue, taskInfo.getResource(), provision, - Optional.of(moreAttrsToGet.toArray(String[]::new)), - Optional.empty())).ifPresent(result::add); + Optional.of(moreAttrsToGet.toArray(String[]::new)))).ifPresent(result::add); } } catch (RuntimeException e) { LOG.error("Could not match {} with any existing {}", any, provision.getObjectClass(), e); } - if (any != null && result.size() == 1) { - virAttrHandler.setValues(any, result.getFirst()); - } - return result; } @@ -195,8 +176,7 @@ public List match( final Any any, final ExternalResource resource, final Provision provision, - final Optional moreAttrsToGet, - final Item... linkingItems) { + final Optional moreAttrsToGet) { Stream matgFromPropagationActions = getPropagationActions(resource).stream(). flatMap(a -> a.moreAttrsToGet(Optional.empty(), provision).stream()); @@ -214,9 +194,7 @@ public List match( rule.get().getFilter(any, resource, provision), resource, provision, - effectiveMATG, - ArrayUtils.isEmpty(linkingItems) - ? Optional.empty() : Optional.of(List.of(linkingItems)))); + effectiveMATG)); } else { Optional connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision); Optional connObjectKeyValue = mappingManager.getConnObjectKeyValue(any, resource, provision); @@ -228,8 +206,7 @@ public List match( connObjectKeyValue.get(), resource, provision, - effectiveMATG, - ArrayUtils.isEmpty(linkingItems) ? Optional.empty() : Optional.of(List.of(linkingItems))). + effectiveMATG). ifPresent(result::add); } } @@ -237,10 +214,6 @@ public List match( LOG.error("Could not match {} with any existing {}", any, provision.getObjectClass(), e); } - if (any != null && result.size() == 1) { - virAttrHandler.setValues(any, result.getFirst()); - } - return result; } @@ -249,15 +222,7 @@ protected List matchByCorrelationRule( final Filter filter, final ExternalResource resource, final Provision provision, - final Optional moreAttrsToGet, - final Optional> linkingItems) { - - Stream items = Stream.concat( - provision.getMapping().getItems().stream(), - linkingItems.isPresent() - ? linkingItems.get().stream() - : virSchemaDAO.findByResourceAndAnyType(resource.getKey(), provision.getAnyType()).stream(). - map(VirSchema::asLinkingMappingItem)); + final Optional moreAttrsToGet) { List objs = new ArrayList<>(); try { @@ -273,7 +238,8 @@ public boolean handle(final ConnectorObject connectorObject) { objs.add(connectorObject); return true; } - }, MappingUtils.buildOperationOptions(items, moreAttrsToGet.orElse(null))); + }, MappingUtils.buildOperationOptions( + provision.getMapping().getItems().stream(), moreAttrsToGet.orElse(null))); } catch (TimeoutException toe) { LOG.debug("Request timeout", toe); throw toe; @@ -291,14 +257,7 @@ public Optional matchByConnObjectKeyValue( final String connObjectKeyValue, final ExternalResource resource, final Provision provision, - final Optional moreAttrsToGet, - final Optional> linkingItems) { - - Stream items = Stream.concat( - provision.getMapping().getItems().stream(), - linkingItems.map(Collection::stream). - orElseGet(() -> virSchemaDAO.findByResourceAndAnyType( - resource.getKey(), provision.getAnyType()).stream().map(VirSchema::asLinkingMappingItem))); + final Optional moreAttrsToGet) { ConnectorObject obj = null; try { @@ -306,7 +265,8 @@ public Optional matchByConnObjectKeyValue( new ObjectClass(provision.getObjectClass()), AttributeBuilder.build(connObjectKeyItem.getExtAttrName(), connObjectKeyValue), provision.isIgnoreCaseMatch(), - MappingUtils.buildOperationOptions(items, moreAttrsToGet.orElse(null))); + MappingUtils.buildOperationOptions( + provision.getMapping().getItems().stream(), moreAttrsToGet.orElse(null))); } catch (TimeoutException toe) { LOG.debug("Request timeout", toe); throw toe; diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java index 9d89e61f789..44e7fa29c83 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java @@ -21,8 +21,6 @@ import java.util.HashSet; import java.util.Optional; import java.util.Set; -import java.util.stream.Stream; -import org.apache.syncope.common.lib.to.Item; import org.apache.syncope.common.lib.to.OrgUnit; import org.apache.syncope.common.lib.to.Provision; import org.apache.syncope.common.lib.types.ConflictResolutionAction; @@ -31,7 +29,6 @@ import org.apache.syncope.core.persistence.api.dao.NotFoundException; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyUtils; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.policy.InboundPolicy; import org.apache.syncope.core.persistence.api.entity.task.PullTask; import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; @@ -191,13 +188,9 @@ protected String doExecute(final JobExecutionContext context) throws JobExecutio try { Set moreAttrsToGet = new HashSet<>(); profile.getActions().forEach(a -> moreAttrsToGet.addAll(a.moreAttrsToGet(profile, provision))); - Stream mapItems = Stream.concat( - MappingUtils.getInboundItems(provision.getMapping().getItems().stream()), - virSchemaDAO.findByResourceAndAnyType( - task.getResource().getKey(), anyType.getKey()).stream(). - map(VirSchema::asLinkingMappingItem)); OperationOptions options = MappingUtils.buildOperationOptions( - mapItems, moreAttrsToGet.toArray(String[]::new)); + MappingUtils.getInboundItems(provision.getMapping().getItems().stream()), + moreAttrsToGet.toArray(String[]::new)); switch (task.getPullMode()) { case INCREMENTAL: diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java index ec7ef1000aa..f3b23a0086b 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java @@ -22,8 +22,6 @@ import java.util.List; import java.util.Optional; import java.util.Set; -import java.util.stream.Stream; -import org.apache.syncope.common.lib.to.Item; import org.apache.syncope.common.lib.to.Provision; import org.apache.syncope.common.lib.to.ProvisioningReport; import org.apache.syncope.common.lib.to.PullTaskTO; @@ -38,7 +36,6 @@ import org.apache.syncope.core.persistence.api.dao.RealmSearchDAO; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.ExternalResource; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.task.AnyTemplatePullTask; import org.apache.syncope.core.persistence.api.entity.task.PullTask; import org.apache.syncope.core.provisioning.api.Connector; @@ -150,16 +147,13 @@ public List pull( Set matg = new HashSet<>(moreAttrsToGet); profile.getActions().forEach(a -> matg.addAll(a.moreAttrsToGet(profile, provision))); - Stream mapItems = Stream.concat( - MappingUtils.getInboundItems(provision.getMapping().getItems().stream()), - virSchemaDAO.findByResourceAndAnyType(task.getResource().getKey(), anyType.getKey()).stream(). - map(VirSchema::asLinkingMappingItem)); - connector.filteredReconciliation( new ObjectClass(provision.getObjectClass()), reconFilterBuilder, dispatcher, - MappingUtils.buildOperationOptions(mapItems, matg.toArray(String[]::new))); + MappingUtils.buildOperationOptions( + MappingUtils.getInboundItems(provision.getMapping().getItems().stream()), + matg.toArray(String[]::new))); try { setGroupOwners(); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegate.java index 964bd9e34de..12b42312125 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegate.java @@ -22,7 +22,6 @@ import java.util.List; import java.util.Optional; import java.util.Set; -import java.util.stream.Stream; import org.apache.syncope.common.lib.to.Item; import org.apache.syncope.common.lib.to.Mapping; import org.apache.syncope.common.lib.to.Provision; @@ -40,7 +39,6 @@ import org.apache.syncope.core.persistence.api.entity.AnyUtils; import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.Implementation; -import org.apache.syncope.core.persistence.api.entity.VirSchema; import org.apache.syncope.core.persistence.api.entity.policy.InboundCorrelationRuleEntity; import org.apache.syncope.core.persistence.api.entity.policy.InboundPolicy; import org.apache.syncope.core.persistence.api.entity.task.PullTask; @@ -118,8 +116,7 @@ private Provision provision( mapping.setConnObjectKeyItem(connObjectKeyItem); columns.stream(). - filter(column -> anyUtils.getField(column).isPresent() - || plainSchemaDAO.existsById(column) || virSchemaDAO.existsById(column)). + filter(column -> anyUtils.getField(column).isPresent() || plainSchemaDAO.existsById(column)). map(column -> { Item item = new Item(); item.setExtAttrName(column); @@ -223,15 +220,12 @@ public List pull( Set moreAttrsToGet = new HashSet<>(); profile.getActions().forEach(a -> moreAttrsToGet.addAll(a.moreAttrsToGet(profile, provision))); - Stream mapItems = Stream.concat( - MappingUtils.getInboundItems(provision.getMapping().getItems().stream()), - virSchemaDAO.findByResourceAndAnyType(resource.getKey(), anyType.getKey()).stream(). - map(VirSchema::asLinkingMappingItem)); - connector.fullReconciliation( new ObjectClass(provision.getObjectClass()), dispatcher, - MappingUtils.buildOperationOptions(mapItems, moreAttrsToGet.toArray(String[]::new))); + MappingUtils.buildOperationOptions( + MappingUtils.getInboundItems(provision.getMapping().getItems().stream()), + moreAttrsToGet.toArray(String[]::new))); try { setGroupOwners(); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java index 4fd6d8a303e..49712cd609a 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java @@ -51,11 +51,6 @@ public static void check(final Map templates, final ClientExcepti && !JexlUtils.isExpressionValid(attrTO.getValues().getFirst())). forEachOrdered(attrTO -> sce.getElements().add("Invalid JEXL: " + attrTO.getValues().getFirst())); - value.getVirAttrs().stream(). - filter(attrTO -> !attrTO.getValues().isEmpty() - && !JexlUtils.isExpressionValid(attrTO.getValues().getFirst())). - forEachOrdered((attrTO) -> sce.getElements().add("Invalid JEXL: " + attrTO.getValues().getFirst())); - switch (value) { case UserTO template -> { if (StringUtils.isNotBlank(template.getUsername()) @@ -107,7 +102,6 @@ protected static void fill(final RealmMember realmMember, final RealmMember temp JexlUtils.addFieldsToContext(realmMember, jexlContext); JexlUtils.addAttrsToContext(realmMember.getPlainAttrs(), jexlContext); JexlUtils.addAttrsToContext(realmMember.getDerAttrs(), jexlContext); - JexlUtils.addAttrsToContext(realmMember.getVirAttrs(), jexlContext); if (template.getRealm() != null) { String evaluated = JexlUtils.evaluateExpr(template.getRealm(), jexlContext).toString(); @@ -137,20 +131,6 @@ protected static void fill(final RealmMember realmMember, final RealmMember temp } } - currentAttrMap = EntityTOUtils.buildAttrMap(realmMember.getVirAttrs()); - for (Attr templateVirAttr : template.getVirAttrs()) { - if (!templateVirAttr.getValues().isEmpty() - && (!currentAttrMap.containsKey(templateVirAttr.getSchema()) - || currentAttrMap.get(templateVirAttr.getSchema()).getValues().isEmpty())) { - - Attr evaluated = evaluateAttr(templateVirAttr, jexlContext); - if (!evaluated.getValues().isEmpty()) { - realmMember.getVirAttrs().add(evaluated); - jexlContext.set(evaluated.getSchema(), evaluated.getValues().getFirst()); - } - } - } - realmMember.getResources().addAll(template.getResources()); realmMember.getAuxClasses().addAll(template.getAuxClasses()); @@ -186,7 +166,6 @@ public void apply(final RealmMember realmMember, final AnyTO template) { JexlUtils.addFieldsToContext(realmMember, jexlContext); JexlUtils.addAttrsToContext(realmMember.getPlainAttrs(), jexlContext); JexlUtils.addAttrsToContext(realmMember.getDerAttrs(), jexlContext); - JexlUtils.addAttrsToContext(realmMember.getVirAttrs(), jexlContext); switch (template) { case AnyObjectTO anyObjectTO -> { @@ -238,13 +217,13 @@ public void apply(final RealmMember realmMember, final AnyTO template) { fillMemberships((GroupableRelatableTO) realmMember, ((GroupableRelatableTO) template)); userTO.getRoles(). - forEach(role -> { - if (realmMember instanceof UserTO urm) { - urm.getRoles().add(role); - } else if (realmMember instanceof UserCR urm) { - urm.getRoles().add(role); - } - }); + forEach(role -> { + if (realmMember instanceof UserTO urm) { + urm.getRoles().add(role); + } else if (realmMember instanceof UserCR urm) { + urm.getRoles().add(role); + } + }); userTO.getLinkedAccounts().forEach(account -> { if (realmMember instanceof UserTO urm && urm.getLinkedAccounts().stream(). diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/cache/VirAttrCacheKeyTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/cache/VirAttrCacheKeyTest.java deleted file mode 100644 index 47becdb3323..00000000000 --- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/cache/VirAttrCacheKeyTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.provisioning.java.cache; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; - -public class VirAttrCacheKeyTest { - - @Test - public void test() { - String type = "type"; - String key = "key"; - String virSchema = "virSchema"; - VirAttrCacheKey cacheKey = VirAttrCacheKey.of(type, key, virSchema); - VirAttrCacheKey cacheKey2 = VirAttrCacheKey.of(type, key, virSchema); - VirAttrCacheKey cacheKey3 = VirAttrCacheKey.of(type, String.format(type, "3"), String.format(virSchema, "3")); - Object nullObj = null; - - assertEquals(cacheKey.hashCode(), cacheKey2.hashCode()); - assertFalse(cacheKey.equals(nullObj)); - assertFalse(cacheKey.equals(String.class)); - assertTrue(cacheKey.equals(cacheKey)); - assertTrue(cacheKey.equals(cacheKey2)); - assertFalse(cacheKey.equals(cacheKey3)); - - assertEquals(cacheKey.toString(), cacheKey2.toString()); - } -} diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/cache/VirAttrCacheValueTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/cache/VirAttrCacheValueTest.java deleted file mode 100644 index 247ef70873d..00000000000 --- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/cache/VirAttrCacheValueTest.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.provisioning.java.cache; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; -import org.junit.jupiter.api.Test; - -public class VirAttrCacheValueTest { - - @Test - public void test() { - Object nullObj = null; - VirAttrCacheValue cacheValue = VirAttrCacheValue.of(List.of("testValue")); - VirAttrCacheValue cacheValue2 = VirAttrCacheValue.of(List.of()); - - assertNotEquals(cacheValue.values(), cacheValue2.values()); - assertNotEquals(cacheValue.hashCode(), cacheValue2.hashCode()); - assertFalse(cacheValue.equals(cacheValue2)); - assertTrue(cacheValue.equals(cacheValue)); - assertFalse(cacheValue2.equals(nullObj)); - assertFalse(cacheValue2.equals(String.class)); - assertNotEquals(cacheValue.toString(), cacheValue2.toString()); - } -} diff --git a/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreApplication.java b/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreApplication.java index 72dec8d9ea3..e5f3c5e588f 100644 --- a/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreApplication.java +++ b/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreApplication.java @@ -38,7 +38,6 @@ import org.apache.syncope.core.persistence.api.dao.SecurityQuestionDAO; import org.apache.syncope.core.persistence.api.dao.TaskDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.provisioning.api.ConnIdBundleManager; import org.apache.syncope.core.provisioning.api.ConnectorManager; import org.apache.syncope.core.provisioning.api.ImplementationLookup; @@ -144,7 +143,6 @@ public SyncopeCoreInfoContributor syncopeCoreInfoContributor( final PolicyDAO policyDAO, final NotificationDAO notificationDAO, final TaskDAO taskDAO, - final VirSchemaDAO virSchemaDAO, final SecurityQuestionDAO securityQuestionDAO, final PersistenceInfoDAO persistenceInfoDAO, final ConfParamOps confParamOps, @@ -162,7 +160,6 @@ public SyncopeCoreInfoContributor syncopeCoreInfoContributor( policyDAO, notificationDAO, taskDAO, - virSchemaDAO, securityQuestionDAO, persistenceInfoDAO, confParamOps, diff --git a/core/starter/src/main/java/org/apache/syncope/core/starter/actuate/DefaultSyncopeCoreInfoContributor.java b/core/starter/src/main/java/org/apache/syncope/core/starter/actuate/DefaultSyncopeCoreInfoContributor.java index 92a1a870a8c..fda269f0d69 100644 --- a/core/starter/src/main/java/org/apache/syncope/core/starter/actuate/DefaultSyncopeCoreInfoContributor.java +++ b/core/starter/src/main/java/org/apache/syncope/core/starter/actuate/DefaultSyncopeCoreInfoContributor.java @@ -52,7 +52,6 @@ import org.apache.syncope.core.persistence.api.dao.SecurityQuestionDAO; import org.apache.syncope.core.persistence.api.dao.TaskDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.ExternalResource; @@ -130,8 +129,6 @@ protected static void initSystemInfo() { protected final TaskDAO taskDAO; - protected final VirSchemaDAO virSchemaDAO; - protected final SecurityQuestionDAO securityQuestionDAO; protected final NotificationDAO notificationDAO; @@ -155,7 +152,6 @@ public DefaultSyncopeCoreInfoContributor( final PolicyDAO policyDAO, final NotificationDAO notificationDAO, final TaskDAO taskDAO, - final VirSchemaDAO virSchemaDAO, final SecurityQuestionDAO securityQuestionDAO, final PersistenceInfoDAO persistenceInfoDAO, final ConfParamOps confParamOps, @@ -172,7 +168,6 @@ public DefaultSyncopeCoreInfoContributor( this.policyDAO = policyDAO; this.notificationDAO = notificationDAO; this.taskDAO = taskDAO; - this.virSchemaDAO = virSchemaDAO; this.securityQuestionDAO = securityQuestionDAO; this.persistenceInfoDAO = persistenceInfoDAO; this.confParamOps = confParamOps; @@ -284,8 +279,6 @@ protected NumbersInfo buildNumbers(final String domain) { NumbersInfo.ConfItem.NOTIFICATION.name(), !notificationDAO.findAll().isEmpty()); numbersInfo.getConfCompleteness().put( NumbersInfo.ConfItem.PULL_TASK.name(), !taskDAO.findAll(TaskType.PULL).isEmpty()); - numbersInfo.getConfCompleteness().put( - NumbersInfo.ConfItem.VIR_SCHEMA.name(), !virSchemaDAO.findAll().isEmpty()); numbersInfo.getConfCompleteness().put( NumbersInfo.ConfItem.ANY_TYPE.name(), !anyObjectNumbers.isEmpty()); numbersInfo.getConfCompleteness().put( diff --git a/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/mapping/OIDCProviderMappingPanel.java b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/mapping/OIDCProviderMappingPanel.java index e838121015c..b2b8bd92898 100644 --- a/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/mapping/OIDCProviderMappingPanel.java +++ b/ext/oidcc4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/mapping/OIDCProviderMappingPanel.java @@ -103,7 +103,6 @@ protected void setAttrNames(final AjaxTextFieldPanel toBeUpdated) { forEach(anyTypeClassTO -> { choices.addAll(anyTypeClassTO.getPlainSchemas()); choices.addAll(anyTypeClassTO.getDerSchemas()); - choices.addAll(anyTypeClassTO.getVirSchemas()); }); Collections.sort(choices); diff --git a/ext/oidcc4ui/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/OIDCC4UIProviderDataBinderImpl.java b/ext/oidcc4ui/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/OIDCC4UIProviderDataBinderImpl.java index 52c0a0aaf57..b78c2b4e8b3 100644 --- a/ext/oidcc4ui/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/OIDCC4UIProviderDataBinderImpl.java +++ b/ext/oidcc4ui/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/OIDCC4UIProviderDataBinderImpl.java @@ -27,7 +27,6 @@ import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.ClientExceptionType; import org.apache.syncope.common.lib.types.MappingPurpose; -import org.apache.syncope.common.lib.types.SchemaType; import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO; import org.apache.syncope.core.persistence.api.dao.ImplementationDAO; import org.apache.syncope.core.persistence.api.dao.OIDCC4UIProviderDAO; @@ -133,10 +132,6 @@ protected void populateItems(final OIDCC4UIProviderTO opTO, final OIDCC4UIProvid }); if (item.isConnObjectKey()) { - if (intAttrName.getSchemaType() == SchemaType.VIRTUAL) { - invalidMapping.getElements(). - add("Virtual attributes cannot be set as ConnObjectKey"); - } if ("password".equals(intAttrName.getField())) { invalidMapping.getElements().add( "Password attributes cannot be set as ConnObjectKey"); diff --git a/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/mapping/SAML2IdPMappingPanel.java b/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/mapping/SAML2IdPMappingPanel.java index 24e7cda4667..70f82bc35f8 100644 --- a/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/mapping/SAML2IdPMappingPanel.java +++ b/ext/saml2sp4ui/client-console/src/main/java/org/apache/syncope/client/console/wizards/mapping/SAML2IdPMappingPanel.java @@ -86,7 +86,6 @@ protected void setAttrNames(final AjaxTextFieldPanel toBeUpdated) { forEach(anyTypeClassTO -> { choices.addAll(anyTypeClassTO.getPlainSchemas()); choices.addAll(anyTypeClassTO.getDerSchemas()); - choices.addAll(anyTypeClassTO.getVirSchemas()); }); Collections.sort(choices); diff --git a/ext/saml2sp4ui/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2SP4UIIdPDataBinderImpl.java b/ext/saml2sp4ui/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2SP4UIIdPDataBinderImpl.java index c3436b38cdd..ddb21fcf541 100644 --- a/ext/saml2sp4ui/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2SP4UIIdPDataBinderImpl.java +++ b/ext/saml2sp4ui/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2SP4UIIdPDataBinderImpl.java @@ -28,7 +28,6 @@ import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.ClientExceptionType; import org.apache.syncope.common.lib.types.MappingPurpose; -import org.apache.syncope.common.lib.types.SchemaType; import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO; import org.apache.syncope.core.persistence.api.dao.ImplementationDAO; import org.apache.syncope.core.persistence.api.dao.SAML2SP4UIIdPDAO; @@ -134,10 +133,6 @@ protected void populateItems(final SAML2SP4UIIdPTO idpTO, final SAML2SP4UIIdP id }); if (item.isConnObjectKey()) { - if (intAttrName.getSchemaType() == SchemaType.VIRTUAL) { - invalidMapping.getElements(). - add("Virtual attributes cannot be set as ConnObjectKey"); - } if ("password".equals(intAttrName.getField())) { invalidMapping.getElements().add( "Password attributes cannot be set as ConnObjectKey"); diff --git a/ext/scimv2/client-console/src/main/java/org/apache/syncope/client/console/panels/mapping/SCIMExtensionMappingPanel.java b/ext/scimv2/client-console/src/main/java/org/apache/syncope/client/console/panels/mapping/SCIMExtensionMappingPanel.java index 683794130cd..1692d11e242 100644 --- a/ext/scimv2/client-console/src/main/java/org/apache/syncope/client/console/panels/mapping/SCIMExtensionMappingPanel.java +++ b/ext/scimv2/client-console/src/main/java/org/apache/syncope/client/console/panels/mapping/SCIMExtensionMappingPanel.java @@ -270,7 +270,6 @@ protected IModel> getExtAttrNames() { forEach(anyTypeClassTO -> { choices.addAll(anyTypeClassTO.getPlainSchemas()); choices.addAll(anyTypeClassTO.getDerSchemas()); - choices.addAll(anyTypeClassTO.getVirSchemas()); }); Collections.sort(choices); diff --git a/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/SCIMDataBinder.java b/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/SCIMDataBinder.java index 20239e7c586..e9292daa2b2 100644 --- a/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/SCIMDataBinder.java +++ b/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/SCIMDataBinder.java @@ -211,7 +211,6 @@ public SCIMUser toSCIMUser( Map attrs = new HashMap<>(); attrs.putAll(EntityTOUtils.buildAttrMap(userTO.getPlainAttrs())); attrs.putAll(EntityTOUtils.buildAttrMap(userTO.getDerAttrs())); - attrs.putAll(EntityTOUtils.buildAttrMap(userTO.getVirAttrs())); attrs.put("username", new Attr.Builder("username").value(userTO.getUsername()).build()); if (conf.getUserConf() != null) { @@ -358,7 +357,7 @@ public SCIMUser toSCIMUser( if (output(attributes, excludedAttributes, "x509Certificates")) { conf.getUserConf().getX509Certificates().stream().filter(attrs::containsKey). forEach(cert -> user.getX509Certificates().add( - new Value(attrs.get(cert).getValues().getFirst()))); + new Value(attrs.get(cert).getValues().getFirst()))); } } @@ -422,10 +421,6 @@ public SCIMUser toSCIMUser( displayName = userManager.getDerAttr( conf.getEnterpriseUserConf().getManager().getDisplayName()).orElse(null); } - if (displayName == null) { - displayName = userManager.getVirAttr( - conf.getEnterpriseUserConf().getManager().getDisplayName()).orElse(null); - } if (displayName != null) { manager.setDisplayName(displayName.getValues().getFirst()); } @@ -825,7 +820,8 @@ public Pair toUserUpdate( } switch (op.getPath().getAttribute()) { - case "externalId" -> setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getExternalId(), op); + case "externalId" -> + setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getExternalId(), op); case "userName" -> { if (op.getOp() != PatchOp.remove && !CollectionUtils.isEmpty(op.getValue())) { @@ -851,8 +847,8 @@ public Pair toUserUpdate( statusR = new StatusR.Builder(before.getKey(), (boolean) op.getValue().getFirst() - ? StatusRType.REACTIVATE - : StatusRType.SUSPEND).resources(resources).build(); + ? StatusRType.REACTIVATE + : StatusRType.SUSPEND).resources(resources).build(); } } @@ -879,22 +875,29 @@ public Pair toUserUpdate( } } - case "displayName" -> setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getDisplayName(), op); + case "displayName" -> + setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getDisplayName(), op); - case "nickName" -> setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getNickName(), op); + case "nickName" -> + setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getNickName(), op); - case "profileUrl" -> setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getProfileUrl(), op); + case "profileUrl" -> + setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getProfileUrl(), op); - case "title" -> setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getTitle(), op); + case "title" -> + setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getTitle(), op); - case "userType" -> setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getUserType(), op); + case "userType" -> + setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getUserType(), op); case "preferredLanguage" -> - setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getPreferredLanguage(), op); + setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getPreferredLanguage(), op); - case "locale" -> setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getLocale(), op); + case "locale" -> + setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getLocale(), op); - case "timezone" -> setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getTimezone(), op); + case "timezone" -> + setAttribute(userUR.getPlainAttrs(), conf.getUserConf().getTimezone(), op); case "emails" -> { if (!CollectionUtils.isEmpty(op.getValue()) && op.getValue().getFirst() instanceof SCIMUser) { @@ -934,48 +937,54 @@ public Pair toUserUpdate( case "addresses" -> { if (!CollectionUtils.isEmpty(op.getValue()) - && op.getValue().getFirst() instanceof final SCIMUser after) { + && op.getValue().getFirst() instanceof final SCIMUser after) { after.getAddresses().stream().filter(address -> address.getType() != null).forEach( address -> conf.getUserConf().getAddresses().stream() .filter(object -> address.getType().equals(object.getType().name())).findFirst() .ifPresent(addressConf -> setAttribute(userUR.getPlainAttrs(), addressConf, op))); } else if (op.getPath().getFilter() != null) { conf.getUserConf().getAddresses().stream().filter(addressConf -> BooleanUtils.toBoolean( - JexlUtils.evaluateExpr(filter2JexlExpression(op.getPath().getFilter()), - new MapContext(Map.of("type", addressConf.getType().name()))).toString())) + JexlUtils.evaluateExpr(filter2JexlExpression(op.getPath().getFilter()), + new MapContext(Map.of("type", addressConf.getType().name()))).toString())) .findFirst() .ifPresent(addressConf -> setAttribute(userUR.getPlainAttrs(), addressConf, op)); } } - case "employeeNumber" -> setAttribute(userUR.getPlainAttrs(), - Optional.ofNullable(conf.getEnterpriseUserConf()).map(SCIMEnterpriseUserConf::getEmployeeNumber) - .orElse(null), op); + case "employeeNumber" -> + setAttribute(userUR.getPlainAttrs(), + Optional.ofNullable(conf.getEnterpriseUserConf()). + map(SCIMEnterpriseUserConf::getEmployeeNumber).orElse(null), op); - case "costCenter" -> setAttribute(userUR.getPlainAttrs(), - Optional.ofNullable(conf.getEnterpriseUserConf()).map(SCIMEnterpriseUserConf::getCostCenter) - .orElse(null), op); + case "costCenter" -> + setAttribute(userUR.getPlainAttrs(), + Optional.ofNullable(conf.getEnterpriseUserConf()). + map(SCIMEnterpriseUserConf::getCostCenter).orElse(null), op); - case "organization" -> setAttribute(userUR.getPlainAttrs(), - Optional.ofNullable(conf.getEnterpriseUserConf()).map(SCIMEnterpriseUserConf::getOrganization) - .orElse(null), op); + case "organization" -> + setAttribute(userUR.getPlainAttrs(), + Optional.ofNullable(conf.getEnterpriseUserConf()). + map(SCIMEnterpriseUserConf::getOrganization).orElse(null), op); - case "division" -> setAttribute(userUR.getPlainAttrs(), - Optional.ofNullable(conf.getEnterpriseUserConf()).map(SCIMEnterpriseUserConf::getDivision) - .orElse(null), op); + case "division" -> + setAttribute(userUR.getPlainAttrs(), + Optional.ofNullable(conf.getEnterpriseUserConf()). + map(SCIMEnterpriseUserConf::getDivision).orElse(null), op); - case "department" -> setAttribute(userUR.getPlainAttrs(), - Optional.ofNullable(conf.getEnterpriseUserConf()).map(SCIMEnterpriseUserConf::getDepartment) - .orElse(null), op); + case "department" -> + setAttribute(userUR.getPlainAttrs(), + Optional.ofNullable(conf.getEnterpriseUserConf()). + map(SCIMEnterpriseUserConf::getDepartment).orElse(null), op); - case "manager" -> setAttribute(userUR.getPlainAttrs(), - Optional.ofNullable(conf.getEnterpriseUserConf()).map(SCIMEnterpriseUserConf::getManager) - .map(SCIMManagerConf::getKey).orElse(null), op); + case "manager" -> + setAttribute(userUR.getPlainAttrs(), + Optional.ofNullable(conf.getEnterpriseUserConf()). + map(SCIMEnterpriseUserConf::getManager).map(SCIMManagerConf::getKey).orElse(null), op); default -> { - Optional.ofNullable(conf.getExtensionUserConf()) - .flatMap(schema -> Optional.ofNullable(schema.asMap().get(op.getPath().getAttribute()))) - .ifPresent(schema -> setAttribute(userUR.getPlainAttrs(), schema, op)); + Optional.ofNullable(conf.getExtensionUserConf()). + flatMap(schema -> Optional.ofNullable(schema.asMap().get(op.getPath().getAttribute()))). + ifPresent(schema -> setAttribute(userUR.getPlainAttrs(), schema, op)); } } @@ -1003,7 +1012,6 @@ public SCIMGroup toSCIMGroup( Map attrs = new HashMap<>(); attrs.putAll(EntityTOUtils.buildAttrMap(groupTO.getPlainAttrs())); attrs.putAll(EntityTOUtils.buildAttrMap(groupTO.getDerAttrs())); - attrs.putAll(EntityTOUtils.buildAttrMap(groupTO.getVirAttrs())); if (output(attributes, excludedAttributes, "externalId") && conf.getGroupConf() != null diff --git a/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/scim/SCIMConfManager.java b/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/scim/SCIMConfManager.java index 4194a9993d4..2a69aefe600 100644 --- a/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/scim/SCIMConfManager.java +++ b/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/scim/SCIMConfManager.java @@ -89,10 +89,10 @@ public void set(final SCIMConf conf) { if (conf.getExtensionUserConf() != null) { conf.getExtensionUserConf().getAttributes().forEach(scimItem -> { + SyncopeClientException invalidMapping = + SyncopeClientException.build(ClientExceptionType.InvalidMapping); try { PlainSchemaTO schema = schemaLogic.read(SchemaType.PLAIN, scimItem.getExtAttrName()); - SyncopeClientException invalidMapping = - SyncopeClientException.build(ClientExceptionType.InvalidMapping); if (!scimItem.getMandatoryCondition().equals(schema.getMandatoryCondition())) { invalidMapping.getElements().add('\'' + scimItem.getIntAttrName() + "' should " + (Boolean.parseBoolean(schema.getMandatoryCondition()) ? "" : "not") @@ -114,14 +114,8 @@ public void set(final SCIMConf conf) { throw invalidMapping; } } catch (NotFoundException e) { - PlainSchemaTO schema = schemaLogic.read(SchemaType.VIRTUAL, scimItem.getExtAttrName()); - if (scimItem.isMutability() != schema.isReadonly()) { - SyncopeClientException invalidMapping = - SyncopeClientException.build(ClientExceptionType.InvalidMapping); - invalidMapping.getElements().add('\'' + scimItem.getIntAttrName() - + "' should " + (schema.isReadonly() ? "" : "not") + " be readonly"); - throw invalidMapping; - } + invalidMapping.getElements().add('\'' + scimItem.getIntAttrName() + "' is not found"); + throw invalidMapping; } }); } diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java index edfbfaec5a8..230656a3fdb 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java @@ -248,8 +248,6 @@ public void initialize(final ConfigurableApplicationContext ctx) { protected static final String RESOURCE_NAME_DBPULL = "resource-db-pull"; - protected static final String RESOURCE_NAME_DBVIRATTR = "resource-db-virattr"; - protected static final String RESOURCE_NAME_NOPROPAGATION = "ws-target-resource-nopropagation"; protected static final String RESOURCE_NAME_NOPROPAGATION2 = "ws-target-resource-nopropagation2"; diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractTypesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractTypesITCase.java index eb2ace111fd..330af289c5a 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractTypesITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AbstractTypesITCase.java @@ -29,9 +29,6 @@ public abstract class AbstractTypesITCase extends AbstractConsoleITCase { protected static final String PLAIN_DATATABLE_PATH = "body:content:tabbedPanel:panel:" + "accordionPanel:tabs:0:body:content:container:content:searchContainer:resultTable"; - protected static final String VIRTUAL_DATATABLE_PATH = "body:content:tabbedPanel:panel:" - + "accordionPanel:tabs:2:body:content:container:content:searchContainer:resultTable"; - protected static final String DATATABLE_PATH = "body:content:tabbedPanel:panel:container:content:searchContainer:resultTable"; @@ -76,15 +73,6 @@ protected void browsingToPlainSchemas() { AjaxFallbackDataTable.class); } - protected void browsingToVirtualSchemas() { - TESTER.clickLink("body:configurationLI:configurationUL:typesLI:types", false); - TESTER.assertRenderedPage(Types.class); - - TESTER.clickLink("body:content:tabbedPanel:tabs-container:tabs:3:link"); - TESTER.assertComponent(VIRTUAL_DATATABLE_PATH + ":tablePanel:groupForm:checkgroup:dataTable", - AjaxFallbackDataTable.class); - } - protected void createAnyTypeClassWithoutSchema(final String name) { browsingToAnyTypeClasses(); diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/GroupsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/GroupsITCase.java index 69122a42a9a..b3e46d24a0b 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/GroupsITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/GroupsITCase.java @@ -207,10 +207,6 @@ public void editGroup() { assertNotNull(formTester); formTester.submit("buttons:next"); - formTester = TESTER.newFormTester(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form"); - assertNotNull(formTester); - formTester.submit("buttons:next"); - formTester = TESTER.newFormTester(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form"); assertNotNull(formTester); formTester.submit("buttons:finish"); diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SchemasITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SchemasITCase.java index 399d9512904..69c4a0954c2 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SchemasITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/SchemasITCase.java @@ -168,57 +168,4 @@ public void deletePlainSchema() { assertNull(findComponentByProp(KEY, PLAIN_DATATABLE_PATH, schemaName)); } - - @Test - public void createVirtualSchema() { - browsingToVirtualSchemas(); - TESTER.clickLink( - "body:content:tabbedPanel:panel:accordionPanel:tabs:2:body:content:container:content:add"); - - TESTER.assertComponent( - "body:content:tabbedPanel:panel:accordionPanel:tabs:2:body:content:outerObjectsRepeater:0:outer", - Modal.class); - - FormTester formTester = TESTER.newFormTester("body:content:tabbedPanel:panel:" - + "accordionPanel:tabs:2:body:content:outerObjectsRepeater:0:outer:form"); - - formTester.setValue("content:form:view:details:resource:dropDownChoiceField", "0"); - TESTER.executeAjaxEvent("body:content:tabbedPanel:panel:" - + "accordionPanel:tabs:2:body:content:outerObjectsRepeater:0:outer:form:" - + "content:form:view:details:resource:dropDownChoiceField", Constants.ON_CHANGE); - - formTester.setValue("content:form:view:details:key:textField", "mynewvir"); - formTester.setValue("content:form:view:details:resource:dropDownChoiceField", "0"); - formTester.setValue("content:form:view:details:anyType:dropDownChoiceField", "0"); - formTester.setValue("content:form:view:details:extAttrName:textField", "virattr"); - - TESTER.executeAjaxEvent("body:content:tabbedPanel:panel:accordionPanel:tabs:2:" - + "body:content:outerObjectsRepeater:0:outer:form:content:form:buttons:next", Constants.ON_CLICK); - - formTester = TESTER.newFormTester("body:content:tabbedPanel:panel:" - + "accordionPanel:tabs:2:body:content:outerObjectsRepeater:0:outer:form"); - formTester.submit("content:form:buttons:finish"); - - assertSuccessMessage(); - TESTER.cleanupFeedbackMessages(); - TESTER.assertRenderedPage(Types.class); - - Component result = findComponentByProp(KEY, VIRTUAL_DATATABLE_PATH, "mynewvir"); - TESTER.executeAjaxEvent(result.getPageRelativePath(), Constants.ON_CLICK); - - TESTER.getRequest().addParameter("confirm", "true"); - TESTER.clickLink( - "body:content:tabbedPanel:panel:accordionPanel:tabs:2:body:content:outerObjectsRepeater:1:outer:" - + "container:content:togglePanelContainer:container:actions:actions:actionRepeater:1:action:action"); - - TESTER.executeAjaxEvent(TESTER.getComponentFromLastRenderedPage( - "body:content:tabbedPanel:panel:accordionPanel:tabs:2:body:content:outerObjectsRepeater:1:outer:" - + "container:content:togglePanelContainer:container:actions:actions:actionRepeater:1:action:action"), - Constants.ON_CLICK); - - assertSuccessMessage(); - TESTER.cleanupFeedbackMessages(); - - assertNull(findComponentByProp(KEY, VIRTUAL_DATATABLE_PATH, "mynewvir")); - } } diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java index 17e5ee32112..d5824b1bd34 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java @@ -152,10 +152,6 @@ public void editRelationships() { assertNotNull(formTester); formTester.submit("buttons:next"); - formTester = TESTER.newFormTester(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form"); - assertNotNull(formTester); - formTester.submit("buttons:next"); - // Add first RELATIONSHIP addRelationship("Canon MF 8030cn"); component = TESTER.getComponentFromLastRenderedPage(TAB_PANEL + "outerObjectsRepeater:0:outer" diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AnyTypeClassITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AnyTypeClassITCase.java index 0c9efef9254..4bc63b6b19e 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AnyTypeClassITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AnyTypeClassITCase.java @@ -47,7 +47,6 @@ public void read() { assertFalse(minimalGroup.getPlainSchemas().isEmpty()); assertFalse(minimalGroup.getDerSchemas().isEmpty()); - assertFalse(minimalGroup.getVirSchemas().isEmpty()); } @Test @@ -81,7 +80,6 @@ public void crud() { assertNotNull(newClass); assertFalse(newClass.getPlainSchemas().isEmpty()); assertTrue(newClass.getDerSchemas().isEmpty()); - assertTrue(newClass.getVirSchemas().isEmpty()); newClass.getDerSchemas().add(derSchema.getKey()); ANY_TYPE_CLASS_SERVICE.update(newClass); @@ -90,7 +88,6 @@ public void crud() { assertNotNull(newClass); assertFalse(newClass.getPlainSchemas().isEmpty()); assertFalse(newClass.getDerSchemas().isEmpty()); - assertTrue(newClass.getVirSchemas().isEmpty()); assertEquals(newClass.getKey(), SCHEMA_SERVICE.read(SchemaType.PLAIN, plainSchema.getKey()).getAnyTypeClass()); assertEquals(newClass.getKey(), SCHEMA_SERVICE.read(SchemaType.DERIVED, derSchema.getKey()).getAnyTypeClass()); diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java index 29390422b35..1f3de649779 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GroupITCase.java @@ -72,7 +72,6 @@ import org.apache.syncope.common.lib.to.PagedResult; import org.apache.syncope.common.lib.to.PlainSchemaTO; import org.apache.syncope.common.lib.to.PropagationStatus; -import org.apache.syncope.common.lib.to.Provision; import org.apache.syncope.common.lib.to.ProvisioningResult; import org.apache.syncope.common.lib.to.ResourceTO; import org.apache.syncope.common.lib.to.TypeExtensionTO; @@ -116,16 +115,10 @@ public static GroupCR getSample(final String name) { @Test public void create() { GroupCR groupCR = getSample("lastGroup"); - groupCR.getVirAttrs().add(attr("rvirtualdata", "rvirtualvalue")); groupCR.setGroupOwner("f779c0d4-633b-4be5-8f57-32eb478a3ca5"); GroupTO groupTO = createGroup(groupCR).getEntity(); assertNotNull(groupTO); - - assertNotNull(groupTO.getVirAttr("rvirtualdata").orElseThrow().getValues()); - assertFalse(groupTO.getVirAttr("rvirtualdata").orElseThrow().getValues().isEmpty()); - assertEquals("rvirtualvalue", groupTO.getVirAttr("rvirtualdata").orElseThrow().getValues().getFirst()); - assertTrue(groupTO.getResources().contains(RESOURCE_NAME_LDAP)); ConnObject connObjectTO = @@ -1042,10 +1035,6 @@ public void issueSYNCOPE632() { newLDAP.setKey("new-ldap"); newLDAP.setPropagationPriority(0); - for (Provision provision : newLDAP.getProvisions()) { - provision.getVirSchemas().clear(); - } - Mapping mapping = newLDAP.getProvision(AnyTypeKind.GROUP.name()).orElseThrow().getMapping(); Item connObjectKey = mapping.getConnObjectKeyItem().orElseThrow(); diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java index 005d7a270f4..8fd15f5a363 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java @@ -658,7 +658,6 @@ public void issueSYNCOPE1430() throws ParseException { Provision provision = ldap.getProvision(AnyTypeKind.USER.name()).orElse(null); assertNotNull(provision); provision.getMapping().getItems().removeIf(item -> "mail".equals(item.getExtAttrName())); - provision.getVirSchemas().clear(); // Date -> long (JEXL expression) -> string Item loginDateForJexlAsLong = new Item(); @@ -737,7 +736,7 @@ public void issueSYNCOPE1430() throws ParseException { Attribute carLicense = AttributeUtil.find("carLicense", propagationAttrs); assertNotNull(carLicense); assertEquals(DateTimeFormatter.ISO_LOCAL_DATE.format(loginDate.plusDays(1)), - carLicense.getValue().getFirst()); + carLicense.getValue().getFirst()); } finally { try { RESOURCE_SERVICE.delete(ldap.getKey()); @@ -767,13 +766,11 @@ public void issueSYNCOPE1473() throws ParseException { Provision provisionGroup = SerializationUtils.clone(ldap.getProvision(AnyTypeKind.GROUP.name()).orElse(null)); assertNotNull(provisionGroup); - provisionGroup.getVirSchemas().clear(); Provision provisionUser = SerializationUtils.clone(ldap.getProvision(AnyTypeKind.USER.name()).orElse(null)); assertNotNull(provisionUser); provisionUser.getMapping().getItems().removeIf(item -> "mail".equals(item.getExtAttrName())); - provisionUser.getVirSchemas().clear(); Item ldapGroups = new Item(); ldapGroups.setPurpose(MappingPurpose.PROPAGATION); @@ -857,7 +854,6 @@ public void issueSYNCOPE1567() { // 1. clone the LDAP resource and add the relationships mapping Provision provision = SerializationUtils.clone(ldap.getProvision(AnyTypeKind.USER.name()).orElseThrow()); assertNotNull(provision); - provision.getVirSchemas().clear(); Item relationships = new Item(); relationships.setPurpose(MappingPurpose.PROPAGATION); @@ -917,7 +913,6 @@ public void issueSYNCOPE1605() throws ParseException { Provision provisionGroup = SerializationUtils.clone(ldap.getProvision(AnyTypeKind.GROUP.name()).orElse(null)); assertNotNull(provisionGroup); - provisionGroup.getVirSchemas().clear(); provisionGroup.getMapping().getItems().clear(); Item item = new Item(); diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java index e9149da0fef..d42afeb4eb8 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java @@ -452,10 +452,6 @@ public void reconcileFromLDAP() { // SYNCOPE-898 assertEquals("/odd", matchingUsers.getResult().getFirst().getRealm()); - // Check for SYNCOPE-436 - assertEquals("pullFromLDAP", - matchingUsers.getResult().getFirst().getVirAttr("virtualReadOnly"). - orElseThrow().getValues().getFirst()); // Check for SYNCOPE-270 assertNotNull(matchingUsers.getResult().getFirst().getPlainAttr("obscure")); // Check for SYNCOPE-123 @@ -814,7 +810,6 @@ public void remediation() { Provision provision = ldap.getProvision(AnyTypeKind.USER.name()).orElseThrow(); provision.getMapping().getItems().removeIf(item -> "userId".equals(item.getIntAttrName())); provision.getMapping().getItems().removeIf(item -> "mail".equals(item.getIntAttrName())); - provision.getVirSchemas().clear(); ldap.getProvisions().clear(); ldap.getProvisions().add(provision); @@ -900,7 +895,6 @@ public void remediationSinglePull() throws IOException { Provision provision = ldap.getProvision(AnyTypeKind.USER.name()).orElseThrow(); provision.getMapping().getItems().removeIf(item -> "userId".equals(item.getIntAttrName())); provision.getMapping().getItems().removeIf(item -> "email".equals(item.getIntAttrName())); - provision.getVirSchemas().clear(); ldap.getProvisions().clear(); ldap.getProvisions().add(provision); @@ -1228,55 +1222,6 @@ public void issueSYNCOPE272() { } } - @Test - public void issueSYNCOPE307() { - assumeFalse(IS_EXT_SEARCH_ENABLED); - - UserCR userCR = UserITCase.getUniqueSample("s307@apache.org"); - userCR.setUsername("test0"); - userCR.getPlainAttrs().removeIf(attr -> "firstname".equals(attr.getSchema())); - userCR.getPlainAttrs().add(attr("firstname", "nome0")); - userCR.getAuxClasses().add("csv"); - - userCR.getResources().clear(); - userCR.getResources().add(RESOURCE_NAME_WS2); - - UserTO userTO = createUser(userCR).getEntity(); - assertNotNull(userTO); - - userTO = USER_SERVICE.read(userTO.getKey()); - assertTrue(userTO.getVirAttrs().isEmpty()); - - // Update pull task - PullTaskTO task = TASK_SERVICE.read(TaskType.PULL, "38abbf9e-a1a3-40a1-a15f-7d0ac02f47f1", true); - assertNotNull(task); - - UserTO template = new UserTO(); - template.setPassword("'password123'"); - template.getResources().add(RESOURCE_NAME_DBVIRATTR); - template.getVirAttrs().add(attr("virtualdata", "'virtualvalue'")); - - task.getTemplates().put(AnyTypeKind.USER.name(), template); - - TASK_SERVICE.update(TaskType.PULL, task); - - // exec task: one user from CSV will match the user created above and template will be applied - ExecTO exec = execSchedTask(TASK_SERVICE, TaskType.PULL, task.getKey(), MAX_WAIT_SECONDS, false); - - // check that template was successfully applied - // 1. propagation to db - assertEquals(ExecStatus.SUCCESS.name(), exec.getStatus()); - - JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource); - String value = queryForObject(jdbcTemplate, - MAX_WAIT_SECONDS, "SELECT USERNAME FROM testpull WHERE ID=?", String.class, userTO.getKey()); - assertEquals("virtualvalue", value); - - // 2. virtual attribute - userTO = USER_SERVICE.read(userTO.getKey()); - assertEquals("virtualvalue", userTO.getVirAttr("virtualdata").orElseThrow().getValues().getFirst()); - } - @Test public void issueSYNCOPE313DB() throws Exception { // 1. create user in DB diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java index 975ec38bc5c..14a05dac2c1 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ResourceITCase.java @@ -95,7 +95,7 @@ private static ResourceTO buildResourceTO(final String resourceKey) { @Test public void getPropagationActionsClasses() { Set actions = ANONYMOUS_CLIENT.platform(). - getJavaImplInfo(IdMImplementationType.PROPAGATION_ACTIONS).get().getClasses(); + getJavaImplInfo(IdMImplementationType.PROPAGATION_ACTIONS).orElseThrow().getClasses(); assertNotNull(actions); assertFalse(actions.isEmpty()); } @@ -210,18 +210,18 @@ public void createWithSingleMappingItem() { ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class); assertNotNull(actual); - assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).get().getMapping()); - assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).get().getMapping().getItems()); - assertNotNull(actual.getProvision(AnyTypeKind.GROUP.name()).get().getMapping()); - assertNotNull(actual.getProvision(AnyTypeKind.GROUP.name()).get().getMapping().getItems()); + assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).orElseThrow().getMapping()); + assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).orElseThrow().getMapping().getItems()); + assertNotNull(actual.getProvision(AnyTypeKind.GROUP.name()).orElseThrow().getMapping()); + assertNotNull(actual.getProvision(AnyTypeKind.GROUP.name()).orElseThrow().getMapping().getItems()); assertEquals( MappingPurpose.PULL, - actual.getProvision(AnyTypeKind.GROUP.name()).get().getMapping(). - getConnObjectKeyItem().get().getPurpose()); + actual.getProvision(AnyTypeKind.GROUP.name()).orElseThrow().getMapping(). + getConnObjectKeyItem().orElseThrow().getPurpose()); assertEquals( MappingPurpose.PROPAGATION, - actual.getProvision(AnyTypeKind.USER.name()).get().getMapping(). - getConnObjectKeyItem().get().getPurpose()); + actual.getProvision(AnyTypeKind.USER.name()).orElseThrow().getMapping(). + getConnObjectKeyItem().orElseThrow().getPurpose()); } @Test @@ -376,7 +376,7 @@ public void update() { assertNotNull(actual); // check for existence - Collection mapItems = actual.getProvision(AnyTypeKind.USER.name()).get().getMapping().getItems(); + Collection mapItems = actual.getProvision(AnyTypeKind.USER.name()).orElseThrow().getMapping().getItems(); assertNotNull(mapItems); assertEquals(4, mapItems.size()); } @@ -404,7 +404,7 @@ public void syncToken() { try { // create a new resource resource = createResource(resource); - assertNull(resource.getProvision(PRINTER).get().getSyncToken()); + assertNull(resource.getProvision(PRINTER).orElseThrow().getSyncToken()); // create some object on the new resource anyObject = createAnyObject(anyObjectCR).getEntity(); @@ -413,13 +413,13 @@ public void syncToken() { RESOURCE_SERVICE.setLatestSyncToken(resource.getKey(), PRINTER); resource = RESOURCE_SERVICE.read(resource.getKey()); - assertNotNull(resource.getProvision(PRINTER).get().getSyncToken()); + assertNotNull(resource.getProvision(PRINTER).orElseThrow().getSyncToken()); // remove sync token RESOURCE_SERVICE.removeSyncToken(resource.getKey(), PRINTER); resource = RESOURCE_SERVICE.read(resource.getKey()); - assertNull(resource.getProvision(PRINTER).get().getSyncToken()); + assertNull(resource.getProvision(PRINTER).orElseThrow().getSyncToken()); } finally { if (anyObject != null) { ANY_OBJECT_SERVICE.delete(anyObject.getKey()); @@ -496,13 +496,11 @@ public void list() { @Test public void read() { - ResourceTO resource = RESOURCE_SERVICE.read(RESOURCE_NAME_DBVIRATTR); + ResourceTO resource = RESOURCE_SERVICE.read(RESOURCE_NAME_DBPULL); assertNotNull(resource); - Optional provision = resource.getProvision(AnyTypeKind.USER.name()); - assertTrue(provision.isPresent()); - assertFalse(provision.get().getMapping().getItems().isEmpty()); - assertFalse(provision.get().getMapping().getLinkingItems().isEmpty()); + Provision provision = resource.getProvision(AnyTypeKind.USER.name()).orElseThrow(); + assertFalse(provision.getMapping().getItems().isEmpty()); } @Test @@ -565,14 +563,14 @@ public void issueSYNCOPE360() { ResourceTO resource = RESOURCE_SERVICE.read(name); assertNotNull(resource); - assertNotNull(resource.getProvision(AnyTypeKind.USER.name()).get().getMapping()); + assertNotNull(resource.getProvision(AnyTypeKind.USER.name()).orElseThrow().getMapping()); - resource.getProvision(AnyTypeKind.USER.name()).get().setMapping(null); + resource.getProvision(AnyTypeKind.USER.name()).orElseThrow().setMapping(null); RESOURCE_SERVICE.update(resource); resource = RESOURCE_SERVICE.read(name); assertNotNull(resource); - assertNull(resource.getProvision(AnyTypeKind.USER.name()).get().getMapping()); + assertNull(resource.getProvision(AnyTypeKind.USER.name()).orElseThrow().getMapping()); } @Test @@ -606,7 +604,7 @@ public void issueSYNCOPE368() { resourceTO = createResource(resourceTO); assertNotNull(resourceTO); - assertEquals(2, resourceTO.getProvision(AnyTypeKind.GROUP.name()).get().getMapping().getItems().size()); + assertEquals(2, resourceTO.getProvision(AnyTypeKind.GROUP.name()).orElseThrow().getMapping().getItems().size()); } @Test @@ -655,13 +653,13 @@ public void issueSYNCOPE493() { ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class); assertNotNull(actual); - assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).get().getMapping()); - assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).get().getMapping().getItems()); + assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).orElseThrow().getMapping()); + assertNotNull(actual.getProvision(AnyTypeKind.USER.name()).orElseThrow().getMapping().getItems()); assertEquals( MappingPurpose.PROPAGATION, - actual.getProvision(AnyTypeKind.USER.name()).get().getMapping(). - getConnObjectKeyItem().get().getPurpose()); - actual.getProvision(AnyTypeKind.USER.name()).get().getMapping().getItems().stream(). + actual.getProvision(AnyTypeKind.USER.name()).orElseThrow().getMapping(). + getConnObjectKeyItem().orElseThrow().getPurpose()); + actual.getProvision(AnyTypeKind.USER.name()).orElseThrow().getMapping().getItems().stream(). filter(itemTO -> ("gender".equals(itemTO.getIntAttrName()))). forEach(itemTO -> assertEquals(MappingPurpose.NONE, itemTO.getPurpose())); } diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java index 803bdc64b57..71f763101f1 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java @@ -850,7 +850,6 @@ public void suspendReactivateOnResource() { public void updateMultivalueAttribute() { UserCR userCR = getUniqueSample("multivalue@syncope.apache.org"); userCR.getResources().clear(); - userCR.getVirAttrs().clear(); UserTO userTO = createUser(userCR).getEntity(); assertNotNull(userTO); @@ -911,7 +910,6 @@ public void groupAttrPropagation() { UserCR userCR = getUniqueSample("checkGroupAttrPropagation@syncope.apache.org"); userCR.getResources().clear(); userCR.getMemberships().clear(); - userCR.getVirAttrs().clear(); userCR.getAuxClasses().add("csv"); @@ -1099,7 +1097,6 @@ public void unlink() throws IOException { UserCR userCR = getUniqueSample("unlink@syncope.apache.org"); userCR.getResources().clear(); userCR.getMemberships().clear(); - userCR.getVirAttrs().clear(); userCR.getAuxClasses().add("csv"); userCR.getResources().add(RESOURCE_NAME_CSV); @@ -1124,7 +1121,6 @@ public void link() throws IOException { UserCR userCR = getUniqueSample("link@syncope.apache.org"); userCR.getResources().clear(); userCR.getMemberships().clear(); - userCR.getVirAttrs().clear(); userCR.getAuxClasses().add("csv"); UserTO actual = createUser(userCR).getEntity(); @@ -1160,7 +1156,6 @@ public void unassign() throws IOException { UserCR userCR = getUniqueSample("unassign@syncope.apache.org"); userCR.getResources().clear(); userCR.getMemberships().clear(); - userCR.getVirAttrs().clear(); userCR.getAuxClasses().add("csv"); userCR.getResources().add(RESOURCE_NAME_CSV); @@ -1190,7 +1185,6 @@ public void assign() throws IOException { UserCR userCR = getUniqueSample("assign@syncope.apache.org"); userCR.getResources().clear(); userCR.getMemberships().clear(); - userCR.getVirAttrs().clear(); userCR.getAuxClasses().add("csv"); UserTO actual = createUser(userCR).getEntity(); @@ -1220,7 +1214,6 @@ public void deprovision() throws IOException { UserCR userCR = getUniqueSample("deprovision@syncope.apache.org"); userCR.getResources().clear(); userCR.getMemberships().clear(); - userCR.getVirAttrs().clear(); userCR.getAuxClasses().add("csv"); userCR.getResources().add(RESOURCE_NAME_CSV); @@ -1250,7 +1243,6 @@ public void provision() throws IOException { UserCR userCR = getUniqueSample("provision@syncope.apache.org"); userCR.getResources().clear(); userCR.getMemberships().clear(); - userCR.getVirAttrs().clear(); userCR.getAuxClasses().add("csv"); UserTO actual = createUser(userCR).getEntity(); @@ -1280,7 +1272,6 @@ public void deprovisionUnlinked() throws IOException { UserCR userCR = getUniqueSample("provision@syncope.apache.org"); userCR.getResources().clear(); userCR.getMemberships().clear(); - userCR.getVirAttrs().clear(); userCR.getAuxClasses().add("csv"); UserTO actual = createUser(userCR).getEntity(); diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java index b02a13d2a16..9765a45e485 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java @@ -309,7 +309,6 @@ public void issueSYNCOPE108() { UserCR userCR = UserITCase.getUniqueSample("syncope108@syncope.apache.org"); userCR.getResources().clear(); userCR.getMemberships().clear(); - userCR.getVirAttrs().clear(); userCR.getAuxClasses().add("csv"); userCR.getMemberships().add(new MembershipTO.Builder("0626100b-a4ba-4e00-9971-86fad52a6216").build()); @@ -385,7 +384,6 @@ public void issueSYNCOPE108() { public void issueSYNCOPE185() { // 1. create user with LDAP resource, successfully propagated UserCR userCR = UserITCase.getSample("syncope185@syncope.apache.org"); - userCR.getVirAttrs().clear(); userCR.getResources().add(RESOURCE_NAME_LDAP); ProvisioningResult result = createUser(userCR); @@ -427,36 +425,6 @@ public void issueSYNCOPE51() { } } - @Test - public void issueSYNCOPE267() { - // ---------------------------------- - // create user and check virtual attribute value propagation - // ---------------------------------- - UserCR userCR = UserITCase.getUniqueSample("syncope267@apache.org"); - userCR.getVirAttrs().add(attr("virtualdata", "virtualvalue")); - userCR.getResources().clear(); - userCR.getResources().add(RESOURCE_NAME_DBVIRATTR); - - ProvisioningResult result = createUser(userCR); - assertNotNull(result); - assertFalse(result.getPropagationStatuses().isEmpty()); - assertEquals(RESOURCE_NAME_DBVIRATTR, result.getPropagationStatuses().getFirst().getResource()); - assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().getFirst().getStatus()); - UserTO userTO = result.getEntity(); - - ConnObject connObjectTO = - RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_DBVIRATTR, AnyTypeKind.USER.name(), userTO.getKey()); - assertNotNull(connObjectTO); - assertEquals("virtualvalue", connObjectTO.getAttr("USERNAME").orElseThrow().getValues().getFirst()); - // ---------------------------------- - - userTO = USER_SERVICE.read(userTO.getKey()); - - assertNotNull(userTO); - assertEquals(1, userTO.getVirAttrs().size()); - assertEquals("virtualvalue", userTO.getVirAttrs().iterator().next().getValues().getFirst()); - } - @Test public void issueSYNCOPE266() { UserCR userCR = UserITCase.getUniqueSample("syncope266@apache.org"); @@ -1148,7 +1116,6 @@ public void issueSYNCOPE391() { userCR = UserITCase.getUniqueSample("syncope391@syncope.apache.org"); userCR.setPassword("passwordTESTNULL1"); userCR.setStorePassword(false); - userCR.getVirAttrs().clear(); userCR.getAuxClasses().add("csv"); userCR.getResources().add(RESOURCE_NAME_CSV); @@ -1168,7 +1135,6 @@ public void issueSYNCOPE391() { // 4. create user and propagate password on resource-csv and on Syncope local storage userCR = UserITCase.getUniqueSample("syncope391@syncope.apache.org"); userCR.setPassword("passwordTESTNULL1"); - userCR.getVirAttrs().clear(); userCR.getAuxClasses().add("csv"); userCR.getResources().add(RESOURCE_NAME_CSV); @@ -1199,7 +1165,6 @@ public void issueSYNCOPE391() { userCR = UserITCase.getUniqueSample("syncope391@syncope.apache.org"); userCR.setPassword(null); userCR.setStorePassword(false); - userCR.getVirAttrs().clear(); userCR.getAuxClasses().add("csv"); userCR.getResources().add(RESOURCE_NAME_CSV); @@ -1220,7 +1185,6 @@ public void issueSYNCOPE647() { UserCR userCR = UserITCase.getUniqueSample("syncope647@syncope.apache.org"); userCR.getResources().clear(); userCR.getMemberships().clear(); - userCR.getVirAttrs().clear(); userCR.getAuxClasses().add("csv"); userCR.getAuxClasses().add("generic membership"); @@ -1381,10 +1345,7 @@ public void issueSYNCOPE710() { @Test public void issueSYNCOPE881() { // 1. create group and assign LDAP - GroupCR groupCR = GroupITCase.getSample("syncope881G"); - groupCR.getVirAttrs().add(attr("rvirtualdata", "rvirtualvalue")); - - GroupTO group = createGroup(groupCR).getEntity(); + GroupTO group = createGroup(GroupITCase.getSample("syncope881G")).getEntity(); assertNotNull(group); assertNotNull(RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), group.getKey())); @@ -1451,7 +1412,7 @@ public void issueSYNCOPE1166() { UserUR userUR = new UserUR(); userUR.setKey(userTO.getKey()); - // resource-ldap has password mapped, resource-db-virattr does not + // resource-ldap has password mapped userUR.setPassword(new PasswordPatch.Builder(). onSyncope(true). resource(RESOURCE_NAME_LDAP). @@ -1459,16 +1420,12 @@ public void issueSYNCOPE1166() { userUR.getResources().add(new StringPatchItem.Builder(). operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_LDAP).build()); - userUR.getResources().add(new StringPatchItem.Builder(). - operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_DBVIRATTR).build()); ProvisioningResult result = updateUser(userUR); assertNotNull(result); - assertEquals(2, result.getPropagationStatuses().size()); - assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource()); - assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus()); - assertEquals(RESOURCE_NAME_DBVIRATTR, result.getPropagationStatuses().get(1).getResource()); - assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(1).getStatus()); + assertEquals(1, result.getPropagationStatuses().size()); + assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().getFirst().getResource()); + assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().getFirst().getStatus()); } @Test diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java index 396ae1994c0..f14f79aacdf 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java @@ -701,7 +701,6 @@ public void issueSYNCOPE15() { UserCR userCR = UserITCase.getUniqueSample("issueSYNCOPE15@syncope.apache.org"); userCR.getResources().clear(); - userCR.getVirAttrs().clear(); userCR.getMemberships().clear(); // Users with group 0cbcabd2-4410-4b6b-8f05-a052b451d18f are defined in workflow as subject to approval diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java deleted file mode 100644 index 900fc6f259e..00000000000 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirAttrITCase.java +++ /dev/null @@ -1,697 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.fit.core; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assumptions.assumeFalse; - -import jakarta.ws.rs.core.GenericType; -import jakarta.ws.rs.core.Response; -import java.util.Locale; -import java.util.Map; -import java.util.Optional; -import org.apache.commons.lang3.SerializationUtils; -import org.apache.syncope.common.lib.Attr; -import org.apache.syncope.common.lib.SyncopeClientException; -import org.apache.syncope.common.lib.request.GroupCR; -import org.apache.syncope.common.lib.request.PasswordPatch; -import org.apache.syncope.common.lib.request.StatusR; -import org.apache.syncope.common.lib.request.StringPatchItem; -import org.apache.syncope.common.lib.request.UserCR; -import org.apache.syncope.common.lib.request.UserUR; -import org.apache.syncope.common.lib.to.AnyTypeClassTO; -import org.apache.syncope.common.lib.to.ConnInstanceTO; -import org.apache.syncope.common.lib.to.ConnObject; -import org.apache.syncope.common.lib.to.GroupTO; -import org.apache.syncope.common.lib.to.Item; -import org.apache.syncope.common.lib.to.Mapping; -import org.apache.syncope.common.lib.to.MembershipTO; -import org.apache.syncope.common.lib.to.Provision; -import org.apache.syncope.common.lib.to.ProvisioningResult; -import org.apache.syncope.common.lib.to.ResourceTO; -import org.apache.syncope.common.lib.to.UserTO; -import org.apache.syncope.common.lib.to.VirSchemaTO; -import org.apache.syncope.common.lib.types.AnyTypeKind; -import org.apache.syncope.common.lib.types.ConnConfProperty; -import org.apache.syncope.common.lib.types.ExecStatus; -import org.apache.syncope.common.lib.types.MappingPurpose; -import org.apache.syncope.common.lib.types.PatchOperation; -import org.apache.syncope.common.lib.types.SchemaType; -import org.apache.syncope.common.lib.types.StatusRType; -import org.apache.syncope.common.rest.api.service.AnyTypeClassService; -import org.apache.syncope.common.rest.api.service.ResourceService; -import org.apache.syncope.fit.AbstractITCase; -import org.identityconnectors.framework.common.objects.ObjectClass; -import org.junit.jupiter.api.Test; -import org.springframework.jdbc.core.JdbcTemplate; - -public class VirAttrITCase extends AbstractITCase { - - @Test - public void issueSYNCOPE16() { - UserCR userCR = UserITCase.getUniqueSample("issue16@apache.org"); - userCR.getVirAttrs().add(attr("virtualdata", "virtualvalue")); - userCR.getResources().add(RESOURCE_NAME_DBVIRATTR); - userCR.getMemberships().add(new MembershipTO.Builder("f779c0d4-633b-4be5-8f57-32eb478a3ca5").build()); - - // 1. create user - UserTO userTO = createUser(userCR).getEntity(); - assertNotNull(userTO); - - // 2. check for virtual attribute value - userTO = USER_SERVICE.read(userTO.getKey()); - assertNotNull(userTO); - assertEquals("virtualvalue", userTO.getVirAttr("virtualdata").get().getValues().getFirst()); - - UserUR userUR = new UserUR(); - userUR.setKey(userTO.getKey()); - userUR.getVirAttrs().add(attr("virtualdata", "virtualupdated")); - - // 3. update virtual attribute - userTO = updateUser(userUR).getEntity(); - assertNotNull(userTO); - - // 4. check for virtual attribute value - userTO = USER_SERVICE.read(userTO.getKey()); - assertNotNull(userTO); - assertEquals("virtualupdated", userTO.getVirAttr("virtualdata").get().getValues().getFirst()); - } - - @Test - public void issueSYNCOPE260() { - // create new virtual schema for the resource below - ResourceTO ws2 = RESOURCE_SERVICE.read(RESOURCE_NAME_WS2); - Provision provision = ws2.getProvision(AnyTypeKind.USER.name()).get(); - assertNotNull(provision); - - VirSchemaTO virSchema = new VirSchemaTO(); - virSchema.setKey("syncope260" + getUUIDString()); - virSchema.setExtAttrName("companyName"); - virSchema.setResource(RESOURCE_NAME_WS2); - virSchema.setAnyType(provision.getAnyType()); - virSchema = createSchema(SchemaType.VIRTUAL, virSchema); - assertNotNull(virSchema); - - AnyTypeClassTO newClass = new AnyTypeClassTO(); - newClass.setKey("syncope260" + getUUIDString()); - newClass.getVirSchemas().add(virSchema.getKey()); - Response response = ANY_TYPE_CLASS_SERVICE.create(newClass); - assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode()); - newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class); - - // ---------------------------------- - // create user and check virtual attribute value propagation - // ---------------------------------- - UserCR userCR = UserITCase.getUniqueSample("260@a.com"); - userCR.getAuxClasses().add(newClass.getKey()); - userCR.getVirAttrs().add(attr(virSchema.getKey(), "virtualvalue")); - userCR.getResources().add(RESOURCE_NAME_WS2); - - ProvisioningResult result = createUser(userCR); - assertNotNull(result); - assertFalse(result.getPropagationStatuses().isEmpty()); - assertEquals(RESOURCE_NAME_WS2, result.getPropagationStatuses().getFirst().getResource()); - assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().getFirst().getStatus()); - UserTO userTO = result.getEntity(); - - ConnObject connObjectTO = - RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey()); - assertEquals("virtualvalue", connObjectTO.getAttr("COMPANYNAME").get().getValues().getFirst()); - // ---------------------------------- - - // ---------------------------------- - // update user virtual attribute and check virtual attribute value update propagation - // ---------------------------------- - UserUR userUR = new UserUR(); - userUR.setKey(userTO.getKey()); - userUR.getVirAttrs().add(attr(virSchema.getKey(), "virtualvalue2")); - - result = updateUser(userUR); - assertNotNull(result); - assertFalse(result.getPropagationStatuses().isEmpty()); - assertEquals(RESOURCE_NAME_WS2, result.getPropagationStatuses().getFirst().getResource()); - assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().getFirst().getStatus()); - userTO = result.getEntity(); - - connObjectTO = RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey()); - assertEquals("virtualvalue2", connObjectTO.getAttr("COMPANYNAME").get().getValues().getFirst()); - // ---------------------------------- - - // ---------------------------------- - // suspend/reactivate user and check virtual attribute value (unchanged) - // ---------------------------------- - StatusR statusR = new StatusR.Builder(userTO.getKey(), StatusRType.SUSPEND).build(); - userTO = USER_SERVICE.status(statusR).readEntity(new GenericType>() { - }).getEntity(); - assertEquals("suspended", userTO.getStatus()); - - connObjectTO = RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey()); - assertEquals("virtualvalue2", connObjectTO.getAttr("COMPANYNAME").get().getValues().getFirst()); - - statusR = new StatusR.Builder(userTO.getKey(), StatusRType.REACTIVATE).build(); - userTO = USER_SERVICE.status(statusR).readEntity(new GenericType>() { - }).getEntity(); - assertEquals("active", userTO.getStatus()); - - connObjectTO = RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey()); - assertEquals("virtualvalue2", connObjectTO.getAttr("COMPANYNAME").get().getValues().getFirst()); - // ---------------------------------- - - // ---------------------------------- - // update user attribute and check virtual attribute value (unchanged) - // ---------------------------------- - userUR = new UserUR(); - userUR.setKey(userTO.getKey()); - userUR.getPlainAttrs().add(attrAddReplacePatch("surname", "Surname2")); - - result = updateUser(userUR); - assertNotNull(result); - assertFalse(result.getPropagationStatuses().isEmpty()); - assertEquals(RESOURCE_NAME_WS2, result.getPropagationStatuses().getFirst().getResource()); - assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().getFirst().getStatus()); - userTO = result.getEntity(); - - connObjectTO = RESOURCE_SERVICE.readConnObject(RESOURCE_NAME_WS2, AnyTypeKind.USER.name(), userTO.getKey()); - assertEquals("Surname2", connObjectTO.getAttr("SURNAME").get().getValues().getFirst()); - - // virtual attribute value did not change - assertFalse(connObjectTO.getAttr("COMPANYNAME").get().getValues().isEmpty()); - assertEquals("virtualvalue2", connObjectTO.getAttr("COMPANYNAME").get().getValues().getFirst()); - // ---------------------------------- - } - - @Test - public void virAttrCache() { - UserCR userCR = UserITCase.getUniqueSample("virattrcache@apache.org"); - userCR.getVirAttrs().clear(); - - Attr virAttr = new Attr(); - virAttr.setSchema("virtualdata"); - virAttr.getValues().add("virattrcache"); - userCR.getVirAttrs().add(virAttr); - - userCR.getMemberships().clear(); - userCR.getResources().clear(); - userCR.getResources().add(RESOURCE_NAME_DBVIRATTR); - - // 1. create user - UserTO actual = createUser(userCR).getEntity(); - assertNotNull(actual); - - // 2. check for virtual attribute value - actual = USER_SERVICE.read(actual.getKey()); - assertEquals("virattrcache", actual.getVirAttr("virtualdata").get().getValues().getFirst()); - - // 3. update virtual attribute directly - JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource); - String value = queryForObject(jdbcTemplate, - MAX_WAIT_SECONDS, "SELECT USERNAME FROM testpull WHERE ID=?", String.class, actual.getKey()); - assertEquals("virattrcache", value); - - jdbcTemplate.update("UPDATE testpull set USERNAME='virattrcache2' WHERE ID=?", actual.getKey()); - - value = queryForObject(jdbcTemplate, - MAX_WAIT_SECONDS, "SELECT USERNAME FROM testpull WHERE ID=?", String.class, actual.getKey()); - assertEquals("virattrcache2", value); - - // 4. check for cached attribute value - actual = USER_SERVICE.read(actual.getKey()); - assertEquals("virattrcache", actual.getVirAttr("virtualdata").get().getValues().getFirst()); - - UserUR userUR = new UserUR(); - userUR.setKey(actual.getKey()); - userUR.getVirAttrs().add(attr("virtualdata", "virtualupdated")); - - // 5. update virtual attribute - actual = updateUser(userUR).getEntity(); - assertNotNull(actual); - - // 6. check for virtual attribute value - actual = USER_SERVICE.read(actual.getKey()); - assertNotNull(actual); - assertEquals("virtualupdated", actual.getVirAttr("virtualdata").get().getValues().getFirst()); - } - - @Test - public void issueSYNCOPE397() { - assumeFalse(IS_NEO4J_PERSISTENCE); - - ResourceTO csv = RESOURCE_SERVICE.read(RESOURCE_NAME_CSV); - - // change mapping of resource-csv - Mapping origMapping = SerializationUtils.clone(csv.getProvisions().getFirst().getMapping()); - try { - // remove this mapping - Optional email = csv.getProvisions().getFirst().getMapping().getItems().stream(). - filter(item -> "email".equals(item.getIntAttrName())).findFirst(); - if (email.isPresent()) { - csv.getProvisions().getFirst().getMapping().getItems().remove(email.get()); - } - - RESOURCE_SERVICE.update(csv); - csv = RESOURCE_SERVICE.read(RESOURCE_NAME_CSV); - assertNotNull(csv.getProvisions().getFirst().getMapping()); - - // create new virtual schema for the resource below - Provision provision = csv.getProvision(AnyTypeKind.USER.name()).get(); - assertNotNull(provision); - - VirSchemaTO virSchema = new VirSchemaTO(); - virSchema.setKey("syncope397" + getUUIDString()); - virSchema.setExtAttrName("email"); - virSchema.setResource(RESOURCE_NAME_CSV); - virSchema.setAnyType(provision.getAnyType()); - virSchema = createSchema(SchemaType.VIRTUAL, virSchema); - assertNotNull(virSchema); - - AnyTypeClassTO newClass = new AnyTypeClassTO(); - newClass.setKey("syncope397" + getUUIDString()); - newClass.getVirSchemas().add(virSchema.getKey()); - Response response = ANY_TYPE_CLASS_SERVICE.create(newClass); - assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode()); - newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class); - - // create a new user - UserCR userCR = UserITCase.getUniqueSample("397@syncope.apache.org"); - userCR.getAuxClasses().add("csv"); - userCR.getAuxClasses().add(newClass.getKey()); - userCR.getResources().clear(); - userCR.getMemberships().clear(); - - userCR.getVirAttrs().clear(); - userCR.getVirAttrs().add(attr(virSchema.getKey(), "test@testone.org")); - // assign resource-csv to user - userCR.getResources().add(RESOURCE_NAME_CSV); - // save user - UserTO userTO = createUser(userCR).getEntity(); - // make std controls about user - assertNotNull(userTO); - assertTrue(RESOURCE_NAME_CSV.equals(userTO.getResources().iterator().next())); - assertEquals("test@testone.org", userTO.getVirAttrs().iterator().next().getValues().getFirst()); - - // update user - UserTO toBeUpdated = USER_SERVICE.read(userTO.getKey()); - UserUR userUR = new UserUR(); - userUR.setKey(toBeUpdated.getKey()); - userUR.setPassword(new PasswordPatch.Builder().value("password234").build()); - // assign new resource to user - userUR.getResources().add(new StringPatchItem.Builder(). - operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS2).build()); - // modify virtual attribute - userUR.getVirAttrs().add(attr(virSchema.getKey(), "test@testoneone.com")); - - // check Syncope change password - userUR.setPassword(new PasswordPatch.Builder(). - value("password234"). - onSyncope(true). - resource(RESOURCE_NAME_WS2). - build()); - - ProvisioningResult result = updateUser(userUR); - assertNotNull(result); - toBeUpdated = result.getEntity(); - assertTrue(toBeUpdated.getVirAttrs().iterator().next().getValues().contains("test@testoneone.com")); - // check if propagates correctly with assertEquals on size of tasks list - assertEquals(2, result.getPropagationStatuses().size()); - } finally { - // restore mapping of resource-csv - csv.getProvisions().getFirst().setMapping(origMapping); - RESOURCE_SERVICE.update(csv); - } - } - - @Test - public void issueSYNCOPE442() { - UserCR userCR = UserITCase.getUniqueSample("syncope442@apache.org"); - userCR.getVirAttrs().clear(); - - Attr virAttr = new Attr(); - virAttr.setSchema("virtualdata"); - virAttr.getValues().add("virattrcache"); - userCR.getVirAttrs().add(virAttr); - - userCR.getMemberships().clear(); - userCR.getResources().clear(); - userCR.getResources().add(RESOURCE_NAME_DBVIRATTR); - - // 1. create user - UserTO userTO = createUser(userCR).getEntity(); - assertNotNull(userTO); - - // 2. check for virtual attribute value - userTO = USER_SERVICE.read(userTO.getKey()); - assertEquals("virattrcache", userTO.getVirAttr("virtualdata").get().getValues().getFirst()); - - // ---------------------------------------- - // 3. change connector URL so that we are sure that any provided value will come from virtual cache - // ---------------------------------------- - String jdbcURL = null; - ConnInstanceTO connInstanceTO = CONNECTOR_SERVICE.readByResource( - RESOURCE_NAME_DBVIRATTR, Locale.ENGLISH.getLanguage()); - for (ConnConfProperty prop : connInstanceTO.getConf()) { - if ("jdbcUrlTemplate".equals(prop.getSchema().getName())) { - jdbcURL = prop.getValues().getFirst().toString(); - prop.getValues().clear(); - prop.getValues().add("jdbc:h2:tcp://localhost:9092/xxx"); - } - } - - CONNECTOR_SERVICE.update(connInstanceTO); - // ---------------------------------------- - - // ---------------------------------------- - // 4. update value on external resource - // ---------------------------------------- - JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource); - String value = queryForObject(jdbcTemplate, - MAX_WAIT_SECONDS, "SELECT USERNAME FROM testpull WHERE ID=?", String.class, userTO. - getKey()); - assertEquals("virattrcache", value); - - jdbcTemplate.update("UPDATE testpull set USERNAME='virattrcache2' WHERE ID=?", userTO.getKey()); - - value = queryForObject(jdbcTemplate, - MAX_WAIT_SECONDS, "SELECT USERNAME FROM testpull WHERE ID=?", String.class, userTO.getKey()); - assertEquals("virattrcache2", value); - // ---------------------------------------- - - userTO = USER_SERVICE.read(userTO.getKey()); - assertEquals("virattrcache", userTO.getVirAttr("virtualdata").get().getValues().getFirst()); - - // ---------------------------------------- - // 5. restore connector URL, values can be read again from external resource - // ---------------------------------------- - for (ConnConfProperty prop : connInstanceTO.getConf()) { - if ("jdbcUrlTemplate".equals(prop.getSchema().getName())) { - prop.getValues().clear(); - prop.getValues().add(jdbcURL); - } - } - - CONNECTOR_SERVICE.update(connInstanceTO); - // ---------------------------------------- - - // cached value still in place... - userTO = USER_SERVICE.read(userTO.getKey()); - assertEquals("virattrcache", userTO.getVirAttr("virtualdata").get().getValues().getFirst()); - - // force cache update by adding a resource which has virtualdata mapped for propagation - UserUR userUR = new UserUR(); - userUR.setKey(userTO.getKey()); - userUR.getResources().add(new StringPatchItem.Builder(). - operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS2).build()); - userTO = updateUser(userUR).getEntity(); - assertNotNull(userTO); - - userTO = USER_SERVICE.read(userTO.getKey()); - assertEquals("virattrcache2", userTO.getVirAttr("virtualdata").get().getValues().getFirst()); - } - - @Test - public void issueSYNCOPE436() { - UserCR userCR = UserITCase.getUniqueSample("syncope436@syncope.apache.org"); - userCR.getMemberships().clear(); - userCR.getResources().clear(); - userCR.getResources().add(RESOURCE_NAME_LDAP); - userCR.getVirAttrs().add(attr("virtualReadOnly", "readOnly")); - UserTO userTO = createUser(userCR).getEntity(); - // finding no values because the virtual attribute is readonly - assertTrue(userTO.getVirAttr("virtualReadOnly").get().getValues().isEmpty()); - } - - @Test - public void issueSYNCOPE453() { - assumeFalse(IS_NEO4J_PERSISTENCE); - - String resourceName = "issueSYNCOPE453Res" + getUUIDString(); - String groupKey = null; - String groupName = "issueSYNCOPE453Group" + getUUIDString(); - - try { - // ------------------------------------------- - // Create a VirAttrITCase ad-hoc - // ------------------------------------------- - VirSchemaTO rvirtualdata; - try { - rvirtualdata = SCHEMA_SERVICE.read(SchemaType.VIRTUAL, "rvirtualdata"); - } catch (SyncopeClientException e) { - LOG.warn("rvirtualdata not found, re-creating", e); - - rvirtualdata = new VirSchemaTO(); - rvirtualdata.setKey("rvirtualdata"); - rvirtualdata.setExtAttrName("businessCategory"); - rvirtualdata.setResource(RESOURCE_NAME_LDAP); - rvirtualdata.setAnyType(AnyTypeKind.GROUP.name()); - - rvirtualdata = createSchema(SchemaType.VIRTUAL, rvirtualdata); - } - assertNotNull(rvirtualdata); - - if (!"minimal group".equals(rvirtualdata.getAnyTypeClass())) { - LOG.warn("rvirtualdata not in minimal group, restoring"); - - AnyTypeClassTO minimalGroup = ANY_TYPE_CLASS_SERVICE.read("minimal group"); - minimalGroup.getVirSchemas().add(rvirtualdata.getKey()); - ANY_TYPE_CLASS_SERVICE.update(minimalGroup); - - rvirtualdata = SCHEMA_SERVICE.read(SchemaType.VIRTUAL, rvirtualdata.getKey()); - assertEquals("minimal group", rvirtualdata.getAnyTypeClass()); - } - - // ------------------------------------------- - // Create a resource ad-hoc - // ------------------------------------------- - ResourceTO resourceTO = new ResourceTO(); - - resourceTO.setKey(resourceName); - resourceTO.setConnector("be24b061-019d-4e3e-baf0-0a6d0a45cb9c"); - - Provision provisionTO = new Provision(); - provisionTO.setAnyType(AnyTypeKind.USER.name()); - provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME); - resourceTO.getProvisions().add(provisionTO); - - Mapping mapping = new Mapping(); - provisionTO.setMapping(mapping); - - Item item = new Item(); - item.setIntAttrName("fullname"); - item.setExtAttrName("ID"); - item.setPurpose(MappingPurpose.PROPAGATION); - item.setConnObjectKey(true); - mapping.setConnObjectKeyItem(item); - - item = new Item(); - item.setIntAttrName("username"); - item.setExtAttrName("USERNAME"); - item.setPurpose(MappingPurpose.PROPAGATION); - mapping.getItems().add(item); - - item = new Item(); - item.setIntAttrName("groups[" + groupName + "].rvirtualdata"); - item.setExtAttrName("EMAIL"); - item.setPurpose(MappingPurpose.PROPAGATION); - mapping.getItems().add(item); - - assertNotNull(getObject( - RESOURCE_SERVICE.create(resourceTO).getLocation(), ResourceService.class, ResourceTO.class)); - // ------------------------------------------- - - GroupCR groupCR = new GroupCR(); - groupCR.setName(groupName); - groupCR.setRealm("/"); - groupCR.getVirAttrs().add(attr(rvirtualdata.getKey(), "ml@group.it")); - groupCR.getResources().add(RESOURCE_NAME_LDAP); - GroupTO groupTO = createGroup(groupCR).getEntity(); - groupKey = groupTO.getKey(); - assertEquals(1, groupTO.getVirAttrs().size()); - assertEquals("ml@group.it", groupTO.getVirAttrs().iterator().next().getValues().getFirst()); - // ------------------------------------------- - - // ------------------------------------------- - // Create new user - // ------------------------------------------- - UserCR userCR = UserITCase.getUniqueSample("syn453@syncope.apache.org"); - userCR.getPlainAttrs().add(attr("fullname", "123")); - userCR.getResources().clear(); - userCR.getResources().add(resourceName); - userCR.getVirAttrs().clear(); - userCR.getMemberships().clear(); - - userCR.getMemberships().add(new MembershipTO.Builder(groupTO.getKey()).build()); - - ProvisioningResult result = createUser(userCR); - assertEquals(2, result.getPropagationStatuses().size()); - assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus()); - assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(1).getStatus()); - UserTO userTO = result.getEntity(); - - JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource); - - Map actuals = jdbcTemplate.queryForMap( - "SELECT id, surname, email FROM testpull WHERE id=?", - new Object[] { userTO.getPlainAttr("fullname").get().getValues().getFirst() }); - - assertEquals(userTO.getPlainAttr("fullname").get().getValues().getFirst(), actuals.get("id").toString()); - assertEquals("ml@group.it", actuals.get("email")); - // ------------------------------------------- - } catch (Exception e) { - LOG.error("Unexpected error", e); - } finally { - // ------------------------------------------- - // Delete resource and group ad-hoc - // ------------------------------------------- - RESOURCE_SERVICE.delete(resourceName); - if (groupKey != null) { - GROUP_SERVICE.delete(groupKey); - } - // ------------------------------------------- - } - } - - @Test - public void issueSYNCOPE459() { - UserCR userCR = UserITCase.getUniqueSample("syncope459@apache.org"); - userCR.getResources().clear(); - userCR.getResources().add(RESOURCE_NAME_LDAP); - userCR.getMemberships().clear(); - userCR.getVirAttrs().clear(); - - UserTO userTO = createUser(userCR).getEntity(); - - assertNotNull(userTO.getVirAttr("virtualReadOnly")); - } - - @Test - public void issueSYNCOPE501() { - // 1. create user and propagate him on resource-db-virattr - UserCR userCR = UserITCase.getUniqueSample("syncope501@apache.org"); - userCR.getResources().clear(); - userCR.getMemberships().clear(); - userCR.getVirAttrs().clear(); - - userCR.getResources().add(RESOURCE_NAME_DBVIRATTR); - - // virtualdata is mapped with username - userCR.getVirAttrs().add(attr("virtualdata", "syncope501@apache.org")); - - UserTO userTO = createUser(userCR).getEntity(); - - assertNotNull(userTO.getVirAttr("virtualdata")); - assertEquals("syncope501@apache.org", userTO.getVirAttr("virtualdata").get().getValues().getFirst()); - - // 2. update virtual attribute - UserUR userUR = new UserUR(); - userUR.setKey(userTO.getKey()); - // change virtual attribute value - userUR.getVirAttrs().add(attr("virtualdata", "syncope501_updated@apache.org")); - - userTO = updateUser(userUR).getEntity(); - assertNotNull(userTO); - - // 3. check that user virtual attribute has really been updated - assertFalse(userTO.getVirAttr("virtualdata").get().getValues().isEmpty()); - assertEquals("syncope501_updated@apache.org", userTO.getVirAttr("virtualdata").get().getValues().getFirst()); - } - - @Test - public void issueSYNCOPE691() { - ResourceTO ldap = RESOURCE_SERVICE.read(RESOURCE_NAME_LDAP); - try { - Provision provision = ldap.getProvision(AnyTypeKind.USER.name()).orElse(null); - assertNotNull(provision); - provision.getMapping().getItems().removeIf(item -> "mail".equals(item.getExtAttrName())); - provision.getVirSchemas().clear(); - - ldap.getProvisions().clear(); - ldap.getProvisions().add(provision); - ldap.setKey(RESOURCE_NAME_LDAP + "691" + getUUIDString()); - RESOURCE_SERVICE.create(ldap); - - ldap = RESOURCE_SERVICE.read(ldap.getKey()); - provision = ldap.getProvision(AnyTypeKind.USER.name()).get(); - assertNotNull(provision); - - // create new virtual schema for the resource below - VirSchemaTO virSchema = new VirSchemaTO(); - virSchema.setKey("syncope691" + getUUIDString()); - virSchema.setExtAttrName("mail"); - virSchema.setResource(ldap.getKey()); - virSchema.setAnyType(provision.getAnyType()); - virSchema = createSchema(SchemaType.VIRTUAL, virSchema); - assertNotNull(virSchema); - - AnyTypeClassTO newClass = new AnyTypeClassTO(); - newClass.setKey("syncope691" + getUUIDString()); - newClass.getVirSchemas().add(virSchema.getKey()); - Response response = ANY_TYPE_CLASS_SERVICE.create(newClass); - assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode()); - newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class); - - // create a new user - UserCR userCR = UserITCase.getUniqueSample("syncope691@syncope.apache.org"); - userCR.getAuxClasses().add(newClass.getKey()); - userCR.getResources().clear(); - userCR.getMemberships().clear(); - userCR.getVirAttrs().clear(); - - Attr emailTO = new Attr(); - emailTO.setSchema(virSchema.getKey()); - emailTO.getValues().add("test@issue691.dom1.org"); - emailTO.getValues().add("test@issue691.dom2.org"); - - userCR.getVirAttrs().add(emailTO); - // assign resource-ldap691 to user - userCR.getResources().add(ldap.getKey()); - // save user - UserTO userTO = createUser(userCR).getEntity(); - // make std controls about user - assertNotNull(userTO); - assertTrue(ldap.getKey().equals(userTO.getResources().iterator().next())); - - assertEquals(2, userTO.getVirAttrs().iterator().next().getValues().size()); - assertTrue(userTO.getVirAttrs().iterator().next().getValues().contains("test@issue691.dom1.org")); - assertTrue(userTO.getVirAttrs().iterator().next().getValues().contains("test@issue691.dom2.org")); - - // update user - UserUR userUR = new UserUR(); - userUR.setKey(userTO.getKey()); - // modify virtual attribute - userUR.getVirAttrs().add(new Attr.Builder(virSchema.getKey()). - value("test@issue691.dom3.org"). - value("test@issue691.dom4.org"). - build()); - - UserTO updated = updateUser(userUR).getEntity(); - assertNotNull(updated); - assertEquals(2, updated.getVirAttrs().iterator().next().getValues().size()); - assertTrue(updated.getVirAttrs().iterator().next().getValues().contains("test@issue691.dom3.org")); - assertTrue(updated.getVirAttrs().iterator().next().getValues().contains("test@issue691.dom4.org")); - } finally { - try { - RESOURCE_SERVICE.delete(ldap.getKey()); - } catch (Exception ignore) { - // ignore - } - } - } -} diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirSchemaITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirSchemaITCase.java deleted file mode 100644 index f63b3a9e655..00000000000 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/VirSchemaITCase.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.fit.core; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -import jakarta.ws.rs.core.Response; -import java.util.List; -import java.util.Locale; -import org.apache.syncope.common.lib.SyncopeClientException; -import org.apache.syncope.common.lib.to.ResourceTO; -import org.apache.syncope.common.lib.to.VirSchemaTO; -import org.apache.syncope.common.lib.types.ClientExceptionType; -import org.apache.syncope.common.lib.types.EntityViolationType; -import org.apache.syncope.common.lib.types.SchemaType; -import org.apache.syncope.common.rest.api.beans.SchemaQuery; -import org.apache.syncope.common.rest.api.service.SchemaService; -import org.apache.syncope.fit.AbstractITCase; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -public class VirSchemaITCase extends AbstractITCase { - - @Test - public void search() { - List schemas = SCHEMA_SERVICE.search(new SchemaQuery.Builder().type(SchemaType.VIRTUAL).build()); - assertFalse(schemas.isEmpty()); - schemas.forEach(Assertions::assertNotNull); - - schemas = SCHEMA_SERVICE.search( - new SchemaQuery.Builder().type(SchemaType.VIRTUAL).keyword("rvirtual*").build()); - assertFalse(schemas.isEmpty()); - schemas.forEach(Assertions::assertNotNull); - } - - @Test - public void crud() { - ResourceTO csv = RESOURCE_SERVICE.read(RESOURCE_NAME_CSV); - assertNotNull(csv); - assertEquals(1, csv.getProvisions().size()); - assertTrue(csv.getProvisions().getFirst().getVirSchemas().isEmpty()); - - VirSchemaTO schema = new VirSchemaTO(); - schema.setKey("virtualTest" + getUUIDString()); - schema.setExtAttrName("name"); - schema.setResource(RESOURCE_NAME_CSV); - schema.setAnyType(csv.getProvisions().getFirst().getAnyType()); - schema.getLabels().put(Locale.ENGLISH, "Virtual"); - - schema = createSchema(SchemaType.VIRTUAL, schema); - assertNotNull(schema); - assertEquals(csv.getProvisions().getFirst().getAnyType(), schema.getAnyType()); - assertEquals(1, schema.getLabels().size()); - assertEquals("Virtual", schema.getLabel(Locale.ENGLISH)); - assertEquals(schema.getKey(), schema.getLabel(Locale.CHINESE)); - - csv = RESOURCE_SERVICE.read(RESOURCE_NAME_CSV); - assertNotNull(csv); - assertEquals(1, csv.getProvisions().size()); - assertFalse(csv.getProvisions().getFirst().getVirSchemas().isEmpty()); - - schema = SCHEMA_SERVICE.read(SchemaType.VIRTUAL, schema.getKey()); - assertNotNull(schema); - - SCHEMA_SERVICE.delete(SchemaType.VIRTUAL, schema.getKey()); - - try { - SCHEMA_SERVICE.read(SchemaType.VIRTUAL, schema.getKey()); - fail("This should not happen"); - } catch (SyncopeClientException e) { - assertEquals(ClientExceptionType.NotFound, e.getType()); - } - - csv = RESOURCE_SERVICE.read(RESOURCE_NAME_CSV); - assertNotNull(csv); - assertEquals(1, csv.getProvisions().size()); - assertTrue(csv.getProvisions().getFirst().getVirSchemas().isEmpty()); - } - - @Test - public void anonymous() { - SchemaService anonymous = ANONYMOUS_CLIENT.getService(SchemaService.class); - assertFalse(anonymous.search(new SchemaQuery.Builder().type(SchemaType.VIRTUAL).build()).isEmpty()); - } - - @Test - public void issueSYNCOPE323() { - VirSchemaTO actual = SCHEMA_SERVICE.read(SchemaType.VIRTUAL, "virtualdata"); - assertNotNull(actual); - - try { - createSchema(SchemaType.VIRTUAL, actual); - fail("This should not happen"); - } catch (SyncopeClientException e) { - assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus()); - assertEquals(ClientExceptionType.EntityExists, e.getType()); - } - - actual.setKey(null); - try { - createSchema(SchemaType.VIRTUAL, actual); - fail("This should not happen"); - } catch (SyncopeClientException e) { - assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus()); - assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType()); - } - } - - @Test - public void issueSYNCOPE418() { - ResourceTO ws1 = RESOURCE_SERVICE.read(RESOURCE_NAME_WS1); - assertNotNull(ws1); - assertEquals(1, ws1.getProvisions().size()); - assertTrue(ws1.getProvisions().getFirst().getVirSchemas().isEmpty()); - - VirSchemaTO schema = new VirSchemaTO(); - schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit"); - schema.setExtAttrName("name"); - schema.setResource(RESOURCE_NAME_WS1); - schema.setAnyType(ws1.getProvisions().getFirst().getAnyType()); - - try { - createSchema(SchemaType.VIRTUAL, schema); - fail("This should not happen"); - } catch (SyncopeClientException e) { - assertEquals(ClientExceptionType.InvalidVirSchema, e.getType()); - - assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidKey.name())); - } - } -} diff --git a/fit/enduser-reference/src/test/resources/customTemplate.json b/fit/enduser-reference/src/test/resources/customTemplate.json index e55ed4c86fd..b31df2da9ae 100644 --- a/fit/enduser-reference/src/test/resources/customTemplate.json +++ b/fit/enduser-reference/src/test/resources/customTemplate.json @@ -68,9 +68,6 @@ "derivedSchemas": { "url": "/derivedSchemas" }, - "virtualSchemas": { - "url": "/virtualSchemas" - }, "resources": { "url": "/resources" }, diff --git a/src/main/asciidoc/reference-guide/concepts/typemanagement.adoc b/src/main/asciidoc/reference-guide/concepts/typemanagement.adoc index 5d3360e9f92..a449ec35e90 100644 --- a/src/main/asciidoc/reference-guide/concepts/typemanagement.adoc +++ b/src/main/asciidoc/reference-guide/concepts/typemanagement.adoc @@ -24,8 +24,7 @@ model. ==== Schema -A schema instance describes the values that attributes with that schema will hold; it can be defined plain, derived or -virtual. +A schema instance describes the values that attributes with that schema will hold; it can be defined plain or derived. It is possible to define i18n labels for each schema, with purpose of improving presentation with Admin and End-user UIs. @@ -84,31 +83,9 @@ For the sample above, it would be With derived attributes, values are not stored into the <> but calculated on request, by evaluating the related JEXL expression -===== Virtual - -Virtual attributes are somehow linked from Identity Stores rather than stored internally. - -The typical use case is when attribute values can change in the Identity Store without notice, and it is required to -always have access to the most recent values that are available. - -It can also be said that virtual schemas are for attributes whose ownership is not that of Syncope but of an Identity Store; -the external resources for such Identity Stores are said to be the _linking resources_. - -[TIP] -As best practice, only attributes for which Apache Syncope retains ownership should be modeled as plain attributes; -attributes for which Apache Syncope does not retain ownership should be modeled -as virtual instead. - -When defining a virtual schema, the following information must be provided: - -* External resource - linking resource -* External attribute - attribute to be linked on the external resource -* Any Type - reference <> on the external resource -* Read-only flag - whether the external attribute value(s) for this schema can only be read, or whether they can be written to as well - ==== AnyTypeClass -Any type classes are aggregations of plain, derived and virtual schemas, provided with unique identifiers. +Any type classes are aggregations of plain and derived schemas, provided with unique identifiers. Classes can be assigned to <>, <> and are also available as auxiliary (hence to be specified on a given user / group / any object instance) and for <>. @@ -127,7 +104,6 @@ Assuming that the following schemas are available: . plain: `firstname`, `surname`, `email` . derived: `fullname` -. virtual: `enrollment` and that the following Any Type classes are defined: @@ -201,14 +177,6 @@ increase readability): "Gioacchino Rossini" ] } - ], - "virAttrs": [ - { - "schema": "enrollment", - "values": [ - "154322" - ] - } ] } ---- diff --git a/src/main/asciidoc/reference-guide/concepts/usersgroupsandanyobjects.adoc b/src/main/asciidoc/reference-guide/concepts/usersgroupsandanyobjects.adoc index 482ce0d6ab9..54d629cbce2 100644 --- a/src/main/asciidoc/reference-guide/concepts/usersgroupsandanyobjects.adoc +++ b/src/main/asciidoc/reference-guide/concepts/usersgroupsandanyobjects.adoc @@ -41,7 +41,7 @@ For each of the identities above, Apache Syncope is capable of maintaining: ** `values` is a (possibly singleton) collection of data (e.g. `[Doe]` but also `[\john.doe@syncope.apache.org, \jdoe@gmail.com]`) ; the type of values that can be assigned to each attribute is defined via the <> matching the `key` -value (e.g. _plain_, _derived_ and _virtual_); +value (e.g. _plain_ and _derived_); . associations with <>, for <>. [IMPORTANT] From d63b67472fb67d9bdb0062796560081fc3721f05 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 May 2025 08:17:31 +0200 Subject: [PATCH 037/579] Bump com.oracle.database.jdbc:ojdbc11 from 23.7.0.25.01 to 23.8.0.25.04 (#1071) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 35742f856d3..bca507383b4 100644 --- a/pom.xml +++ b/pom.xml @@ -519,7 +519,7 @@ under the License. 42.7.5 9.2.0 3.5.3 - 23.7.0.25.01 + 23.8.0.25.04 ${project.build.directory}/bundles From 8cb85bfc95557d0367346639664581275905be83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Fri, 9 May 2025 14:58:28 +0200 Subject: [PATCH 038/579] [SYNCOPE-1877] Removing SAML2SPEntity and related (#1072) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../client/console/AMConsoleContext.java | 7 - .../client/console/commons/AMConstants.java | 2 - .../syncope/client/console/pages/WA.java | 11 +- .../syncope/client/console/panels/SAML2.java | 81 ------- .../panels/SAML2SPEntityDirectoryPanel.java | 213 ------------------ .../console/rest/SAML2SPEntityRestClient.java | 45 ---- .../wizards/AuthModuleWizardBuilder.java | 44 +++- .../wizards/SAML2EntityWizardBuilder.java | 65 ------ .../wizards/SAML2IdPEntityWizardBuilder.java | 32 ++- .../wizards/SAML2SPEntityWizardBuilder.java | 111 --------- .../SAML2SPEntityDirectoryPanel.properties | 20 -- ...ML2SPEntityDirectoryPanel_fr_CA.properties | 20 -- .../SAML2SPEntityDirectoryPanel_it.properties | 20 -- .../SAML2SPEntityDirectoryPanel_ja.properties | 20 -- ...ML2SPEntityDirectoryPanel_pt_BR.properties | 20 -- .../SAML2SPEntityDirectoryPanel_ru.properties | 20 -- ...duleWizardBuilder$AuthModuleConfSAML.html} | 6 +- ...SAML2IdPEntityWizardBuilder$Metadata.html} | 0 ... SAML2IdPEntityWizardBuilder$TextPem.html} | 0 .../SAML2SPEntityWizardBuilder$Profile.html | 23 -- .../src/main/resources/MIMETypes.json | 4 + .../markup/html/form/BinaryFieldPanel.java | 6 +- .../lib/auth/SAML2IdPAuthModuleConf.java | 72 +++--- .../common/lib/to/SAML2SPEntityTO.java | 93 -------- .../common/lib/types/AMEntitlement.java | 8 - .../common/lib/types/TriStateBoolean.java | 9 +- .../api/service/SAML2SPEntityService.java | 92 -------- .../rest/api/service/wa/WASAML2SPService.java | 58 +++++ .../syncope/core/logic/AMLogicContext.java | 11 - .../syncope/core/logic/AuthModuleLogic.java | 62 +++++ .../core/logic/SAML2SPEntityLogic.java | 103 --------- .../core/rest/cxf/AMRESTCXFContext.java | 17 +- .../cxf/service/SAML2SPEntityServiceImpl.java | 53 ----- .../cxf/service/wa/WASAML2SPServiceImpl.java | 61 +++++ .../core/logic/ReconciliationLogic.java | 5 +- .../syncope/core/logic/ResourceLogic.java | 1 - .../api/entity/am/SAML2SPEntity.java | 32 --- .../src/main/resources/schema.xml | 8 +- .../persistence/jpa/PersistenceContext.java | 8 - .../jpa/dao/repo/SAML2SPEntityRepo.java | 28 --- .../jpa/entity/AbstractEntityFactory.java | 4 - .../jpa/entity/am/JPASAML2SPEntity.java | 64 ------ .../jpa/inner/SAML2SPEntityTest.java | 160 ------------- .../test/resources/domains/MasterContent.xml | 2 +- .../persistence/neo4j/PersistenceContext.java | 8 - .../neo4j/dao/repo/SAML2SPEntityRepo.java | 28 --- .../neo4j/entity/Neo4jEntityFactory.java | 4 - .../neo4j/entity/am/Neo4jSAML2SPEntity.java | 56 ----- .../neo4j/inner/SAML2SPEntityTest.java | 158 ------------- .../test/resources/domains/MasterContent.xml | 2 +- .../api/data/SAML2SPEntityDataBinder.java | 31 --- .../java/ProvisioningContext.java | 8 - .../java/data/ResourceDataBinderImpl.java | 2 - .../data/SAML2SPEntityDataBinderImpl.java | 65 ------ .../DefaultUserPushResultHandler.java | 1 - .../java/pushpull/OutboundMatcher.java | 6 - .../apache/syncope/fit/AbstractITCase.java | 4 - .../syncope/fit/core/AuthModuleITCase.java | 13 +- .../syncope/fit/core/SAML2SPEntityITCase.java | 89 -------- pom.xml | 2 +- .../AuthModulePropertySourceMapper.java | 8 +- .../saml/WASAML2ClientKeystoreGenerator.java | 32 ++- .../saml/WASAML2ClientMetadataGenerator.java | 20 +- .../pac4j/saml/WASAML2MetadataResolver.java | 10 +- .../wa/starter/SyncopeCoreTestingServer.java | 2 +- .../pac4j/saml/BaseWASAML2ClientTest.java | 32 +++ .../saml/WASAML2ClientCustomizerTest.java | 26 +-- .../WASAML2ClientKeystoreGeneratorTest.java | 31 +-- .../WASAML2ClientMetadataGeneratorTest.java | 30 +-- .../saml/WASAML2MetadataResolverTest.java | 26 +-- 70 files changed, 401 insertions(+), 2014 deletions(-) delete mode 100644 client/am/console/src/main/java/org/apache/syncope/client/console/panels/SAML2.java delete mode 100644 client/am/console/src/main/java/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel.java delete mode 100644 client/am/console/src/main/java/org/apache/syncope/client/console/rest/SAML2SPEntityRestClient.java delete mode 100644 client/am/console/src/main/java/org/apache/syncope/client/console/wizards/SAML2EntityWizardBuilder.java delete mode 100644 client/am/console/src/main/java/org/apache/syncope/client/console/wizards/SAML2SPEntityWizardBuilder.java delete mode 100644 client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel.properties delete mode 100644 client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_fr_CA.properties delete mode 100644 client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_it.properties delete mode 100644 client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_ja.properties delete mode 100644 client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_pt_BR.properties delete mode 100644 client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_ru.properties rename client/am/console/src/main/resources/org/apache/syncope/client/console/{panels/SAML2.html => wizards/AuthModuleWizardBuilder$AuthModuleConfSAML.html} (84%) rename client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/{SAML2EntityWizardBuilder$Metadata.html => SAML2IdPEntityWizardBuilder$Metadata.html} (100%) rename client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/{SAML2EntityWizardBuilder$Pem.html => SAML2IdPEntityWizardBuilder$TextPem.html} (100%) delete mode 100644 client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/SAML2SPEntityWizardBuilder$Profile.html delete mode 100644 common/am/lib/src/main/java/org/apache/syncope/common/lib/to/SAML2SPEntityTO.java rename core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SAML2SPEntityDAO.java => common/am/lib/src/main/java/org/apache/syncope/common/lib/types/TriStateBoolean.java (81%) delete mode 100644 common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2SPEntityService.java create mode 100644 common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/wa/WASAML2SPService.java delete mode 100644 core/am/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPEntityLogic.java delete mode 100644 core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SPEntityServiceImpl.java create mode 100644 core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/WASAML2SPServiceImpl.java delete mode 100644 core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/SAML2SPEntity.java delete mode 100644 core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/SAML2SPEntityRepo.java delete mode 100644 core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPASAML2SPEntity.java delete mode 100644 core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/SAML2SPEntityTest.java delete mode 100644 core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/SAML2SPEntityRepo.java delete mode 100644 core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/am/Neo4jSAML2SPEntity.java delete mode 100644 core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/SAML2SPEntityTest.java delete mode 100644 core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SAML2SPEntityDataBinder.java delete mode 100644 core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2SPEntityDataBinderImpl.java delete mode 100644 fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2SPEntityITCase.java diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/AMConsoleContext.java b/client/am/console/src/main/java/org/apache/syncope/client/console/AMConsoleContext.java index 46b94e1603e..8d8b53f3bc3 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/AMConsoleContext.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/AMConsoleContext.java @@ -33,7 +33,6 @@ import org.apache.syncope.client.console.rest.OIDCJWKSRestClient; import org.apache.syncope.client.console.rest.PolicyRestClient; import org.apache.syncope.client.console.rest.SAML2IdPEntityRestClient; -import org.apache.syncope.client.console.rest.SAML2SPEntityRestClient; import org.apache.syncope.client.console.rest.SRARouteRestClient; import org.apache.syncope.client.console.rest.SRAStatisticsRestClient; import org.apache.syncope.client.console.rest.WAConfigRestClient; @@ -100,12 +99,6 @@ public SAML2IdPEntityRestClient saml2IdPEntityRestClient() { return new SAML2IdPEntityRestClient(); } - @ConditionalOnMissingBean - @Bean - public SAML2SPEntityRestClient saml2SPEntityRestClient() { - return new SAML2SPEntityRestClient(); - } - @ConditionalOnMissingBean @Bean public SRARouteRestClient sraRouteRestClient() { diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/commons/AMConstants.java b/client/am/console/src/main/java/org/apache/syncope/client/console/commons/AMConstants.java index 3f6af5ab8de..fcd7b3fc580 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/commons/AMConstants.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/commons/AMConstants.java @@ -36,8 +36,6 @@ public final class AMConstants { public static final String PREF_SAML2_IDP_ENTITY_PAGINATOR_ROWS = "saml2idpentity.properties.paginator.rows"; - public static final String PREF_SAML2_SP_ENTITY_PAGINATOR_ROWS = "saml2spentity.properties.paginator.rows"; - public static final String PREF_AUTHPROFILE_PAGINATOR_ROWS = "authprofile.paginator.rows"; public static final String PREF_AUTHPROFILE_IMPERSONATED_PAGINATOR_ROWS = "authprofile.impersonated.paginator.rows"; diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/pages/WA.java b/client/am/console/src/main/java/org/apache/syncope/client/console/pages/WA.java index 54b8ea45dd7..88dd3683105 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/pages/WA.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/pages/WA.java @@ -39,12 +39,13 @@ import org.apache.syncope.client.console.panels.AttrRepoDirectoryPanel; import org.apache.syncope.client.console.panels.AuthModuleDirectoryPanel; import org.apache.syncope.client.console.panels.OIDC; -import org.apache.syncope.client.console.panels.SAML2; +import org.apache.syncope.client.console.panels.SAML2IdPEntityDirectoryPanel; import org.apache.syncope.client.console.panels.WAConfigDirectoryPanel; import org.apache.syncope.client.console.panels.WAPushModalPanel; import org.apache.syncope.client.console.rest.AttrRepoRestClient; import org.apache.syncope.client.console.rest.AuthModuleRestClient; import org.apache.syncope.client.console.rest.AuthProfileRestClient; +import org.apache.syncope.client.console.rest.SAML2IdPEntityRestClient; import org.apache.syncope.client.console.rest.WAConfigRestClient; import org.apache.syncope.client.console.rest.WASessionRestClient; import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal; @@ -82,6 +83,9 @@ public class WA extends BasePage { @SpringBean protected AttrRepoRestClient attrRepoRestClient; + @SpringBean + protected SAML2IdPEntityRestClient saml2IdPEntityRestClient; + @SpringBean protected ServiceOps serviceOps; @@ -127,7 +131,7 @@ public void onClick(final AjaxRequestTarget target) { if (!instances.isEmpty()) { String actuatorEndpoint = StringUtils.appendIfMissing( - instances.getFirst().getAddress(), "/") + "actuator/env"; + instances.getFirst().getAddress(), "/") + "actuator/env"; try { Response response = WebClientBuilder.build(actuatorEndpoint, SyncopeWebApplication.get().getAnonymousUser(), @@ -204,7 +208,8 @@ public Panel getPanel(final String panelId) { @Override public Panel getPanel(final String panelId) { - return new SAML2(panelId, waPrefix, getPageReference()); + return new SAML2IdPEntityDirectoryPanel( + panelId, saml2IdPEntityRestClient, waPrefix, getPageReference()); } }); diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/panels/SAML2.java b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/SAML2.java deleted file mode 100644 index 04fa7d2c50a..00000000000 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/panels/SAML2.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.client.console.panels; - -import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel; -import java.util.ArrayList; -import java.util.List; -import org.apache.syncope.client.console.SyncopeConsoleSession; -import org.apache.syncope.client.console.rest.SAML2IdPEntityRestClient; -import org.apache.syncope.client.console.rest.SAML2SPEntityRestClient; -import org.apache.syncope.common.lib.SyncopeConstants; -import org.apache.syncope.common.lib.types.AMEntitlement; -import org.apache.wicket.PageReference; -import org.apache.wicket.extensions.markup.html.tabs.AbstractTab; -import org.apache.wicket.extensions.markup.html.tabs.ITab; -import org.apache.wicket.markup.html.panel.Panel; -import org.apache.wicket.model.Model; -import org.apache.wicket.spring.injection.annot.SpringBean; - -public class SAML2 extends Panel { - - private static final long serialVersionUID = 7093557205333650002L; - - @SpringBean - protected SAML2IdPEntityRestClient saml2IdPEntityRestClient; - - @SpringBean - protected SAML2SPEntityRestClient saml2SPEntityRestClient; - - public SAML2(final String id, final String waPrefix, final PageReference pageRef) { - super(id); - - add(new AjaxBootstrapTabbedPanel<>("saml2", buildTabList(waPrefix, pageRef))); - } - - protected List buildTabList(final String waPrefix, final PageReference pageRef) { - List tabs = new ArrayList<>(); - - if (SyncopeConsoleSession.get().owns(AMEntitlement.SAML2_IDP_ENTITY_LIST, SyncopeConstants.ROOT_REALM)) { - tabs.add(new AbstractTab(Model.of("Identity Provider")) { - - private static final long serialVersionUID = 5211692813425391144L; - - @Override - public Panel getPanel(final String panelId) { - return new SAML2IdPEntityDirectoryPanel(panelId, saml2IdPEntityRestClient, waPrefix, pageRef); - } - }); - } - - if (SyncopeConsoleSession.get().owns(AMEntitlement.SAML2_SP_ENTITY_LIST, SyncopeConstants.ROOT_REALM)) { - tabs.add(new AbstractTab(Model.of("Service Provider")) { - - private static final long serialVersionUID = 5211692813425391144L; - - @Override - public Panel getPanel(final String panelId) { - return new SAML2SPEntityDirectoryPanel(panelId, saml2SPEntityRestClient, waPrefix, pageRef); - } - }); - } - - return tabs; - } -} diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel.java deleted file mode 100644 index 10f99409127..00000000000 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.client.console.panels; - -import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import org.apache.syncope.client.console.SyncopeConsoleSession; -import org.apache.syncope.client.console.commons.AMConstants; -import org.apache.syncope.client.console.commons.DirectoryDataProvider; -import org.apache.syncope.client.console.commons.SortableDataProviderComparator; -import org.apache.syncope.client.console.panels.SAML2SPEntityDirectoryPanel.SAML2SPEntityProvider; -import org.apache.syncope.client.console.rest.SAML2SPEntityRestClient; -import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink; -import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel; -import org.apache.syncope.client.console.wizards.SAML2SPEntityWizardBuilder; -import org.apache.syncope.client.ui.commons.Constants; -import org.apache.syncope.client.ui.commons.pages.BaseWebPage; -import org.apache.syncope.client.ui.commons.wizards.AjaxWizard; -import org.apache.syncope.common.lib.to.SAML2SPEntityTO; -import org.apache.syncope.common.lib.types.AMEntitlement; -import org.apache.wicket.PageReference; -import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy; -import org.apache.wicket.event.Broadcast; -import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator; -import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn; -import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; -import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn; -import org.apache.wicket.markup.ComponentTag; -import org.apache.wicket.markup.html.link.ExternalLink; -import org.apache.wicket.markup.repeater.Item; -import org.apache.wicket.model.CompoundPropertyModel; -import org.apache.wicket.model.IModel; -import org.apache.wicket.model.Model; -import org.apache.wicket.model.StringResourceModel; - -public class SAML2SPEntityDirectoryPanel extends DirectoryPanel< - SAML2SPEntityTO, SAML2SPEntityTO, SAML2SPEntityProvider, SAML2SPEntityRestClient> { - - private static final long serialVersionUID = -3890622383545171017L; - - private final String waPrefix; - - public SAML2SPEntityDirectoryPanel( - final String id, - final SAML2SPEntityRestClient restClient, - final String waPrefix, - final PageReference pageRef) { - - super(id, restClient, pageRef); - this.waPrefix = waPrefix; - - disableCheckBoxes(); - - modal.size(Modal.Size.Large); - modal.addSubmitButton(); - - modal.setWindowClosedCallback(target -> { - updateResultTable(target); - modal.show(false); - }); - - addNewItemPanelBuilder(new SAML2SPEntityWizardBuilder(new SAML2SPEntityTO(), restClient, pageRef), true); - - MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, AMEntitlement.SAML2_SP_ENTITY_SET); - - initResultTable(); - } - - @Override - protected List> getColumns() { - List> columns = new ArrayList<>(); - - columns.add(new PropertyColumn<>( - new StringResourceModel(Constants.KEY_FIELD_NAME, this), - Constants.KEY_FIELD_NAME, Constants.KEY_FIELD_NAME)); - - columns.add(new AbstractColumn<>(Model.of("URL")) { - - private static final long serialVersionUID = -7226955670801277153L; - - @Override - public void populateItem( - final Item> cellItem, - final String componentId, - final IModel rowModel) { - - String metadataURL = waPrefix + "/sp/" + rowModel.getObject().getKey() + "/metadata"; - cellItem.add(new ExternalLink( - componentId, - Model.of(metadataURL), - Model.of(metadataURL)) { - - private static final long serialVersionUID = -1919646533527005367L; - - @Override - protected void onComponentTag(final ComponentTag tag) { - super.onComponentTag(tag); - - tag.setName("a"); - if (metadataURL.startsWith("http")) { - tag.put("href", getDefaultModelObject().toString()); - tag.put("target", "_blank"); - } - } - }); - } - }); - - return columns; - } - - @Override - protected ActionsPanel getActions(final IModel model) { - ActionsPanel panel = super.getActions(model); - - panel.add(new ActionLink<>() { - - private static final long serialVersionUID = -3722207913631435501L; - - @Override - public void onClick(final AjaxRequestTarget target, final SAML2SPEntityTO ignore) { - send(SAML2SPEntityDirectoryPanel.this, Broadcast.EXACT, - new AjaxWizard.EditItemActionEvent<>( - restClient.get(model.getObject().getKey()), target)); - } - }, ActionLink.ActionType.EDIT, AMEntitlement.SAML2_SP_ENTITY_SET); - - panel.add(new ActionLink<>() { - - private static final long serialVersionUID = -3722207913631435501L; - - @Override - public void onClick(final AjaxRequestTarget target, final SAML2SPEntityTO ignore) { - try { - restClient.delete(model.getObject().getKey()); - - SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED)); - target.add(container); - } catch (Exception e) { - LOG.error("While deleting {}", model.getObject().getKey(), e); - SyncopeConsoleSession.get().onException(e); - } - ((BaseWebPage) pageRef.getPage()).getNotificationPanel().refresh(target); - } - }, ActionLink.ActionType.DELETE, AMEntitlement.AUTH_MODULE_DELETE, true); - - return panel; - } - - @Override - protected Collection getBatches() { - return List.of(); - } - - @Override - protected SAML2SPEntityProvider dataProvider() { - return new SAML2SPEntityProvider(rows); - } - - @Override - protected String paginatorRowsKey() { - return AMConstants.PREF_SAML2_SP_ENTITY_PAGINATOR_ROWS; - } - - protected final class SAML2SPEntityProvider extends DirectoryDataProvider { - - private static final long serialVersionUID = 5282134321828253058L; - - private final SortableDataProviderComparator comparator; - - public SAML2SPEntityProvider(final int paginatorRows) { - super(paginatorRows); - comparator = new SortableDataProviderComparator<>(this); - } - - @Override - public Iterator iterator(final long first, final long count) { - List sps = restClient.list(); - sps.sort(comparator); - return sps.subList((int) first, (int) first + (int) count).iterator(); - } - - @Override - public long size() { - return restClient.list().size(); - } - - @Override - public IModel model(final SAML2SPEntityTO metadata) { - return new CompoundPropertyModel<>(metadata); - } - } -} diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/rest/SAML2SPEntityRestClient.java b/client/am/console/src/main/java/org/apache/syncope/client/console/rest/SAML2SPEntityRestClient.java deleted file mode 100644 index 42873a25a30..00000000000 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/rest/SAML2SPEntityRestClient.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.client.console.rest; - -import java.util.ArrayList; -import java.util.List; -import org.apache.syncope.common.lib.to.SAML2SPEntityTO; -import org.apache.syncope.common.rest.api.service.SAML2SPEntityService; - -public class SAML2SPEntityRestClient extends BaseRestClient { - - private static final long serialVersionUID = -1392090291817187902L; - - public List list() { - return new ArrayList<>(getService(SAML2SPEntityService.class).list()); - } - - public SAML2SPEntityTO get(final String key) { - return getService(SAML2SPEntityService.class).get(key); - } - - public void set(final SAML2SPEntityTO entityTO) { - getService(SAML2SPEntityService.class).set(entityTO); - } - - public void delete(final String key) { - getService(SAML2SPEntityService.class).delete(key); - } -} diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder.java b/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder.java index a0b7317bf42..2dac0c78751 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder.java @@ -25,6 +25,8 @@ import org.apache.syncope.client.console.SyncopeWebApplication; import org.apache.syncope.client.console.panels.BeanPanel; import org.apache.syncope.client.console.rest.AuthModuleRestClient; +import org.apache.syncope.client.console.wicket.markup.html.form.BinaryFieldPanel; +import org.apache.syncope.client.console.wicket.markup.html.form.XMLEditorPanel; import org.apache.syncope.client.console.wizards.mapping.AuthModuleMappingPanel; import org.apache.syncope.client.ui.commons.Constants; import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior; @@ -36,6 +38,7 @@ import org.apache.syncope.common.lib.AbstractLDAPConf; import org.apache.syncope.common.lib.auth.AuthModuleConf; import org.apache.syncope.common.lib.auth.LDAPDependantAuthModuleConf; +import org.apache.syncope.common.lib.auth.SAML2IdPAuthModuleConf; import org.apache.syncope.common.lib.to.AuthModuleTO; import org.apache.syncope.common.lib.types.AuthModuleState; import org.apache.wicket.PageReference; @@ -92,6 +95,7 @@ protected WizardModel buildModelSteps(final AuthModuleTO modelObject, final Wiza wizardModel.add(new Profile(modelObject, authModuleConfs, authModuleConfClass)); wizardModel.add(new Configuration(modelObject)); wizardModel.add(new AuthModuleConfLDAP(modelObject, authModuleConfClass)); + wizardModel.add(new AuthModuleConfSAML(modelObject, authModuleConfClass)); wizardModel.add(new Mapping(modelObject)); return wizardModel; } @@ -170,8 +174,44 @@ protected class Configuration extends WizardStep { private static final long serialVersionUID = -785981096328637758L; Configuration(final AuthModuleTO authModule) { - add(new BeanPanel<>("bean", new PropertyModel<>(authModule, "conf"), pageRef, "ldap"). - setRenderBodyOnly(true)); + add(new BeanPanel<>("bean", new PropertyModel<>(authModule, "conf"), pageRef, + "ldap", "keystore", "serviceProviderMetadata").setRenderBodyOnly(true)); + } + } + + protected class AuthModuleConfSAML extends WizardStep implements WizardModel.ICondition { + + private static final long serialVersionUID = 8139350816753061469L; + + private final Model> authModuleConfClass; + + AuthModuleConfSAML( + final AuthModuleTO authModule, + final Model> authModuleConfClass) { + + this.authModuleConfClass = authModuleConfClass; + + add(new BinaryFieldPanel( + "keystore", + "", + new PropertyModel<>(authModule, "conf.keystore"), + "application/x-java-keystore", + authModule.getKey()) { + + private static final long serialVersionUID = -3268213909514986831L; + + @Override + protected PageReference getPageReference() { + return pageRef; + } + }); + add(new XMLEditorPanel(null, + new PropertyModel<>(authModule, "conf.serviceProviderMetadata"), false, pageRef)); + } + + @Override + public boolean evaluate() { + return SAML2IdPAuthModuleConf.class.isAssignableFrom(authModuleConfClass.getObject()); } } diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/SAML2EntityWizardBuilder.java b/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/SAML2EntityWizardBuilder.java deleted file mode 100644 index 0e7393a5ab3..00000000000 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/SAML2EntityWizardBuilder.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.client.console.wizards; - -import org.apache.commons.lang3.StringUtils; -import org.apache.syncope.client.console.wicket.markup.html.form.XMLEditorPanel; -import org.apache.syncope.common.lib.to.SAML2EntityTO; -import org.apache.wicket.PageReference; -import org.apache.wicket.extensions.wizard.WizardStep; -import org.apache.wicket.model.PropertyModel; - -abstract class SAML2EntityWizardBuilder extends BaseAjaxWizardBuilder { - - private static final long serialVersionUID = 1L; - - protected SAML2EntityWizardBuilder(final T defaultItem, final PageReference pageRef) { - super(defaultItem, pageRef); - } - - protected class Metadata extends WizardStep { - - private static final long serialVersionUID = -3043839139187792810L; - - Metadata(final T entity, final PageReference pageRef) { - add(new XMLEditorPanel(null, new PropertyModel<>(entity, "metadata"), false, pageRef)); - } - - @Override - public String getTitle() { - return "Metadata"; - } - } - - protected abstract class Pem extends WizardStep { - - private static final long serialVersionUID = -3043839139187792810L; - - protected final String property; - - Pem(final String property) { - this.property = property; - } - - @Override - public String getTitle() { - return StringUtils.capitalize(property); - } - } -} diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPEntityWizardBuilder.java b/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPEntityWizardBuilder.java index 9d88b52989a..2e3c7ced70f 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPEntityWizardBuilder.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPEntityWizardBuilder.java @@ -21,14 +21,17 @@ import java.io.Serializable; import java.nio.charset.StandardCharsets; import java.util.Base64; +import org.apache.commons.lang3.StringUtils; import org.apache.syncope.client.console.rest.SAML2IdPEntityRestClient; import org.apache.syncope.client.console.wicket.markup.html.form.TextEditorPanel; +import org.apache.syncope.client.console.wicket.markup.html.form.XMLEditorPanel; import org.apache.syncope.common.lib.to.SAML2IdPEntityTO; import org.apache.wicket.PageReference; import org.apache.wicket.extensions.wizard.WizardModel; +import org.apache.wicket.extensions.wizard.WizardStep; import org.apache.wicket.model.PropertyModel; -public class SAML2IdPEntityWizardBuilder extends SAML2EntityWizardBuilder { +public class SAML2IdPEntityWizardBuilder extends BaseAjaxWizardBuilder { private static final long serialVersionUID = -8013493490328546125L; @@ -100,14 +103,35 @@ protected WizardModel buildModelSteps(final SAML2IdPEntityTO modelObject, final return wizardModel; } - protected class TextPem extends Pem { + protected class Metadata extends WizardStep { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = -3043839139187792810L; + + Metadata(final SAML2IdPEntityTO entity, final PageReference pageRef) { + add(new XMLEditorPanel(null, new PropertyModel<>(entity, "metadata"), false, pageRef)); + } + + @Override + public String getTitle() { + return "Metadata"; + } + } + + protected class TextPem extends WizardStep { + + private static final long serialVersionUID = -3713108738476604821L; + + protected final String property; public TextPem(final SAML2IdPEntityTO entity, final String property, final PageReference pageRef) { - super(property); + this.property = property; add(new TextEditorPanel(null, new PropertyModel<>(entity, property), false, pageRef)); } + + @Override + public String getTitle() { + return StringUtils.capitalize(property); + } } } diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/SAML2SPEntityWizardBuilder.java b/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/SAML2SPEntityWizardBuilder.java deleted file mode 100644 index d3262189457..00000000000 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/SAML2SPEntityWizardBuilder.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.client.console.wizards; - -import jakarta.ws.rs.core.MediaType; -import java.io.Serializable; -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import org.apache.syncope.client.console.rest.SAML2SPEntityRestClient; -import org.apache.syncope.client.console.wicket.markup.html.form.BinaryFieldPanel; -import org.apache.syncope.client.ui.commons.Constants; -import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel; -import org.apache.syncope.client.ui.commons.wizards.AjaxWizard; -import org.apache.syncope.common.lib.to.SAML2SPEntityTO; -import org.apache.wicket.PageReference; -import org.apache.wicket.extensions.wizard.WizardModel; -import org.apache.wicket.extensions.wizard.WizardStep; -import org.apache.wicket.model.PropertyModel; - -public class SAML2SPEntityWizardBuilder extends SAML2EntityWizardBuilder { - - private static final long serialVersionUID = 2400472385439304277L; - - protected final SAML2SPEntityRestClient saml2SPEntityRestClient; - - public SAML2SPEntityWizardBuilder( - final SAML2SPEntityTO defaultItem, - final SAML2SPEntityRestClient saml2SPEntityRestClient, - final PageReference pageRef) { - - super(defaultItem, pageRef); - this.saml2SPEntityRestClient = saml2SPEntityRestClient; - } - - @Override - protected Serializable onApplyInternal(final SAML2SPEntityTO modelObject) { - if (modelObject.getMetadata() != null) { - modelObject.setMetadata(Base64.getEncoder().encodeToString( - modelObject.getMetadata().getBytes(StandardCharsets.UTF_8))); - } - saml2SPEntityRestClient.set(modelObject); - return modelObject; - } - - @Override - protected WizardModel buildModelSteps(final SAML2SPEntityTO modelObject, final WizardModel wizardModel) { - if (modelObject.getMetadata() != null) { - modelObject.setMetadata(new String(Base64.getDecoder().decode( - modelObject.getMetadata()), StandardCharsets.UTF_8)); - } - - wizardModel.add(new Profile(modelObject, mode == AjaxWizard.Mode.CREATE)); - wizardModel.add(new Metadata(modelObject, pageRef)); - wizardModel.add(new BinaryPem(modelObject, "keystore", pageRef)); - return wizardModel; - } - - protected static class Profile extends WizardStep { - - private static final long serialVersionUID = -3043839139187792810L; - - Profile(final SAML2SPEntityTO entity, final boolean isNew) { - AjaxTextFieldPanel key = new AjaxTextFieldPanel( - Constants.KEY_FIELD_NAME, Constants.KEY_FIELD_NAME, - new PropertyModel<>(entity, Constants.KEY_FIELD_NAME)); - key.addRequiredLabel(); - key.setEnabled(isNew); - add(key); - } - } - - protected class BinaryPem extends Pem { - - private static final long serialVersionUID = 1L; - - public BinaryPem(final SAML2SPEntityTO entity, final String property, final PageReference pageRef) { - super(property); - - add(new BinaryFieldPanel( - "content", - "", - new PropertyModel<>(entity, property), - MediaType.APPLICATION_OCTET_STREAM, - entity.getKey()) { - - private static final long serialVersionUID = -3268213909514986831L; - - @Override - protected PageReference getPageReference() { - return pageRef; - } - }); - } - } -} diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel.properties deleted file mode 100644 index 5289997f8c4..00000000000 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel.properties +++ /dev/null @@ -1,20 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -any.edit=Edit ${key} -any.new=New SP Entity -any.finish=Submit ${key} -any.cancel=Cancel ${key} diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_fr_CA.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_fr_CA.properties deleted file mode 100644 index c8a88c81ca8..00000000000 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_fr_CA.properties +++ /dev/null @@ -1,20 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -any.edit=Modifier ${key} -any.new=New SP Entity -any.finish=Soumettre ${key} -any.cancel=Annuler ${key} diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_it.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_it.properties deleted file mode 100644 index 9129629c7a9..00000000000 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_it.properties +++ /dev/null @@ -1,20 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -any.edit=Modifica ${key} -any.new=Nuova Entit\u00e0 SP -any.finish=Invia ${key} -any.cancel=Annulla ${key} diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_ja.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_ja.properties deleted file mode 100644 index cf51cb13e16..00000000000 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_ja.properties +++ /dev/null @@ -1,20 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -any.edit=${key} \u3092\u7de8\u96c6 -any.new=New SP Entity -any.finish=${key} \u3092\u5b9f\u884c -any.cancel=${key} \u3092\u30ad\u30e3\u30f3\u30bb\u30eb diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_pt_BR.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_pt_BR.properties deleted file mode 100644 index 5289997f8c4..00000000000 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_pt_BR.properties +++ /dev/null @@ -1,20 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -any.edit=Edit ${key} -any.new=New SP Entity -any.finish=Submit ${key} -any.cancel=Cancel ${key} diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_ru.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_ru.properties deleted file mode 100644 index 651eac5cc63..00000000000 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2SPEntityDirectoryPanel_ru.properties +++ /dev/null @@ -1,20 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -any.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c ${key} -any.new=New SP Entity -any.finish=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c ${key} -any.cancel=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c ${key} diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2.html b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$AuthModuleConfSAML.html similarity index 84% rename from client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2.html rename to client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$AuthModuleConfSAML.html index a82819c549e..ddacc6fb1b1 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/SAML2.html +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder$AuthModuleConfSAML.html @@ -18,6 +18,10 @@ --> -
+ +
+ + +
diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/SAML2EntityWizardBuilder$Metadata.html b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/SAML2IdPEntityWizardBuilder$Metadata.html similarity index 100% rename from client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/SAML2EntityWizardBuilder$Metadata.html rename to client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/SAML2IdPEntityWizardBuilder$Metadata.html diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/SAML2EntityWizardBuilder$Pem.html b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/SAML2IdPEntityWizardBuilder$TextPem.html similarity index 100% rename from client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/SAML2EntityWizardBuilder$Pem.html rename to client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/SAML2IdPEntityWizardBuilder$TextPem.html diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/SAML2SPEntityWizardBuilder$Profile.html b/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/SAML2SPEntityWizardBuilder$Profile.html deleted file mode 100644 index 993f7801bf7..00000000000 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/wizards/SAML2SPEntityWizardBuilder$Profile.html +++ /dev/null @@ -1,23 +0,0 @@ - - - -
[key]
-
- diff --git a/client/idrepo/common-ui/src/main/resources/MIMETypes.json b/client/idrepo/common-ui/src/main/resources/MIMETypes.json index e7e36820f0c..5d7b6387657 100644 --- a/client/idrepo/common-ui/src/main/resources/MIMETypes.json +++ b/client/idrepo/common-ui/src/main/resources/MIMETypes.json @@ -84,6 +84,10 @@ { "name": "application/java-byte-code" }, + { + "name": "application/x-java-keystore", + "extension": "jks" + }, { "name": "application/javascript" }, diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java index fdc90afd265..69e38e9d7ec 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/BinaryFieldPanel.java @@ -216,7 +216,11 @@ public String getAjaxIndicatorMarkupId() { } protected Response buildResponse() { - return Response.ok(new ByteArrayInputStream(Base64.getMimeDecoder().decode(getModelObject()))). + byte[] content = Optional.ofNullable(getModelObject()). + map(modelObject -> Base64.getMimeDecoder().decode(modelObject)). + orElseGet(() -> new byte[0]); + + return Response.ok(new ByteArrayInputStream(content)). type(StringUtils.isBlank(mimeType) ? MediaType.APPLICATION_OCTET_STREAM : mimeType). header(HttpHeaders.LOCATION, StringUtils.EMPTY). build(); diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/SAML2IdPAuthModuleConf.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/SAML2IdPAuthModuleConf.java index b78b3a2010c..35e4e0c839c 100644 --- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/SAML2IdPAuthModuleConf.java +++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/auth/SAML2IdPAuthModuleConf.java @@ -23,33 +23,27 @@ import java.util.Map; import org.apache.syncope.common.lib.to.AuthModuleTO; import org.apache.syncope.common.lib.types.SAML2BindingType; +import org.apache.syncope.common.lib.types.TriStateBoolean; public class SAML2IdPAuthModuleConf extends Pac4jAuthModuleConf implements AuthModuleConf { private static final long serialVersionUID = -471527731042579422L; /** - * The attribute value that should be used - * for the authenticated username, upon a successful authentication + * The attribute value that should be used for the authenticated username, upon a successful authentication * attempt. */ protected String userIdAttribute; /** - * The destination binding to use - * when creating authentication requests. + * The destination binding to use when creating authentication requests. */ protected SAML2BindingType destinationBinding = SAML2BindingType.REDIRECT; /** - * The Service Provider metadata path. + * Base64-encoded keystore content.. */ - protected String serviceProviderMetadataPath; - - /** - * The path to the keystore. - */ - protected String keystorePath; + protected String keystore; /** * The password to use when generating the SP keystore. @@ -59,7 +53,12 @@ public class SAML2IdPAuthModuleConf extends Pac4jAuthModuleConf implements AuthM /** * The password to use when generating the private key for the SP keystore. */ - protected String protectedKeyPassword; + protected String privateKeyPassword; + + /** + * Base64-encoded SP metadata content. + */ + protected String serviceProviderMetadata; /** * The metadata location of the identity provider that is to handle authentications. @@ -67,11 +66,10 @@ public class SAML2IdPAuthModuleConf extends Pac4jAuthModuleConf implements AuthM protected String identityProviderMetadataPath; /** - * Flag to indicate whether the allow-create flags - * for nameid policies should be set to true, false or ignored/defined. - * Accepted values are true, false or undefined. + * Flag to indicate whether the allow-create flags for nameid policies should be set to true, false or + * ignored/undefined. */ - protected String nameIdPolicyAllowCreate = "undefined"; + protected TriStateBoolean nameIdPolicyAllowCreate = TriStateBoolean.TRUE; /** * Once you have an authenticated session on the identity provider, usually it won't prompt you again to enter your @@ -149,8 +147,7 @@ public class SAML2IdPAuthModuleConf extends Pac4jAuthModuleConf implements AuthM protected int assertionConsumerServiceIndex = -1; /** - * Whether name qualifiers should be produced - * in the final saml response. + * Whether name qualifiers should be produced in the final saml response. */ protected boolean useNameQualifier = true; @@ -191,8 +188,7 @@ public class SAML2IdPAuthModuleConf extends Pac4jAuthModuleConf implements AuthM /** * Provider name set for the saml authentication request. - * Sets the human-readable name of the requester for use by - * the presenter's user agent or the identity provider. + * Sets the human-readable name of the requester for use by the presenter's user agent or the identity provider. */ protected String providerName; @@ -212,36 +208,36 @@ public void setDestinationBinding(final SAML2BindingType destinationBinding) { this.destinationBinding = destinationBinding; } - public String getServiceProviderMetadataPath() { - return serviceProviderMetadataPath; + public String getKeystorePassword() { + return keystorePassword; } - public void setServiceProviderMetadataPath(final String serviceProviderMetadataPath) { - this.serviceProviderMetadataPath = serviceProviderMetadataPath; + public void setKeystorePassword(final String keystorePassword) { + this.keystorePassword = keystorePassword; } - public String getKeystorePath() { - return keystorePath; + public String getPrivateKeyPassword() { + return privateKeyPassword; } - public void setKeystorePath(final String keystorePath) { - this.keystorePath = keystorePath; + public void setPrivateKeyPassword(final String privateKeyPassword) { + this.privateKeyPassword = privateKeyPassword; } - public String getKeystorePassword() { - return keystorePassword; + public String getKeystore() { + return keystore; } - public void setKeystorePassword(final String keystorePassword) { - this.keystorePassword = keystorePassword; + public void setKeystore(final String keystore) { + this.keystore = keystore; } - public String getPrivateKeyPassword() { - return protectedKeyPassword; + public String getServiceProviderMetadata() { + return serviceProviderMetadata; } - public void setPrivateKeyPassword(final String protectedKeyPassword) { - this.protectedKeyPassword = protectedKeyPassword; + public void setServiceProviderMetadata(final String serviceProviderMetadata) { + this.serviceProviderMetadata = serviceProviderMetadata; } public String getIdentityProviderMetadataPath() { @@ -292,11 +288,11 @@ public void setPassive(final boolean passive) { this.passive = passive; } - public String getNameIdPolicyAllowCreate() { + public TriStateBoolean getNameIdPolicyAllowCreate() { return nameIdPolicyAllowCreate; } - public void setNameIdPolicyAllowCreate(final String nameIdPolicyAllowCreate) { + public void setNameIdPolicyAllowCreate(final TriStateBoolean nameIdPolicyAllowCreate) { this.nameIdPolicyAllowCreate = nameIdPolicyAllowCreate; } diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/SAML2SPEntityTO.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/SAML2SPEntityTO.java deleted file mode 100644 index ee1f1d81901..00000000000 --- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/SAML2SPEntityTO.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.common.lib.to; - -import org.apache.commons.lang3.builder.EqualsBuilder; -import org.apache.commons.lang3.builder.HashCodeBuilder; - -public class SAML2SPEntityTO extends SAML2EntityTO { - - private static final long serialVersionUID = 6215073386484048953L; - - public static class Builder extends SAML2EntityTO.Builder { - - @Override - protected SAML2SPEntityTO newInstance() { - return new SAML2SPEntityTO(); - } - - public Builder keystore(final String keystore) { - getInstance().setKeystore(keystore); - return this; - } - - public Builder metadata(final String metadata) { - getInstance().setMetadata(metadata); - return this; - } - } - - private String keystore; - - private String metadata; - - public String getKeystore() { - return keystore; - } - - public void setKeystore(final String keystore) { - this.keystore = keystore; - } - - public String getMetadata() { - return metadata; - } - - public void setMetadata(final String metadata) { - this.metadata = metadata; - } - - @Override - public int hashCode() { - return new HashCodeBuilder(). - appendSuper(super.hashCode()). - append(keystore). - append(metadata). - build(); - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - SAML2SPEntityTO other = (SAML2SPEntityTO) obj; - return new EqualsBuilder(). - appendSuper(super.equals(obj)). - append(keystore, other.keystore). - append(metadata, other.metadata). - build(); - } -} diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMEntitlement.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMEntitlement.java index 7b914dff91c..ceae04b368d 100644 --- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMEntitlement.java +++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMEntitlement.java @@ -74,14 +74,6 @@ public final class AMEntitlement { public static final String SAML2_IDP_ENTITY_GET = "SAML2_IDP_ENTITY_GET"; - public static final String SAML2_SP_ENTITY_SET = "SAML2_SP_ENTITY_SET"; - - public static final String SAML2_SP_ENTITY_DELETE = "SAML2_SP_ENTITY_DELETE"; - - public static final String SAML2_SP_ENTITY_LIST = "SAML2_SP_ENTITY_LIST"; - - public static final String SAML2_SP_ENTITY_GET = "SAML2_SP_ENTITY_GET"; - public static final String AUTH_PROFILE_DELETE = "AUTH_PROFILE_DELETE"; public static final String AUTH_PROFILE_CREATE = "AUTH_PROFILE_CREATE"; diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SAML2SPEntityDAO.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/TriStateBoolean.java similarity index 81% rename from core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SAML2SPEntityDAO.java rename to common/am/lib/src/main/java/org/apache/syncope/common/lib/types/TriStateBoolean.java index 567c00b2f69..0639751737e 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SAML2SPEntityDAO.java +++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/TriStateBoolean.java @@ -16,9 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.syncope.core.persistence.api.dao; +package org.apache.syncope.common.lib.types; -import org.apache.syncope.core.persistence.api.entity.am.SAML2SPEntity; +public enum TriStateBoolean { + + TRUE, + FALSE, + UNDEFINED; -public interface SAML2SPEntityDAO extends DAO { } diff --git a/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2SPEntityService.java b/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2SPEntityService.java deleted file mode 100644 index 1aae8f14534..00000000000 --- a/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2SPEntityService.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.common.rest.api.service; - -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.enums.ParameterIn; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.security.SecurityRequirement; -import io.swagger.v3.oas.annotations.security.SecurityRequirements; -import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.validation.constraints.NotNull; -import jakarta.ws.rs.Consumes; -import jakarta.ws.rs.DELETE; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.MediaType; -import java.util.List; -import org.apache.syncope.common.lib.to.SAML2SPEntityTO; -import org.apache.syncope.common.rest.api.RESTHeaders; - -/** - * REST operations for SAML 2.0 SP entity. - */ -@Tag(name = "SAML 2.0") -@SecurityRequirements({ - @SecurityRequirement(name = "BasicAuthentication"), - @SecurityRequirement(name = "Bearer") }) -@Path("saml2/sp") -public interface SAML2SPEntityService extends JAXRSService { - - /** - * Returns the SAML 2.0 SP entities. - * - * @return SAML 2.0 SP entities - */ - @GET - @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) - List list(); - - /** - * Returns the SAML 2.0 SP entity matching the given key. - * - * @param key key of requested SAML 2.0 SP entity - * @return SAML 2.0 SP entity with matching key - */ - @GET - @Path("{key}") - @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) - SAML2SPEntityTO get(@NotNull @PathParam("key") String key); - - /** - * Store the entity to finalize the generation process. - * - * @param entityTO entity to be created - */ - @Parameter(name = "key", description = "SAML2SPEntityTO's key", in = ParameterIn.PATH, schema = - @Schema(type = "string")) - @POST - @Path("{key}") - @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) - @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) - void set(@NotNull SAML2SPEntityTO entityTO); - - /** - * Delets the SAML 2.0 SP entity matching the given key. - * - * @param key key of requested SAML 2.0 SP entity - */ - @DELETE - @Path("{key}") - @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) - void delete(@NotNull @PathParam("key") String key); -} diff --git a/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/wa/WASAML2SPService.java b/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/wa/WASAML2SPService.java new file mode 100644 index 00000000000..850cdbe1890 --- /dev/null +++ b/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/wa/WASAML2SPService.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.common.rest.api.service.wa; + +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.security.SecurityRequirements; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.constraints.NotNull; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.core.Response; +import java.io.InputStream; +import org.apache.syncope.common.rest.api.service.JAXRSService; + +/** + * REST operations for WA to work with SAML2SP clients. + */ +@Tag(name = "WA") +@SecurityRequirements({ + @SecurityRequirement(name = "BasicAuthentication"), + @SecurityRequirement(name = "Bearer") }) +@Path("wa/saml2sp") +public interface WASAML2SPService extends JAXRSService { + + @GET + @Path("{clientName}/keystore") + Response getSAML2SPKeystore(@NotNull @PathParam("clientName") String clientName); + + @PUT + @Path("{clientName}/keystore") + void setSAML2SPKeystore(@NotNull @PathParam("clientName") String clientName, InputStream keystore); + + @GET + @Path("{clientName}/metadata") + Response getSAML2SPMetadata(@NotNull @PathParam("clientName") String clientName); + + @PUT + @Path("{clientName}/metadata") + void setSAML2SPMetadata(@NotNull @PathParam("clientName") String clientName, InputStream metadata); +} diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/AMLogicContext.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/AMLogicContext.java index ce6fb71ab3d..bdff58a04eb 100644 --- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/AMLogicContext.java +++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/AMLogicContext.java @@ -35,7 +35,6 @@ import org.apache.syncope.core.persistence.api.dao.OIDCRPClientAppDAO; import org.apache.syncope.core.persistence.api.dao.SAML2IdPEntityDAO; import org.apache.syncope.core.persistence.api.dao.SAML2SPClientAppDAO; -import org.apache.syncope.core.persistence.api.dao.SAML2SPEntityDAO; import org.apache.syncope.core.persistence.api.dao.SRARouteDAO; import org.apache.syncope.core.persistence.api.dao.WAConfigDAO; import org.apache.syncope.core.persistence.api.entity.EntityFactory; @@ -46,7 +45,6 @@ import org.apache.syncope.core.provisioning.api.data.ClientAppDataBinder; import org.apache.syncope.core.provisioning.api.data.OIDCJWKSDataBinder; import org.apache.syncope.core.provisioning.api.data.SAML2IdPEntityDataBinder; -import org.apache.syncope.core.provisioning.api.data.SAML2SPEntityDataBinder; import org.apache.syncope.core.provisioning.api.data.SRARouteDataBinder; import org.apache.syncope.core.provisioning.api.data.WAConfigDataBinder; import org.apache.syncope.core.provisioning.api.data.wa.WAClientAppDataBinder; @@ -130,15 +128,6 @@ public SAML2IdPEntityLogic saml2IdPEntityLogic( return new SAML2IdPEntityLogic(binder, saml2IdPEntityDAO); } - @ConditionalOnMissingBean - @Bean - public SAML2SPEntityLogic saml2SPEntityLogic( - final SAML2SPEntityDataBinder binder, - final SAML2SPEntityDAO saml2SPEntityDAO) { - - return new SAML2SPEntityLogic(binder, saml2SPEntityDAO); - } - @ConditionalOnMissingBean @Bean public SRARouteLogic sraRouteLogic( diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/AuthModuleLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/AuthModuleLogic.java index 8c8a17960aa..0d547fa85ae 100644 --- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/AuthModuleLogic.java +++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/AuthModuleLogic.java @@ -18,11 +18,19 @@ */ package org.apache.syncope.core.logic; +import java.io.IOException; +import java.io.InputStream; import java.lang.reflect.Method; +import java.nio.charset.StandardCharsets; import java.util.List; +import java.util.Objects; import org.apache.commons.lang3.ArrayUtils; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.auth.Pac4jAuthModuleConf; +import org.apache.syncope.common.lib.auth.SAML2IdPAuthModuleConf; import org.apache.syncope.common.lib.to.AuthModuleTO; import org.apache.syncope.common.lib.types.AMEntitlement; +import org.apache.syncope.common.lib.types.ClientExceptionType; import org.apache.syncope.common.lib.types.IdRepoEntitlement; import org.apache.syncope.core.persistence.api.dao.AuthModuleDAO; import org.apache.syncope.core.persistence.api.dao.NotFoundException; @@ -81,6 +89,60 @@ public AuthModuleTO delete(final String key) { return deleted; } + protected AuthModule readByClientName(final String clientName) { + return authModuleDAO.findAll().stream(). + filter(m -> m.getConf() instanceof Pac4jAuthModuleConf conf + && (Objects.equals(clientName, conf.getClientName()) + || Objects.equals(clientName, m.getKey()))).findFirst(). + orElseThrow(() -> new NotFoundException("AuthModule with client name " + clientName)); + } + + @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')") + @Transactional(readOnly = true) + public SAML2IdPAuthModuleConf readSAML2SPConf(final String clientName) { + AuthModule authModule = readByClientName(clientName); + + return (SAML2IdPAuthModuleConf) authModule.getConf(); + } + + @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')") + public void setSAML2SPKeystore(final String clientName, final InputStream keystore) { + AuthModule authModule = readByClientName(clientName); + SAML2IdPAuthModuleConf conf = (SAML2IdPAuthModuleConf) authModule.getConf(); + + try { + conf.setKeystore(new String(keystore.readAllBytes(), StandardCharsets.UTF_8)); + authModule.setConf(conf); + + authModuleDAO.save(authModule); + } catch (IOException e) { + LOG.error("While reading the provided keystore", e); + + SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidEntity); + sce.getElements().add(e.getMessage()); + throw sce; + } + } + + @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')") + public void setSAML2SPMetadata(final String clientName, final InputStream metadata) { + AuthModule authModule = readByClientName(clientName); + SAML2IdPAuthModuleConf conf = (SAML2IdPAuthModuleConf) authModule.getConf(); + + try { + conf.setServiceProviderMetadata(new String(metadata.readAllBytes(), StandardCharsets.UTF_8)); + authModule.setConf(conf); + + authModuleDAO.save(authModule); + } catch (IOException e) { + LOG.error("While reading the provided metadata", e); + + SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidEntity); + sce.getElements().add(e.getMessage()); + throw sce; + } + } + @Override protected AuthModuleTO resolveReference(final Method method, final Object... args) throws UnresolvedReferenceException { diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPEntityLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPEntityLogic.java deleted file mode 100644 index 13734891239..00000000000 --- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPEntityLogic.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.logic; - -import java.lang.reflect.Method; -import java.util.List; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.syncope.common.lib.to.SAML2SPEntityTO; -import org.apache.syncope.common.lib.types.AMEntitlement; -import org.apache.syncope.common.lib.types.IdRepoEntitlement; -import org.apache.syncope.core.persistence.api.dao.NotFoundException; -import org.apache.syncope.core.persistence.api.dao.SAML2SPEntityDAO; -import org.apache.syncope.core.persistence.api.entity.am.SAML2SPEntity; -import org.apache.syncope.core.provisioning.api.data.SAML2SPEntityDataBinder; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.transaction.annotation.Transactional; - -public class SAML2SPEntityLogic extends AbstractTransactionalLogic { - - protected final SAML2SPEntityDataBinder binder; - - protected final SAML2SPEntityDAO saml2SPEntityDAO; - - public SAML2SPEntityLogic(final SAML2SPEntityDataBinder binder, final SAML2SPEntityDAO saml2SPEntityDAO) { - this.binder = binder; - this.saml2SPEntityDAO = saml2SPEntityDAO; - } - - @PreAuthorize("hasRole('" + AMEntitlement.SAML2_SP_ENTITY_LIST + "')") - @Transactional(readOnly = true) - public List list() { - return saml2SPEntityDAO.findAll().stream(). - map(binder::getSAML2SPEntityTO). - toList(); - } - - @PreAuthorize("hasRole('" + AMEntitlement.SAML2_SP_ENTITY_GET + "') " - + "or hasRole('" + IdRepoEntitlement.ANONYMOUS + "')") - @Transactional(readOnly = true) - public SAML2SPEntityTO read(final String key) { - return saml2SPEntityDAO.findById(key). - map(binder::getSAML2SPEntityTO). - orElseThrow(() -> new NotFoundException(key + " not found")); - } - - @PreAuthorize("hasRole('" + AMEntitlement.SAML2_SP_ENTITY_SET + "') " - + "or hasRole('" + IdRepoEntitlement.ANONYMOUS + "')") - public SAML2SPEntityTO set(final SAML2SPEntityTO entityTO) { - SAML2SPEntity entity = saml2SPEntityDAO.findById(entityTO.getKey()). - map(metadata -> binder.update(metadata, entityTO)). - orElseGet(() -> binder.create(entityTO)); - return binder.getSAML2SPEntityTO(saml2SPEntityDAO.save(entity)); - } - - @PreAuthorize("hasRole('" + AMEntitlement.SAML2_SP_ENTITY_DELETE + "')") - public void delete(final String key) { - saml2SPEntityDAO.findById(key).ifPresentOrElse( - saml2SPEntityDAO::delete, - () -> new NotFoundException("SAML SP " + key)); - } - - @Override - protected SAML2SPEntityTO resolveReference(final Method method, final Object... args) - throws UnresolvedReferenceException { - - String key = null; - if (ArrayUtils.isNotEmpty(args)) { - for (int i = 0; key == null && i < args.length; i++) { - if (args[i] instanceof String string) { - key = string; - } else if (args[i] instanceof SAML2SPEntityTO saml2SPEntityTO) { - key = saml2SPEntityTO.getKey(); - } - } - } - - if (key != null) { - try { - return binder.getSAML2SPEntityTO(saml2SPEntityDAO.findById(key).orElseThrow()); - } catch (Throwable ignore) { - LOG.debug("Unresolved reference", ignore); - throw new UnresolvedReferenceException(ignore); - } - } - throw new UnresolvedReferenceException(); - } -} diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AMRESTCXFContext.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AMRESTCXFContext.java index bcae28de555..3ca003d1d7a 100644 --- a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AMRESTCXFContext.java +++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/AMRESTCXFContext.java @@ -24,7 +24,6 @@ import org.apache.syncope.common.rest.api.service.ClientAppService; import org.apache.syncope.common.rest.api.service.OIDCJWKSService; import org.apache.syncope.common.rest.api.service.SAML2IdPEntityService; -import org.apache.syncope.common.rest.api.service.SAML2SPEntityService; import org.apache.syncope.common.rest.api.service.SRARouteService; import org.apache.syncope.common.rest.api.service.wa.GoogleMfaAuthAccountService; import org.apache.syncope.common.rest.api.service.wa.GoogleMfaAuthTokenService; @@ -32,6 +31,7 @@ import org.apache.syncope.common.rest.api.service.wa.MfaTrustStorageService; import org.apache.syncope.common.rest.api.service.wa.WAClientAppService; import org.apache.syncope.common.rest.api.service.wa.WAConfigService; +import org.apache.syncope.common.rest.api.service.wa.WASAML2SPService; import org.apache.syncope.common.rest.api.service.wa.WebAuthnRegistrationService; import org.apache.syncope.core.logic.AttrRepoLogic; import org.apache.syncope.core.logic.AuthModuleLogic; @@ -39,7 +39,6 @@ import org.apache.syncope.core.logic.ClientAppLogic; import org.apache.syncope.core.logic.OIDCJWKSLogic; import org.apache.syncope.core.logic.SAML2IdPEntityLogic; -import org.apache.syncope.core.logic.SAML2SPEntityLogic; import org.apache.syncope.core.logic.SRARouteLogic; import org.apache.syncope.core.logic.wa.GoogleMfaAuthAccountLogic; import org.apache.syncope.core.logic.wa.GoogleMfaAuthTokenLogic; @@ -54,7 +53,6 @@ import org.apache.syncope.core.rest.cxf.service.ClientAppServiceImpl; import org.apache.syncope.core.rest.cxf.service.OIDCJWKSServiceImpl; import org.apache.syncope.core.rest.cxf.service.SAML2IdPEntityServiceImpl; -import org.apache.syncope.core.rest.cxf.service.SAML2SPEntityServiceImpl; import org.apache.syncope.core.rest.cxf.service.SRARouteServiceImpl; import org.apache.syncope.core.rest.cxf.service.wa.GoogleMfaAuthAccountServiceImpl; import org.apache.syncope.core.rest.cxf.service.wa.GoogleMfaAuthTokenServiceImpl; @@ -62,6 +60,7 @@ import org.apache.syncope.core.rest.cxf.service.wa.MfaTrustStorageServiceImpl; import org.apache.syncope.core.rest.cxf.service.wa.WAClientAppServiceImpl; import org.apache.syncope.core.rest.cxf.service.wa.WAConfigServiceImpl; +import org.apache.syncope.core.rest.cxf.service.wa.WASAML2SPServiceImpl; import org.apache.syncope.core.rest.cxf.service.wa.WebAuthnRegistrationServiceImpl; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; @@ -128,12 +127,6 @@ public SAML2IdPEntityService saml2IdPEntityService(final SAML2IdPEntityLogic sam return new SAML2IdPEntityServiceImpl(saml2IdPEntityLogic); } - @ConditionalOnMissingBean - @Bean - public SAML2SPEntityService saml2SPEntityService(final SAML2SPEntityLogic saml2SPEntityLogic) { - return new SAML2SPEntityServiceImpl(saml2SPEntityLogic); - } - @ConditionalOnMissingBean @Bean public SRARouteService sraRouteService(final SRARouteLogic sraRouteLogic) { @@ -152,6 +145,12 @@ public WAClientAppService waClientAppService(final WAClientAppLogic waClientAppL return new WAClientAppServiceImpl(waClientAppLogic); } + @ConditionalOnMissingBean + @Bean + public WASAML2SPService waSAML2SPService(final AuthModuleLogic authModuleLogic) { + return new WASAML2SPServiceImpl(authModuleLogic); + } + @ConditionalOnMissingBean @Bean public WAConfigService waConfigService(final WAConfigLogic waConfigLogic) { diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SPEntityServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SPEntityServiceImpl.java deleted file mode 100644 index a3d5507a323..00000000000 --- a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2SPEntityServiceImpl.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.rest.cxf.service; - -import java.util.List; -import org.apache.syncope.common.lib.to.SAML2SPEntityTO; -import org.apache.syncope.common.rest.api.service.SAML2SPEntityService; -import org.apache.syncope.core.logic.SAML2SPEntityLogic; - -public class SAML2SPEntityServiceImpl extends AbstractService implements SAML2SPEntityService { - - protected final SAML2SPEntityLogic logic; - - public SAML2SPEntityServiceImpl(final SAML2SPEntityLogic logic) { - this.logic = logic; - } - - @Override - public List list() { - return logic.list(); - } - - @Override - public SAML2SPEntityTO get(final String key) { - return logic.read(key); - } - - @Override - public void set(final SAML2SPEntityTO entityTO) { - logic.set(entityTO); - } - - @Override - public void delete(final String key) { - logic.delete(key); - } -} diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/WASAML2SPServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/WASAML2SPServiceImpl.java new file mode 100644 index 00000000000..7fa509eaca6 --- /dev/null +++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/WASAML2SPServiceImpl.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.rest.cxf.service.wa; + +import jakarta.ws.rs.core.Response; +import java.io.InputStream; +import java.util.Optional; +import org.apache.syncope.common.rest.api.service.wa.WASAML2SPService; +import org.apache.syncope.core.logic.AuthModuleLogic; +import org.apache.syncope.core.rest.cxf.service.AbstractService; + +public class WASAML2SPServiceImpl extends AbstractService implements WASAML2SPService { + + protected final AuthModuleLogic logic; + + public WASAML2SPServiceImpl(final AuthModuleLogic logic) { + this.logic = logic; + } + + @Override + public Response getSAML2SPKeystore(final String clientName) { + return Optional.ofNullable(logic.readSAML2SPConf(clientName).getKeystore()). + map(Response::ok). + orElseGet(() -> Response.status(Response.Status.NOT_FOUND)). + build(); + } + + @Override + public void setSAML2SPKeystore(final String clientName, final InputStream keystore) { + logic.setSAML2SPKeystore(clientName, keystore); + } + + @Override + public Response getSAML2SPMetadata(final String clientName) { + return Optional.ofNullable(logic.readSAML2SPConf(clientName).getServiceProviderMetadata()). + map(Response::ok). + orElseGet(() -> Response.status(Response.Status.NOT_FOUND)). + build(); + } + + @Override + public void setSAML2SPMetadata(final String clientName, final InputStream metadata) { + logic.setSAML2SPMetadata(clientName, metadata); + } +} diff --git a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java index 40fd1f311ea..91092829b05 100644 --- a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java +++ b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java @@ -286,7 +286,6 @@ public ReconStatus status( } protected SyncDeltaBuilder syncDeltaBuilder( - final AnyType anyType, final ExternalResource resource, final Provision provision, final Filter filter, @@ -328,7 +327,7 @@ public ReconStatus status( Triple triple = getProvision(anyTypeKey, resourceKey); SyncDeltaBuilder syncDeltaBuilder = syncDeltaBuilder( - triple.getLeft(), triple.getMiddle(), triple.getRight(), filter, moreAttrsToGet); + triple.getMiddle(), triple.getRight(), filter, moreAttrsToGet); ReconStatus status = new ReconStatus(); if (syncDeltaBuilder.getObject() != null) { @@ -414,7 +413,7 @@ public List push( Triple triple = getProvision(anyTypeKey, resourceKey); SyncDeltaBuilder syncDeltaBuilder = syncDeltaBuilder( - triple.getLeft(), triple.getMiddle(), triple.getRight(), filter, moreAttrsToGet); + triple.getMiddle(), triple.getRight(), filter, moreAttrsToGet); SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Reconciliation); List results = new ArrayList<>(); diff --git a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java index d4a88b91ff7..b653b9b4fa9 100644 --- a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java +++ b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java @@ -357,7 +357,6 @@ public ConnObject readConnObjectByConnObjectKeyValue( connectorManager.getConnector(triple.getMiddle()), connObjectKeyItem, connObjectKeyValue, - triple.getMiddle(), triple.getRight(), Optional.empty()). map(connectorObject -> ConnObjectUtils.getConnObjectTO( diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/SAML2SPEntity.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/SAML2SPEntity.java deleted file mode 100644 index 469e68d24b9..00000000000 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/SAML2SPEntity.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.api.entity.am; - -import org.apache.syncope.core.persistence.api.entity.ProvidedKeyEntity; - -public interface SAML2SPEntity extends ProvidedKeyEntity { - - byte[] getKeystore(); - - void setKeystore(byte[] keystore); - - byte[] getMetadata(); - - void setMetadata(byte[] metadata); -} diff --git a/core/persistence-jpa-upgrader/src/main/resources/schema.xml b/core/persistence-jpa-upgrader/src/main/resources/schema.xml index 6c16bbee010..e0de4a63b3a 100644 --- a/core/persistence-jpa-upgrader/src/main/resources/schema.xml +++ b/core/persistence-jpa-upgrader/src/main/resources/schema.xml @@ -1140,12 +1140,6 @@ under the License.
- - - - - -
@@ -1431,4 +1425,4 @@ under the License.
- \ No newline at end of file + diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java index b44799e0de9..9eee3cbcd54 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java @@ -69,7 +69,6 @@ import org.apache.syncope.core.persistence.api.dao.RoleDAO; import org.apache.syncope.core.persistence.api.dao.SAML2IdPEntityDAO; import org.apache.syncope.core.persistence.api.dao.SAML2SPClientAppDAO; -import org.apache.syncope.core.persistence.api.dao.SAML2SPEntityDAO; import org.apache.syncope.core.persistence.api.dao.SRARouteDAO; import org.apache.syncope.core.persistence.api.dao.SecurityQuestionDAO; import org.apache.syncope.core.persistence.api.dao.TaskDAO; @@ -174,7 +173,6 @@ import org.apache.syncope.core.persistence.jpa.dao.repo.SAML2SPClientAppRepo; import org.apache.syncope.core.persistence.jpa.dao.repo.SAML2SPClientAppRepoExt; import org.apache.syncope.core.persistence.jpa.dao.repo.SAML2SPClientAppRepoExtImpl; -import org.apache.syncope.core.persistence.jpa.dao.repo.SAML2SPEntityRepo; import org.apache.syncope.core.persistence.jpa.dao.repo.SRARouteRepo; import org.apache.syncope.core.persistence.jpa.dao.repo.SecurityQuestionRepo; import org.apache.syncope.core.persistence.jpa.dao.repo.SecurityQuestionRepoExt; @@ -927,12 +925,6 @@ public SAML2SPClientAppDAO saml2SPClientAppDAO( return jpaRepositoryFactory.getRepository(SAML2SPClientAppRepo.class, saml2SPClientAppRepoExt); } - @ConditionalOnMissingBean - @Bean - public SAML2SPEntityDAO saml2SPEntityDAO(final JpaRepositoryFactory jpaRepositoryFactory) { - return jpaRepositoryFactory.getRepository(SAML2SPEntityRepo.class); - } - @ConditionalOnMissingBean @Bean public SecurityQuestionRepoExt securityQuestionRepoExt( diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/SAML2SPEntityRepo.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/SAML2SPEntityRepo.java deleted file mode 100644 index 94dfe9736f9..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/SAML2SPEntityRepo.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.dao.repo; - -import org.apache.syncope.core.persistence.api.dao.SAML2SPEntityDAO; -import org.apache.syncope.core.persistence.jpa.entity.am.JPASAML2SPEntity; -import org.springframework.data.repository.ListCrudRepository; - -public interface SAML2SPEntityRepo - extends ListCrudRepository, SAML2SPEntityDAO { - -} diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntityFactory.java index a91b28266a4..c1089baa2bd 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntityFactory.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntityFactory.java @@ -55,7 +55,6 @@ import org.apache.syncope.core.persistence.api.entity.am.OIDCRPClientApp; import org.apache.syncope.core.persistence.api.entity.am.SAML2IdPEntity; import org.apache.syncope.core.persistence.api.entity.am.SAML2SPClientApp; -import org.apache.syncope.core.persistence.api.entity.am.SAML2SPEntity; import org.apache.syncope.core.persistence.api.entity.am.WAConfigEntry; import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership; import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership; @@ -102,7 +101,6 @@ import org.apache.syncope.core.persistence.jpa.entity.am.JPAOIDCRPClientApp; import org.apache.syncope.core.persistence.jpa.entity.am.JPASAML2IdPEntity; import org.apache.syncope.core.persistence.jpa.entity.am.JPASAML2SPClientApp; -import org.apache.syncope.core.persistence.jpa.entity.am.JPASAML2SPEntity; import org.apache.syncope.core.persistence.jpa.entity.am.JPAWAConfigEntry; import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership; import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAMembership; @@ -282,8 +280,6 @@ public E newEntity(final Class reference) { result = (E) new JPASAML2SPClientApp(); } else if (reference.equals(SAML2IdPEntity.class)) { result = (E) new JPASAML2IdPEntity(); - } else if (reference.equals(SAML2SPEntity.class)) { - result = (E) new JPASAML2SPEntity(); } else if (reference.equals(AuthProfile.class)) { result = (E) new JPAAuthProfile(); } else if (reference.equals(OIDCJWKS.class)) { diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPASAML2SPEntity.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPASAML2SPEntity.java deleted file mode 100644 index c0e6f79d1d6..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPASAML2SPEntity.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.entity.am; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.Lob; -import jakarta.persistence.Table; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.syncope.core.persistence.api.entity.am.SAML2SPEntity; -import org.apache.syncope.core.persistence.jpa.entity.AbstractProvidedKeyEntity; - -@Entity -@Table(name = JPASAML2SPEntity.TABLE) -public class JPASAML2SPEntity extends AbstractProvidedKeyEntity implements SAML2SPEntity { - - public static final String TABLE = "SAML2SPEntity"; - - private static final long serialVersionUID = 12342617217394093L; - - @Column(nullable = true) - @Lob - private byte[] keystore; - - @Column(nullable = true) - @Lob - private byte[] metadata; - - @Override - public byte[] getKeystore() { - return keystore; - } - - @Override - public void setKeystore(final byte[] keystore) { - this.keystore = ArrayUtils.clone(keystore); - } - - @Override - public byte[] getMetadata() { - return metadata; - } - - @Override - public void setMetadata(final byte[] metadata) { - this.metadata = ArrayUtils.clone(metadata); - } -} diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/SAML2SPEntityTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/SAML2SPEntityTest.java deleted file mode 100644 index 324e6e0cfc7..00000000000 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/SAML2SPEntityTest.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.inner; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.math.BigInteger; -import java.nio.charset.StandardCharsets; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.KeyStore; -import java.security.Signature; -import java.security.cert.Certificate; -import java.security.cert.CertificateFactory; -import java.util.Date; -import java.util.UUID; -import org.apache.cxf.helpers.IOUtils; -import org.apache.syncope.core.persistence.api.dao.SAML2SPEntityDAO; -import org.apache.syncope.core.persistence.api.entity.am.SAML2SPEntity; -import org.apache.syncope.core.persistence.jpa.AbstractTest; -import org.bouncycastle.asn1.ASN1EncodableVector; -import org.bouncycastle.asn1.ASN1Encoding; -import org.bouncycastle.asn1.ASN1Integer; -import org.bouncycastle.asn1.DERBitString; -import org.bouncycastle.asn1.DERNull; -import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.AlgorithmIdentifier; -import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.asn1.x509.TBSCertificate; -import org.bouncycastle.asn1.x509.Time; -import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.io.ClassPathResource; -import org.springframework.transaction.annotation.Transactional; - -@Transactional -public class SAML2SPEntityTest extends AbstractTest { - - private static Certificate createSelfSignedCert(final KeyPair keyPair) throws Exception { - X500Name dn = new X500Name("cn=Unknown"); - V3TBSCertificateGenerator certGen = new V3TBSCertificateGenerator(); - - certGen.setSerialNumber(new ASN1Integer(BigInteger.valueOf(1))); - certGen.setIssuer(dn); - certGen.setSubject(dn); - certGen.setStartDate(new Time(new Date(System.currentTimeMillis() - 1000L))); - - Date expiration = new Date(System.currentTimeMillis() + 100000); - certGen.setEndDate(new Time(expiration)); - - AlgorithmIdentifier sigAlgID = new AlgorithmIdentifier( - PKCSObjectIdentifiers.sha1WithRSAEncryption, DERNull.INSTANCE); - certGen.setSignature(sigAlgID); - certGen.setSubjectPublicKeyInfo(SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded())); - - Signature sig = Signature.getInstance("SHA1WithRSA"); - sig.initSign(keyPair.getPrivate()); - sig.update(certGen.generateTBSCertificate().getEncoded(ASN1Encoding.DER)); - - TBSCertificate tbsCert = certGen.generateTBSCertificate(); - ASN1EncodableVector v = new ASN1EncodableVector(); - - v.add(tbsCert); - v.add(sigAlgID); - v.add(new DERBitString(sig.sign())); - - Certificate cert = CertificateFactory.getInstance("X.509"). - generateCertificate(new ByteArrayInputStream(new DERSequence(v).getEncoded(ASN1Encoding.DER))); - cert.verify(keyPair.getPublic()); - return cert; - } - - @Autowired - private SAML2SPEntityDAO saml2SPEntityDAO; - - private SAML2SPEntity create(final String owner) throws Exception { - SAML2SPEntity entity = entityFactory.newEntity(SAML2SPEntity.class); - entity.setKey(owner); - entity.setMetadata(IOUtils.toString( - new ClassPathResource("sp-metadata.xml").getInputStream()).getBytes(StandardCharsets.UTF_8)); - - KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); - char[] pwdArray = "password".toCharArray(); - ks.load(null, pwdArray); - - KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); - keyPairGenerator.initialize(4096); - KeyPair keyPair = keyPairGenerator.generateKeyPair(); - Certificate certificate = createSelfSignedCert(keyPair); - ks.setKeyEntry("main", keyPair.getPrivate(), "password".toCharArray(), new Certificate[] { certificate }); - - try (ByteArrayOutputStream fos = new ByteArrayOutputStream()) { - ks.store(fos, pwdArray); - fos.flush(); - entity.setKeystore(fos.toByteArray()); - } - assertNotNull(entity.getKeystore()); - - entity = saml2SPEntityDAO.save(entity); - assertNotNull(saml2SPEntityDAO.findById(entity.getKey())); - return entity; - } - - @Test - public void find() throws Exception { - create("Syncope"); - - assertTrue(saml2SPEntityDAO.findById("Syncope").isPresent()); - - assertTrue(saml2SPEntityDAO.findById(UUID.randomUUID().toString()).isEmpty()); - } - - @Test - public void save() throws Exception { - SAML2SPEntity created = create("SyncopeCreate"); - - KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); - char[] pwdArray = "password".toCharArray(); - ks.load(new ByteArrayInputStream(created.getKeystore()), pwdArray); - assertTrue(ks.size() > 0); - } - - @Test - public void update() throws Exception { - SAML2SPEntity entity = create("SyncopeUpdate"); - assertNotNull(entity); - entity.setKey("OtherSyncope"); - - entity = saml2SPEntityDAO.save(entity); - assertNotNull(entity); - - entityManager.flush(); - - SAML2SPEntity found = saml2SPEntityDAO.findById(entity.getKey()).orElseThrow(); - assertEquals("OtherSyncope", found.getKey()); - } -} diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml index 9009ca3c278..9e02cede0c3 100644 --- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml +++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml @@ -78,7 +78,7 @@ under the License. description="Duo Mfa auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.DuoMfaAuthModuleConf","integrationKey":"DIOXVRZD2UMZ8XXMNFQ5","secretKey":"Q2IU2i8BFNd6VYflZT8Evl6lF7oPlj3PM15BmRU7", "apiHost":"theapi.duosecurity.com"}'/> - diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/PersistenceContext.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/PersistenceContext.java index 85461094525..9544c68fcd3 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/PersistenceContext.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/PersistenceContext.java @@ -71,7 +71,6 @@ import org.apache.syncope.core.persistence.api.dao.RoleDAO; import org.apache.syncope.core.persistence.api.dao.SAML2IdPEntityDAO; import org.apache.syncope.core.persistence.api.dao.SAML2SPClientAppDAO; -import org.apache.syncope.core.persistence.api.dao.SAML2SPEntityDAO; import org.apache.syncope.core.persistence.api.dao.SRARouteDAO; import org.apache.syncope.core.persistence.api.dao.SecurityQuestionDAO; import org.apache.syncope.core.persistence.api.dao.TaskDAO; @@ -183,7 +182,6 @@ import org.apache.syncope.core.persistence.neo4j.dao.repo.SAML2SPClientAppRepo; import org.apache.syncope.core.persistence.neo4j.dao.repo.SAML2SPClientAppRepoExt; import org.apache.syncope.core.persistence.neo4j.dao.repo.SAML2SPClientAppRepoExtImpl; -import org.apache.syncope.core.persistence.neo4j.dao.repo.SAML2SPEntityRepo; import org.apache.syncope.core.persistence.neo4j.dao.repo.SRARouteRepo; import org.apache.syncope.core.persistence.neo4j.dao.repo.SecurityQuestionRepo; import org.apache.syncope.core.persistence.neo4j.dao.repo.SecurityQuestionRepoExt; @@ -1335,12 +1333,6 @@ public SAML2SPClientAppDAO saml2SPClientAppDAO( return neo4jRepositoryFactory.getRepository(SAML2SPClientAppRepo.class, saml2SPClientAppRepoExt); } - @ConditionalOnMissingBean - @Bean - public SAML2SPEntityDAO saml2SPEntityDAO(final SyncopeNeo4jRepositoryFactory neo4jRepositoryFactory) { - return neo4jRepositoryFactory.getRepository(SAML2SPEntityRepo.class); - } - @ConditionalOnMissingBean @Bean public SecurityQuestionRepoExt securityQuestionRepoExt( diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/SAML2SPEntityRepo.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/SAML2SPEntityRepo.java deleted file mode 100644 index b76b7daa3d5..00000000000 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/SAML2SPEntityRepo.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.neo4j.dao.repo; - -import org.apache.syncope.core.persistence.api.dao.SAML2SPEntityDAO; -import org.apache.syncope.core.persistence.neo4j.entity.am.Neo4jSAML2SPEntity; -import org.springframework.data.repository.ListCrudRepository; - -public interface SAML2SPEntityRepo - extends ListCrudRepository, SAML2SPEntityDAO { - -} diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jEntityFactory.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jEntityFactory.java index 5a79855f470..b8f71ea9130 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jEntityFactory.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jEntityFactory.java @@ -56,7 +56,6 @@ import org.apache.syncope.core.persistence.api.entity.am.OIDCRPClientApp; import org.apache.syncope.core.persistence.api.entity.am.SAML2IdPEntity; import org.apache.syncope.core.persistence.api.entity.am.SAML2SPClientApp; -import org.apache.syncope.core.persistence.api.entity.am.SAML2SPEntity; import org.apache.syncope.core.persistence.api.entity.am.WAConfigEntry; import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership; import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership; @@ -103,7 +102,6 @@ import org.apache.syncope.core.persistence.neo4j.entity.am.Neo4jOIDCRPClientApp; import org.apache.syncope.core.persistence.neo4j.entity.am.Neo4jSAML2IdPEntity; import org.apache.syncope.core.persistence.neo4j.entity.am.Neo4jSAML2SPClientApp; -import org.apache.syncope.core.persistence.neo4j.entity.am.Neo4jSAML2SPEntity; import org.apache.syncope.core.persistence.neo4j.entity.am.Neo4jWAConfigEntry; import org.apache.syncope.core.persistence.neo4j.entity.anyobject.Neo4jADynGroupMembership; import org.apache.syncope.core.persistence.neo4j.entity.anyobject.Neo4jAMembership; @@ -283,8 +281,6 @@ public E newEntity(final Class reference) { result = (E) new Neo4jSAML2SPClientApp(); } else if (reference.equals(SAML2IdPEntity.class)) { result = (E) new Neo4jSAML2IdPEntity(); - } else if (reference.equals(SAML2SPEntity.class)) { - result = (E) new Neo4jSAML2SPEntity(); } else if (reference.equals(AuthProfile.class)) { result = (E) new Neo4jAuthProfile(); } else if (reference.equals(OIDCJWKS.class)) { diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/am/Neo4jSAML2SPEntity.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/am/Neo4jSAML2SPEntity.java deleted file mode 100644 index ba40300265b..00000000000 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/am/Neo4jSAML2SPEntity.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.neo4j.entity.am; - -import org.apache.commons.lang3.ArrayUtils; -import org.apache.syncope.core.persistence.api.entity.am.SAML2SPEntity; -import org.apache.syncope.core.persistence.neo4j.entity.AbstractProvidedKeyNode; -import org.springframework.data.neo4j.core.schema.Node; - -@Node(Neo4jSAML2SPEntity.NODE) -public class Neo4jSAML2SPEntity extends AbstractProvidedKeyNode implements SAML2SPEntity { - - public static final String NODE = "SAML2SPEntity"; - - private static final long serialVersionUID = 12342617217394093L; - - private byte[] keystore; - - private byte[] metadata; - - @Override - public byte[] getKeystore() { - return keystore; - } - - @Override - public void setKeystore(final byte[] keystore) { - this.keystore = ArrayUtils.clone(keystore); - } - - @Override - public byte[] getMetadata() { - return metadata; - } - - @Override - public void setMetadata(final byte[] metadata) { - this.metadata = ArrayUtils.clone(metadata); - } -} diff --git a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/SAML2SPEntityTest.java b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/SAML2SPEntityTest.java deleted file mode 100644 index 27232e64644..00000000000 --- a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/SAML2SPEntityTest.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.neo4j.inner; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.math.BigInteger; -import java.nio.charset.StandardCharsets; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.KeyStore; -import java.security.Signature; -import java.security.cert.Certificate; -import java.security.cert.CertificateFactory; -import java.util.Date; -import java.util.UUID; -import org.apache.cxf.helpers.IOUtils; -import org.apache.syncope.core.persistence.api.dao.SAML2SPEntityDAO; -import org.apache.syncope.core.persistence.api.entity.am.SAML2SPEntity; -import org.apache.syncope.core.persistence.neo4j.AbstractTest; -import org.bouncycastle.asn1.ASN1EncodableVector; -import org.bouncycastle.asn1.ASN1Encoding; -import org.bouncycastle.asn1.ASN1Integer; -import org.bouncycastle.asn1.DERBitString; -import org.bouncycastle.asn1.DERNull; -import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.AlgorithmIdentifier; -import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.asn1.x509.TBSCertificate; -import org.bouncycastle.asn1.x509.Time; -import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.io.ClassPathResource; -import org.springframework.transaction.annotation.Transactional; - -@Transactional -public class SAML2SPEntityTest extends AbstractTest { - - private static Certificate createSelfSignedCert(final KeyPair keyPair) throws Exception { - X500Name dn = new X500Name("cn=Unknown"); - V3TBSCertificateGenerator certGen = new V3TBSCertificateGenerator(); - - certGen.setSerialNumber(new ASN1Integer(BigInteger.valueOf(1))); - certGen.setIssuer(dn); - certGen.setSubject(dn); - certGen.setStartDate(new Time(new Date(System.currentTimeMillis() - 1000L))); - - Date expiration = new Date(System.currentTimeMillis() + 100000); - certGen.setEndDate(new Time(expiration)); - - AlgorithmIdentifier sigAlgID = new AlgorithmIdentifier( - PKCSObjectIdentifiers.sha1WithRSAEncryption, DERNull.INSTANCE); - certGen.setSignature(sigAlgID); - certGen.setSubjectPublicKeyInfo(SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded())); - - Signature sig = Signature.getInstance("SHA1WithRSA"); - sig.initSign(keyPair.getPrivate()); - sig.update(certGen.generateTBSCertificate().getEncoded(ASN1Encoding.DER)); - - TBSCertificate tbsCert = certGen.generateTBSCertificate(); - ASN1EncodableVector v = new ASN1EncodableVector(); - - v.add(tbsCert); - v.add(sigAlgID); - v.add(new DERBitString(sig.sign())); - - Certificate cert = CertificateFactory.getInstance("X.509"). - generateCertificate(new ByteArrayInputStream(new DERSequence(v).getEncoded(ASN1Encoding.DER))); - cert.verify(keyPair.getPublic()); - return cert; - } - - @Autowired - private SAML2SPEntityDAO saml2SPEntityDAO; - - private SAML2SPEntity create(final String owner) throws Exception { - SAML2SPEntity entity = entityFactory.newEntity(SAML2SPEntity.class); - entity.setKey(owner); - entity.setMetadata(IOUtils.toString( - new ClassPathResource("sp-metadata.xml").getInputStream()).getBytes(StandardCharsets.UTF_8)); - - KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); - char[] pwdArray = "password".toCharArray(); - ks.load(null, pwdArray); - - KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); - keyPairGenerator.initialize(4096); - KeyPair keyPair = keyPairGenerator.generateKeyPair(); - Certificate certificate = createSelfSignedCert(keyPair); - ks.setKeyEntry("main", keyPair.getPrivate(), "password".toCharArray(), new Certificate[] { certificate }); - - try (ByteArrayOutputStream fos = new ByteArrayOutputStream()) { - ks.store(fos, pwdArray); - fos.flush(); - entity.setKeystore(fos.toByteArray()); - } - assertNotNull(entity.getKeystore()); - - entity = saml2SPEntityDAO.save(entity); - assertNotNull(saml2SPEntityDAO.findById(entity.getKey())); - return entity; - } - - @Test - public void find() throws Exception { - create("Syncope"); - - assertTrue(saml2SPEntityDAO.findById("Syncope").isPresent()); - - assertTrue(saml2SPEntityDAO.findById(UUID.randomUUID().toString()).isEmpty()); - } - - @Test - public void save() throws Exception { - SAML2SPEntity created = create("SyncopeCreate"); - - KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); - char[] pwdArray = "password".toCharArray(); - ks.load(new ByteArrayInputStream(created.getKeystore()), pwdArray); - assertTrue(ks.size() > 0); - } - - @Test - public void update() throws Exception { - SAML2SPEntity entity = create("SyncopeUpdate"); - assertNotNull(entity); - entity.setKey("OtherSyncope"); - - entity = saml2SPEntityDAO.save(entity); - assertNotNull(entity); - - SAML2SPEntity found = saml2SPEntityDAO.findById(entity.getKey()).orElseThrow(); - assertEquals("OtherSyncope", found.getKey()); - } -} diff --git a/core/persistence-neo4j/src/test/resources/domains/MasterContent.xml b/core/persistence-neo4j/src/test/resources/domains/MasterContent.xml index 0d8c78b01a4..c271719ecf6 100644 --- a/core/persistence-neo4j/src/test/resources/domains/MasterContent.xml +++ b/core/persistence-neo4j/src/test/resources/domains/MasterContent.xml @@ -78,7 +78,7 @@ under the License. description="Duo Mfa auth module" jsonConf='{"_class":"org.apache.syncope.common.lib.auth.DuoMfaAuthModuleConf","integrationKey":"DIOXVRZD2UMZ8XXMNFQ5","secretKey":"Q2IU2i8BFNd6VYflZT8Evl6lF7oPlj3PM15BmRU7", "apiHost":"theapi.duosecurity.com"}'/> - diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SAML2SPEntityDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SAML2SPEntityDataBinder.java deleted file mode 100644 index f21ae3586db..00000000000 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/SAML2SPEntityDataBinder.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.provisioning.api.data; - -import org.apache.syncope.common.lib.to.SAML2SPEntityTO; -import org.apache.syncope.core.persistence.api.entity.am.SAML2SPEntity; - -public interface SAML2SPEntityDataBinder { - - SAML2SPEntity create(SAML2SPEntityTO entityTO); - - SAML2SPEntity update(SAML2SPEntity entity, SAML2SPEntityTO entityTO); - - SAML2SPEntityTO getSAML2SPEntityTO(SAML2SPEntity entity); -} diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java index 580783622c7..47b0a67cd8f 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java @@ -96,7 +96,6 @@ import org.apache.syncope.core.provisioning.api.data.ResourceDataBinder; import org.apache.syncope.core.provisioning.api.data.RoleDataBinder; import org.apache.syncope.core.provisioning.api.data.SAML2IdPEntityDataBinder; -import org.apache.syncope.core.provisioning.api.data.SAML2SPEntityDataBinder; import org.apache.syncope.core.provisioning.api.data.SRARouteDataBinder; import org.apache.syncope.core.provisioning.api.data.SchemaDataBinder; import org.apache.syncope.core.provisioning.api.data.SecurityQuestionDataBinder; @@ -134,7 +133,6 @@ import org.apache.syncope.core.provisioning.java.data.ResourceDataBinderImpl; import org.apache.syncope.core.provisioning.java.data.RoleDataBinderImpl; import org.apache.syncope.core.provisioning.java.data.SAML2IdPEntityDataBinderImpl; -import org.apache.syncope.core.provisioning.java.data.SAML2SPEntityDataBinderImpl; import org.apache.syncope.core.provisioning.java.data.SRARouteDataBinderImpl; import org.apache.syncope.core.provisioning.java.data.SchemaDataBinderImpl; import org.apache.syncope.core.provisioning.java.data.SecurityQuestionDataBinderImpl; @@ -1010,12 +1008,6 @@ public SAML2IdPEntityDataBinder saml2IdPEntityDataBinder(final EntityFactory ent return new SAML2IdPEntityDataBinderImpl(entityFactory); } - @ConditionalOnMissingBean - @Bean - public SAML2SPEntityDataBinder saml2SPEntityDataBinder(final EntityFactory entityFactory) { - return new SAML2SPEntityDataBinderImpl(entityFactory); - } - @ConditionalOnMissingBean @Bean public SRARouteDataBinder sraRouteDataBinder() { diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java index 3f2dc2c94db..a83fb9fcdc9 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java @@ -206,7 +206,6 @@ public ExternalResource update(final ExternalResource resource, final ResourceTO }); populateMapping( - resource, provisionTO.getMapping(), mapping, anyType.getKind(), @@ -363,7 +362,6 @@ public ExternalResource update(final ExternalResource resource, final ResourceTO } protected void populateMapping( - final ExternalResource resource, final Mapping mappingTO, final Mapping mapping, final AnyTypeKind anyTypeKind, diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2SPEntityDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2SPEntityDataBinderImpl.java deleted file mode 100644 index 2ea41ee719e..00000000000 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2SPEntityDataBinderImpl.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.provisioning.java.data; - -import java.util.Base64; -import org.apache.syncope.common.lib.to.SAML2SPEntityTO; -import org.apache.syncope.core.persistence.api.entity.EntityFactory; -import org.apache.syncope.core.persistence.api.entity.am.SAML2SPEntity; -import org.apache.syncope.core.provisioning.api.data.SAML2SPEntityDataBinder; - -public class SAML2SPEntityDataBinderImpl implements SAML2SPEntityDataBinder { - - protected final EntityFactory entityFactory; - - public SAML2SPEntityDataBinderImpl(final EntityFactory entityFactory) { - this.entityFactory = entityFactory; - } - - @Override - public SAML2SPEntity create(final SAML2SPEntityTO entityTO) { - SAML2SPEntity entity = entityFactory.newEntity(SAML2SPEntity.class); - entity.setKey(entityTO.getKey()); - return update(entity, entityTO); - } - - @Override - public SAML2SPEntity update(final SAML2SPEntity entity, final SAML2SPEntityTO entityTO) { - entity.setKeystore(entityTO.getKeystore() == null - ? null - : Base64.getDecoder().decode(entityTO.getKeystore())); - entity.setMetadata(entityTO.getMetadata() == null - ? null - : Base64.getDecoder().decode(entityTO.getMetadata())); - return entity; - } - - @Override - public SAML2SPEntityTO getSAML2SPEntityTO(final SAML2SPEntity entity) { - SAML2SPEntityTO entityTO = new SAML2SPEntityTO(); - entityTO.setKey(entity.getKey()); - if (entity.getKeystore() != null) { - entityTO.setKeystore(Base64.getEncoder().encodeToString(entity.getKeystore())); - } - if (entity.getMetadata() != null) { - entityTO.setMetadata(Base64.getEncoder().encodeToString(entity.getMetadata())); - } - return entityTO; - } -} diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java index 24421002ba0..10d0e9d44bd 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java @@ -226,7 +226,6 @@ protected void doHandle(final LinkedAccount account, final Provision provision) profile.getConnector(), connObjectKeyItem, account.getConnObjectKeyValue(), - profile.getTask().getResource(), provision, Optional.empty())); LOG.debug("Match found for linked account {} as {}: {}", account, provision.getObjectClass(), connObj); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java index 038df153f03..c0020ea25e3 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java @@ -134,7 +134,6 @@ public List match( result.addAll(matchByCorrelationRule( connector, rule.get().getFilter(any, taskInfo.getResource(), provision), - taskInfo.getResource(), provision, Optional.of(moreAttrsToGet.toArray(String[]::new)))); } else { @@ -142,7 +141,6 @@ public List match( connector, connObjectKeyItem, connObjectKeyValue, - taskInfo.getResource(), provision, Optional.of(moreAttrsToGet.toArray(String[]::new)))).ifPresent(result::add); } @@ -192,7 +190,6 @@ public List match( result.addAll(matchByCorrelationRule( connector, rule.get().getFilter(any, resource, provision), - resource, provision, effectiveMATG)); } else { @@ -204,7 +201,6 @@ public List match( connector, connObjectKeyItem.get(), connObjectKeyValue.get(), - resource, provision, effectiveMATG). ifPresent(result::add); @@ -220,7 +216,6 @@ public List match( protected List matchByCorrelationRule( final Connector connector, final Filter filter, - final ExternalResource resource, final Provision provision, final Optional moreAttrsToGet) { @@ -255,7 +250,6 @@ public Optional matchByConnObjectKeyValue( final Connector connector, final Item connObjectKeyItem, final String connObjectKeyValue, - final ExternalResource resource, final Provision provision, final Optional moreAttrsToGet) { diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java index 230656a3fdb..5813a6d0dc4 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java @@ -154,7 +154,6 @@ import org.apache.syncope.common.rest.api.service.SAML2IdPEntityService; import org.apache.syncope.common.rest.api.service.SAML2SP4UIIdPService; import org.apache.syncope.common.rest.api.service.SAML2SP4UIService; -import org.apache.syncope.common.rest.api.service.SAML2SPEntityService; import org.apache.syncope.common.rest.api.service.SCIMConfService; import org.apache.syncope.common.rest.api.service.SRARouteService; import org.apache.syncope.common.rest.api.service.SchemaService; @@ -378,8 +377,6 @@ public void initialize(final ConfigurableApplicationContext ctx) { protected static AuthProfileService AUTH_PROFILE_SERVICE; - protected static SAML2SPEntityService SAML2SP_ENTITY_SERVICE; - protected static SAML2IdPEntityService SAML2IDP_ENTITY_SERVICE; protected static OIDCJWKSService OIDC_JWKS_SERVICE; @@ -577,7 +574,6 @@ public static void restSetup() { CLIENT_APP_SERVICE = ADMIN_CLIENT.getService(ClientAppService.class); AUTH_MODULE_SERVICE = ADMIN_CLIENT.getService(AuthModuleService.class); ATTR_REPO_SERVICE = ADMIN_CLIENT.getService(AttrRepoService.class); - SAML2SP_ENTITY_SERVICE = ADMIN_CLIENT.getService(SAML2SPEntityService.class); SAML2IDP_ENTITY_SERVICE = ADMIN_CLIENT.getService(SAML2IdPEntityService.class); AUTH_PROFILE_SERVICE = ADMIN_CLIENT.getService(AuthProfileService.class); OIDC_JWKS_SERVICE = ADMIN_CLIENT.getService(OIDCJWKSService.class); diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthModuleITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthModuleITCase.java index 49f115008d7..2b79628be54 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthModuleITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthModuleITCase.java @@ -26,6 +26,7 @@ import jakarta.ws.rs.core.Response; import java.io.IOException; +import java.util.Base64; import java.util.EnumSet; import java.util.List; import java.util.Map; @@ -414,9 +415,11 @@ public void updateSAML2IdPAuthModule() { newsaml2IdpAuthModuleTO = createAuthModule(newsaml2IdpAuthModuleTO); assertNotNull(newsaml2IdpAuthModuleTO); - AuthModuleConf conf = saml2IdpAuthModuleTO.getConf(); + SAML2IdPAuthModuleConf conf = (SAML2IdPAuthModuleConf) saml2IdpAuthModuleTO.getConf(); assertNotNull(conf); - SAML2IdPAuthModuleConf.class.cast(conf).setServiceProviderEntityId("newEntityId"); + conf.setClientName("clientName"); + conf.setServiceProviderEntityId("newEntityId"); + conf.setServiceProviderMetadata(Base64.getEncoder().encodeToString("testMetadata".getBytes())); newsaml2IdpAuthModuleTO.setConf(conf); // update new auth module @@ -424,8 +427,10 @@ public void updateSAML2IdPAuthModule() { newsaml2IdpAuthModuleTO = AUTH_MODULE_SERVICE.read(newsaml2IdpAuthModuleTO.getKey()); assertNotNull(newsaml2IdpAuthModuleTO); - conf = newsaml2IdpAuthModuleTO.getConf(); - assertEquals("newEntityId", SAML2IdPAuthModuleConf.class.cast(conf).getServiceProviderEntityId()); + conf = (SAML2IdPAuthModuleConf) newsaml2IdpAuthModuleTO.getConf(); + assertEquals("clientName", conf.getClientName()); + assertEquals("newEntityId", conf.getServiceProviderEntityId()); + assertEquals("testMetadata", new String(Base64.getDecoder().decode(conf.getServiceProviderMetadata()))); } @Test diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2SPEntityITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2SPEntityITCase.java deleted file mode 100644 index 26fd91ba8c6..00000000000 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2SPEntityITCase.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.fit.core; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assumptions.assumeTrue; - -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import org.apache.syncope.client.lib.SyncopeClientFactoryBean; -import org.apache.syncope.common.lib.SyncopeClientException; -import org.apache.syncope.common.lib.to.SAML2SPEntityTO; -import org.apache.syncope.common.rest.api.service.SAML2SPEntityService; -import org.apache.syncope.fit.AbstractITCase; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -public class SAML2SPEntityITCase extends AbstractITCase { - - private static final String OWNER = "owner"; - - private static SAML2SPEntityService WA_SAML2SP_ENTITY_SERVICE; - - @BeforeAll - public static void setup() { - assumeTrue(CLIENT_FACTORY.getContentType() == SyncopeClientFactoryBean.ContentType.JSON); - - WA_SAML2SP_ENTITY_SERVICE = ANONYMOUS_CLIENT.getService(SAML2SPEntityService.class); - } - - private static SAML2SPEntityTO set() { - SAML2SPEntityTO entityTO = new SAML2SPEntityTO.Builder(). - key(OWNER). - metadata(Base64.getEncoder().encodeToString("testMetadata".getBytes(StandardCharsets.UTF_8))). - build(); - WA_SAML2SP_ENTITY_SERVICE.set(entityTO); - - return entityTO; - } - - @Test - public void get() { - SAML2SPEntityTO entityTO; - try { - entityTO = WA_SAML2SP_ENTITY_SERVICE.get(OWNER); - } catch (SyncopeClientException e) { - entityTO = set(); - } - assertNotNull(entityTO); - - assertEquals(OWNER, entityTO.getKey()); - } - - @Test - public void getAndSet() { - SAML2SPEntityTO entityTO; - try { - entityTO = WA_SAML2SP_ENTITY_SERVICE.get(OWNER); - } catch (SyncopeClientException e) { - entityTO = set(); - } - assertNotNull(entityTO); - - entityTO.setMetadata(Base64.getEncoder().encodeToString("new metadata".getBytes(StandardCharsets.UTF_8))); - WA_SAML2SP_ENTITY_SERVICE.set(entityTO); - - entityTO = WA_SAML2SP_ENTITY_SERVICE.get(entityTO.getKey()); - assertEquals( - "new metadata", - new String(Base64.getDecoder().decode(entityTO.getMetadata()), StandardCharsets.UTF_8)); - } -} diff --git a/pom.xml b/pom.xml index bca507383b4..b8024c5c6a9 100644 --- a/pom.xml +++ b/pom.xml @@ -1812,7 +1812,7 @@ under the License. us.hebi.sass sass-cli-maven-plugin - 1.0.3 + 1.0.4 1.62.0 ${sass.skip} diff --git a/wa/bootstrap/src/main/java/org/apache/syncope/wa/bootstrap/mapping/AuthModulePropertySourceMapper.java b/wa/bootstrap/src/main/java/org/apache/syncope/wa/bootstrap/mapping/AuthModulePropertySourceMapper.java index a659e47d545..0add168ac65 100644 --- a/wa/bootstrap/src/main/java/org/apache/syncope/wa/bootstrap/mapping/AuthModulePropertySourceMapper.java +++ b/wa/bootstrap/src/main/java/org/apache/syncope/wa/bootstrap/mapping/AuthModulePropertySourceMapper.java @@ -288,8 +288,6 @@ public Map map(final AuthModuleTO authModuleTO, final SAML2IdPAu props.setBlockedSignatureSigningAlgorithms(conf.getBlockedSignatureSigningAlgorithms()); props.setDestinationBinding(conf.getDestinationBinding().getUri()); props.getMetadata().setIdentityProviderMetadataPath(conf.getIdentityProviderMetadataPath()); - props.getMetadata().getServiceProvider().getFileSystem().setLocation(conf.getServiceProviderMetadataPath()); - props.setKeystorePath(conf.getKeystorePath()); props.setWantsAssertionsSigned(conf.isWantsAssertionsSigned()); props.setWantsResponsesSigned(conf.isResponsesSigned()); props.setKeystorePassword(conf.getKeystorePassword()); @@ -302,9 +300,9 @@ public Map map(final AuthModuleTO authModuleTO, final SAML2IdPAu props.setSignatureCanonicalizationAlgorithm(conf.getSignatureCanonicalizationAlgorithm()); props.setSignatureReferenceDigestMethods(conf.getSignatureReferenceDigestMethods()); props.setPrincipalIdAttribute(conf.getUserIdAttribute()); - props.setNameIdPolicyAllowCreate(StringUtils.isBlank(conf.getNameIdPolicyAllowCreate()) - ? TriStateBoolean.UNDEFINED - : TriStateBoolean.valueOf(conf.getNameIdPolicyAllowCreate().toUpperCase())); + props.setNameIdPolicyAllowCreate(Optional.ofNullable(conf.getNameIdPolicyAllowCreate()). + map(v -> TriStateBoolean.valueOf(v.name())). + orElse(TriStateBoolean.UNDEFINED)); return prefix("cas.authn.pac4j.saml[].", WAConfUtils.asMap(props)); } diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientKeystoreGenerator.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientKeystoreGenerator.java index a02327dab0b..ec328b6a21b 100644 --- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientKeystoreGenerator.java +++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientKeystoreGenerator.java @@ -18,15 +18,17 @@ */ package org.apache.syncope.wa.starter.pac4j.saml; +import jakarta.ws.rs.core.Response; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.security.KeyStore; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.util.Base64; -import org.apache.syncope.common.lib.to.SAML2SPEntityTO; -import org.apache.syncope.common.rest.api.service.SAML2SPEntityService; +import org.apache.commons.io.IOUtils; +import org.apache.syncope.common.rest.api.service.wa.WASAML2SPService; import org.apache.syncope.wa.bootstrap.WARestClient; import org.pac4j.saml.client.SAML2Client; import org.pac4j.saml.metadata.keystore.BaseSAML2KeystoreGenerator; @@ -50,8 +52,9 @@ public WASAML2ClientKeystoreGenerator(final WARestClient waRestClient, final SAM @Override public boolean shouldGenerate() { try { - SAML2SPEntityTO spEntity = waRestClient.getService(SAML2SPEntityService.class).get(saml2Client.getName()); - return spEntity.getKeystore() == null; + Response response = waRestClient.getService(WASAML2SPService.class). + getSAML2SPKeystore(saml2Client.getName()); + return response.getStatus() == Response.Status.NOT_FOUND.getStatusCode() || !response.hasEntity(); } catch (Exception e) { LOG.error("While attempting to read if keystore is available for SP Entity {}", saml2Client.getName(), e); return true; @@ -71,27 +74,18 @@ protected void store(final KeyStore ks, final X509Certificate certificate, final LOG.debug("Encoded keystore {}", encodedKeystore); } - SAML2SPEntityTO entityTO; - try { - entityTO = waRestClient.getService(SAML2SPEntityService.class).get(saml2Client.getName()); - entityTO.setKeystore(encodedKeystore); - } catch (Exception e) { - LOG.debug("SP Entity {} keystore not found, creating new", saml2Client.getName(), e); - - entityTO = new SAML2SPEntityTO.Builder().key(saml2Client.getName()).keystore(encodedKeystore).build(); - } - - LOG.debug("Storing SP Entity {}", entityTO); - waRestClient.getService(SAML2SPEntityService.class).set(entityTO); + waRestClient.getService(WASAML2SPService.class).setSAML2SPKeystore( + saml2Client.getName(), IOUtils.toInputStream(encodedKeystore, StandardCharsets.UTF_8)); } @Override public InputStream retrieve() throws Exception { try { - SAML2SPEntityTO spEntity = waRestClient.getService(SAML2SPEntityService.class).get(saml2Client.getName()); + String encodedKeystore = waRestClient.getService(WASAML2SPService.class). + getSAML2SPKeystore(saml2Client.getName()).readEntity(String.class); - LOG.debug("Retrieved keystore {}", spEntity.getKeystore()); - return new ByteArrayInputStream(Base64.getDecoder().decode(spEntity.getKeystore())); + LOG.debug("Retrieved keystore {}", encodedKeystore); + return new ByteArrayInputStream(Base64.getDecoder().decode(encodedKeystore)); } catch (Exception e) { String message = "Unable to fetch SAML2 SP keystore for " + saml2Client.getName(); LOG.error(message, e); diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientMetadataGenerator.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientMetadataGenerator.java index 89b1e3f605b..9f90207dcaf 100644 --- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientMetadataGenerator.java +++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientMetadataGenerator.java @@ -20,8 +20,8 @@ import java.nio.charset.StandardCharsets; import java.util.Base64; -import org.apache.syncope.common.lib.to.SAML2SPEntityTO; -import org.apache.syncope.common.rest.api.service.SAML2SPEntityService; +import org.apache.commons.io.IOUtils; +import org.apache.syncope.common.rest.api.service.wa.WASAML2SPService; import org.apache.syncope.wa.bootstrap.WARestClient; import org.opensaml.saml.metadata.resolver.MetadataResolver; import org.opensaml.saml.metadata.resolver.impl.AbstractMetadataResolver; @@ -57,23 +57,15 @@ protected AbstractMetadataResolver createMetadataResolver() { public MetadataResolver buildMetadataResolver() throws Exception { String encodedMetadata = Base64.getEncoder().encodeToString( getMetadata(buildEntityDescriptor()).getBytes(StandardCharsets.UTF_8)); + LOG.debug("Encoded SP metadata {}", encodedMetadata); - SAML2SPEntityTO entityTO; try { - entityTO = waRestClient.getService(SAML2SPEntityService.class).get(saml2Client.getName()); - entityTO.setMetadata(encodedMetadata); + waRestClient.getService(WASAML2SPService.class).setSAML2SPMetadata( + saml2Client.getName(), IOUtils.toInputStream(encodedMetadata, StandardCharsets.UTF_8)); } catch (Exception e) { - LOG.debug("SP Entity {} not found, creating new", saml2Client.getName(), e); - - entityTO = new SAML2SPEntityTO.Builder(). - key(saml2Client.getName()). - metadata(encodedMetadata). - build(); + LOG.error("While storing SP {} metadata", saml2Client.getName(), e); } - LOG.debug("Storing SP Entity {}", entityTO); - waRestClient.getService(SAML2SPEntityService.class).set(entityTO); - return super.buildMetadataResolver(); } } diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2MetadataResolver.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2MetadataResolver.java index 4bbddf064ed..1788e31baf9 100644 --- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2MetadataResolver.java +++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2MetadataResolver.java @@ -20,8 +20,7 @@ import java.util.Base64; import net.shibboleth.shared.resolver.ResolverException; -import org.apache.syncope.common.lib.to.SAML2SPEntityTO; -import org.apache.syncope.common.rest.api.service.SAML2SPEntityService; +import org.apache.syncope.common.rest.api.service.wa.WASAML2SPService; import org.apache.syncope.wa.bootstrap.WARestClient; import org.opensaml.saml.metadata.resolver.impl.AbstractReloadingMetadataResolver; import org.pac4j.saml.client.SAML2Client; @@ -49,8 +48,11 @@ protected String getMetadataIdentifier() { @Override protected byte[] fetchMetadata() throws ResolverException { try { - SAML2SPEntityTO metadataTO = waRestClient.getService(SAML2SPEntityService.class).get(saml2Client.getName()); - return Base64.getDecoder().decode(metadataTO.getMetadata()); + String encodedMetadata = waRestClient.getService(WASAML2SPService.class). + getSAML2SPMetadata(saml2Client.getName()).readEntity(String.class); + + LOG.debug("Retrieved keystore {}", encodedMetadata); + return Base64.getDecoder().decode(encodedMetadata); } catch (Exception e) { String message = "Unable to fetch SP metadata for " + saml2Client.getName(); LOG.error(message, e); diff --git a/wa/starter/src/test/java/org/apache/syncope/wa/starter/SyncopeCoreTestingServer.java b/wa/starter/src/test/java/org/apache/syncope/wa/starter/SyncopeCoreTestingServer.java index 96a20e9dee0..929d15f9206 100644 --- a/wa/starter/src/test/java/org/apache/syncope/wa/starter/SyncopeCoreTestingServer.java +++ b/wa/starter/src/test/java/org/apache/syncope/wa/starter/SyncopeCoreTestingServer.java @@ -72,7 +72,7 @@ protected static class StubAuthModuleService implements AuthModuleService { @Override public AuthModuleTO read(final String key) { return AUTH_MODULES.stream().filter(m -> Objects.equals(key, m.getKey())). - findFirst().orElseThrow(() -> new NotFoundException("Auth Module with key " + key)); + findFirst().orElseThrow(() -> new NotFoundException("AuthModule with key " + key)); } @Override diff --git a/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/BaseWASAML2ClientTest.java b/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/BaseWASAML2ClientTest.java index 8630fde9378..8ed84ab1308 100644 --- a/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/BaseWASAML2ClientTest.java +++ b/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/BaseWASAML2ClientTest.java @@ -18,10 +18,20 @@ */ package org.apache.syncope.wa.starter.pac4j.saml; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import jakarta.ws.rs.core.Response; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.IOException; +import java.io.InputStream; import java.math.BigInteger; +import java.nio.charset.StandardCharsets; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; @@ -30,6 +40,9 @@ import java.security.cert.CertificateFactory; import java.util.Base64; import java.util.Date; +import org.apache.commons.io.IOUtils; +import org.apache.syncope.common.rest.api.service.wa.WASAML2SPService; +import org.apache.syncope.wa.bootstrap.WARestClient; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Integer; @@ -99,6 +112,7 @@ protected static SAML2Client getSAML2Client() throws Exception { cfg.setServiceProviderMetadataResource(new FileSystemResource(File.createTempFile("sp-metadata", ".xml"))); SAML2Client client = new SAML2Client(cfg); + client.setName("CAS"); client.setCallbackUrl("https://syncope.apache.org"); return client; } @@ -123,4 +137,22 @@ protected static String getKeystoreAsString() throws Exception { return Base64.getEncoder().encodeToString(fos.toByteArray()); } } + + protected static String getSPMetadata() throws IOException { + return Base64.getEncoder().encodeToString( + IOUtils.toString(new ClassPathResource("sp-metadata.xml").getInputStream(), StandardCharsets.UTF_8). + getBytes(StandardCharsets.UTF_8)); + } + + protected static WARestClient getWARestClient() throws Exception { + WASAML2SPService service = mock(WASAML2SPService.class); + when(service.getSAML2SPKeystore(anyString())).thenReturn(Response.ok(getKeystoreAsString()).build()); + when(service.getSAML2SPMetadata(anyString())).thenReturn(Response.ok(getSPMetadata()).build()); + doNothing().when(service).setSAML2SPKeystore(anyString(), any(InputStream.class)); + doNothing().when(service).setSAML2SPMetadata(anyString(), any(InputStream.class)); + + WARestClient waRestClient = mock(WARestClient.class); + when(waRestClient.getService(WASAML2SPService.class)).thenReturn(service); + return waRestClient; + } } diff --git a/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientCustomizerTest.java b/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientCustomizerTest.java index 94b4db15525..406452871e1 100644 --- a/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientCustomizerTest.java +++ b/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientCustomizerTest.java @@ -19,39 +19,15 @@ package org.apache.syncope.wa.starter.pac4j.saml; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import java.nio.charset.StandardCharsets; -import org.apache.commons.io.IOUtils; -import org.apache.syncope.common.lib.to.SAML2SPEntityTO; -import org.apache.syncope.common.rest.api.service.SAML2SPEntityService; -import org.apache.syncope.wa.bootstrap.WARestClient; import org.junit.jupiter.api.Test; import org.pac4j.saml.client.SAML2Client; -import org.springframework.core.io.ClassPathResource; public class WASAML2ClientCustomizerTest extends BaseWASAML2ClientTest { @Test public void customize() throws Exception { - SAML2SPEntityTO entityTO = new SAML2SPEntityTO.Builder() - .key("CAS") - .keystore(getKeystoreAsString()) - .metadata(IOUtils.toString(new ClassPathResource("sp-metadata.xml").getInputStream(), - StandardCharsets.UTF_8)) - .build(); - SAML2SPEntityService service = mock(SAML2SPEntityService.class); - when(service.get(anyString())).thenReturn(entityTO); - doNothing().when(service).set(any(SAML2SPEntityTO.class)); - - WARestClient waRestClient = mock(WARestClient.class); - when(waRestClient.getService(SAML2SPEntityService.class)).thenReturn(service); - - WASAML2ClientCustomizer customizer = new WASAML2ClientCustomizer(waRestClient); + WASAML2ClientCustomizer customizer = new WASAML2ClientCustomizer(getWARestClient()); SAML2Client client = getSAML2Client(); customizer.customize(client); client.init(); diff --git a/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientKeystoreGeneratorTest.java b/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientKeystoreGeneratorTest.java index 43457616b83..99e5686e0b7 100644 --- a/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientKeystoreGeneratorTest.java +++ b/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientKeystoreGeneratorTest.java @@ -19,44 +19,15 @@ package org.apache.syncope.wa.starter.pac4j.saml; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import java.nio.charset.StandardCharsets; -import org.apache.commons.io.IOUtils; -import org.apache.syncope.common.lib.to.SAML2SPEntityTO; -import org.apache.syncope.common.rest.api.service.SAML2SPEntityService; -import org.apache.syncope.wa.bootstrap.WARestClient; import org.junit.jupiter.api.Test; -import org.pac4j.saml.client.SAML2Client; import org.pac4j.saml.metadata.keystore.SAML2KeystoreGenerator; -import org.springframework.core.io.ClassPathResource; public class WASAML2ClientKeystoreGeneratorTest extends BaseWASAML2ClientTest { - private static WARestClient getWaRestClient() throws Exception { - SAML2SPEntityTO keystoreTO = new SAML2SPEntityTO.Builder() - .key("CAS") - .keystore(getKeystoreAsString()) - .metadata(IOUtils.toString(new ClassPathResource("sp-metadata.xml").getInputStream(), - StandardCharsets.UTF_8)) - .build(); - SAML2SPEntityService service = mock(SAML2SPEntityService.class); - when(service.get(anyString())).thenReturn(keystoreTO); - doNothing().when(service).set(any(SAML2SPEntityTO.class)); - - WARestClient waRestClient = mock(WARestClient.class); - when(waRestClient.getService(SAML2SPEntityService.class)).thenReturn(service); - return waRestClient; - } - @Test public void generate() throws Exception { - SAML2Client client = getSAML2Client(); - SAML2KeystoreGenerator generator = new WASAML2ClientKeystoreGenerator(getWaRestClient(), client); + SAML2KeystoreGenerator generator = new WASAML2ClientKeystoreGenerator(getWARestClient(), getSAML2Client()); assertDoesNotThrow(generator::generate); } } diff --git a/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientMetadataGeneratorTest.java b/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientMetadataGeneratorTest.java index 5683c097078..d5449e96a89 100644 --- a/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientMetadataGeneratorTest.java +++ b/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientMetadataGeneratorTest.java @@ -19,50 +19,22 @@ package org.apache.syncope.wa.starter.pac4j.saml; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import org.apache.commons.io.IOUtils; -import org.apache.syncope.common.lib.to.SAML2SPEntityTO; -import org.apache.syncope.common.rest.api.service.SAML2SPEntityService; -import org.apache.syncope.wa.bootstrap.WARestClient; import org.junit.jupiter.api.Test; import org.opensaml.saml.saml2.metadata.EntityDescriptor; import org.pac4j.saml.client.SAML2Client; import org.pac4j.saml.metadata.SAML2MetadataGenerator; -import org.springframework.core.io.ClassPathResource; public class WASAML2ClientMetadataGeneratorTest extends BaseWASAML2ClientTest { - private static WARestClient getWaRestClient() throws IOException { - SAML2SPEntityTO metadataTO = new SAML2SPEntityTO.Builder() - .key("Syncope") - .metadata(IOUtils.toString(new ClassPathResource("sp-metadata.xml").getInputStream(), - StandardCharsets.UTF_8)) - .build(); - - SAML2SPEntityService saml2SPMetadataService = mock(SAML2SPEntityService.class); - when(saml2SPMetadataService.get(anyString())).thenReturn(metadataTO); - doNothing().when(saml2SPMetadataService).set(any(SAML2SPEntityTO.class)); - - WARestClient waRestClient = mock(WARestClient.class); - when(waRestClient.getService(SAML2SPEntityService.class)).thenReturn(saml2SPMetadataService); - return waRestClient; - } - @Test public void storeMetadata() throws Exception { SAML2Client client = getSAML2Client(); String keystoreFile = File.createTempFile("keystore", "jks").getCanonicalPath(); client.getConfiguration().setKeystoreResourceFilepath(keystoreFile); - SAML2MetadataGenerator generator = new WASAML2ClientMetadataGenerator(getWaRestClient(), client); + SAML2MetadataGenerator generator = new WASAML2ClientMetadataGenerator(getWARestClient(), client); EntityDescriptor entityDescriptor = generator.buildEntityDescriptor(); String metadata = generator.getMetadata(entityDescriptor); assertNotNull(generator.storeMetadata(metadata, false)); diff --git a/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2MetadataResolverTest.java b/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2MetadataResolverTest.java index c30758eceaa..60d4e652bcc 100644 --- a/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2MetadataResolverTest.java +++ b/wa/starter/src/test/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2MetadataResolverTest.java @@ -19,21 +19,10 @@ package org.apache.syncope.wa.starter.pac4j.saml; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; import java.io.File; -import java.util.Base64; -import org.apache.commons.io.IOUtils; -import org.apache.syncope.common.lib.to.SAML2SPEntityTO; -import org.apache.syncope.common.rest.api.service.SAML2SPEntityService; -import org.apache.syncope.wa.bootstrap.WARestClient; import org.junit.jupiter.api.Test; import org.pac4j.saml.client.SAML2Client; -import org.springframework.core.io.ClassPathResource; public class WASAML2MetadataResolverTest extends BaseWASAML2ClientTest { @@ -43,20 +32,7 @@ public void fetchMetadata() throws Exception { String keystoreFile = File.createTempFile("keystore", "jks").getCanonicalPath(); client.getConfiguration().setKeystoreResourceFilepath(keystoreFile); - SAML2SPEntityTO metadataTO = new SAML2SPEntityTO.Builder() - .key("Syncope") - .metadata(Base64.getEncoder().encodeToString( - IOUtils.toByteArray(new ClassPathResource("sp-metadata.xml").getInputStream()))) - .build(); - - SAML2SPEntityService saml2SPMetadataService = mock(SAML2SPEntityService.class); - when(saml2SPMetadataService.get(anyString())).thenReturn(metadataTO); - doNothing().when(saml2SPMetadataService).set(any(SAML2SPEntityTO.class)); - - WARestClient waRestClient = mock(WARestClient.class); - when(waRestClient.getService(SAML2SPEntityService.class)).thenReturn(saml2SPMetadataService); - - WASAML2MetadataResolver resolver = new WASAML2MetadataResolver(waRestClient, client); + WASAML2MetadataResolver resolver = new WASAML2MetadataResolver(getWARestClient(), client); assertNotNull(resolver.fetchMetadata()); } } From 12a070e0d45916d960c14cc54b5fbfbc78d35b61 Mon Sep 17 00:00:00 2001 From: Andrea Patricelli Date: Fri, 9 May 2025 16:43:38 +0200 Subject: [PATCH 039/579] code alignment for reference groovy implementations in console --- .../client/console/implementations/MyAccountRule.groovy | 2 +- .../console/implementations/MyAttrValueValidator.groovy | 8 ++------ .../client/console/implementations/MyMacroActions.groovy | 2 +- .../client/console/implementations/MyPasswordRule.groovy | 2 +- .../console/implementations/MyPropagationActions.groovy | 4 ++-- 5 files changed, 7 insertions(+), 11 deletions(-) diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyAccountRule.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyAccountRule.groovy index 1826559aa4d..6768799e632 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyAccountRule.groovy +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyAccountRule.groovy @@ -17,7 +17,7 @@ * under the License. */ import groovy.transform.CompileStatic -import org.apache.syncope.core.persistence.api.dao.AccountRule +import org.apache.syncope.core.provisioning.api.rules.AccountRule import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount import org.apache.syncope.core.persistence.api.entity.user.User diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyAttrValueValidator.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyAttrValueValidator.groovy index 9e9a79dc089..7998e986af4 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyAttrValueValidator.groovy +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyAttrValueValidator.groovy @@ -17,7 +17,7 @@ * under the License. */ import groovy.transform.CompileStatic -import org.apache.syncope.core.persistence.api.attrvalue.validation.PlainAttrValueValidator +import org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValueValidator import org.apache.syncope.core.persistence.api.entity.PlainAttrValue import org.apache.syncope.core.persistence.api.entity.PlainSchema @@ -25,10 +25,6 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema class MyAttrValueValidator implements PlainAttrValueValidator { @Override - void setSchema(PlainSchema schema) { - } - - @Override - void validate(String value, PlainAttrValue attrValue) { + void validate(PlainSchema schema, String value, PlainAttrValue attrValue) { } } diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyMacroActions.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyMacroActions.groovy index 354fa91ea21..1edd24358a6 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyMacroActions.groovy +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyMacroActions.groovy @@ -19,7 +19,7 @@ import groovy.transform.CompileStatic import java.util.Map import java.util.Optional -import javax.validation.ValidationException +import jakarta.validation.ValidationException import org.apache.syncope.common.lib.command.CommandArgs import org.apache.syncope.common.lib.form.SyncopeForm import org.apache.syncope.core.provisioning.api.macro.Command diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPasswordRule.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPasswordRule.groovy index a54f8ceb3c6..a73034060d7 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPasswordRule.groovy +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPasswordRule.groovy @@ -17,7 +17,7 @@ * under the License. */ import groovy.transform.CompileStatic -import org.apache.syncope.core.persistence.api.dao.PasswordRule +import org.apache.syncope.core.provisioning.api.rules.PasswordRule import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount import org.apache.syncope.core.persistence.api.entity.user.User diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPropagationActions.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPropagationActions.groovy index 9ad62814fed..0e170bfc709 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPropagationActions.groovy +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPropagationActions.groovy @@ -30,12 +30,12 @@ import org.identityconnectors.framework.common.objects.ConnectorObject class MyPropagationActions implements PropagationActions { @Override - Set moreAttrsToGet(Optional task, OrgUnit orgUnit) { + Set moreAttrsToGet(Optional taskInfo, OrgUnit orgUnit) { return Set.of(); } @Override - Set moreAttrsToGet(Optional task, Provision provision) { + Set moreAttrsToGet(Optional taskInfo, Provision provision){ return Set.of(); } From 51c82b570e2bd8365fdb57e654cd35725e2acdf9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 May 2025 22:51:18 +0000 Subject: [PATCH 040/579] Bump com.nimbusds:nimbus-jose-jwt from 10.2 to 10.3 Bumps [com.nimbusds:nimbus-jose-jwt](https://bitbucket.org/connect2id/nimbus-jose-jwt) from 10.2 to 10.3. - [Changelog](https://bitbucket.org/connect2id/nimbus-jose-jwt/src/master/CHANGELOG.txt) - [Commits](https://bitbucket.org/connect2id/nimbus-jose-jwt/branches/compare/10.3..10.2) --- updated-dependencies: - dependency-name: com.nimbusds:nimbus-jose-jwt dependency-version: '10.3' dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b8024c5c6a9..57d0ec38883 100644 --- a/pom.xml +++ b/pom.xml @@ -413,7 +413,7 @@ under the License. 4.1.1 1.80 - 10.2 + 10.3 3.4.5 4.2.1 From 16b57dc37d4e97302975680c5a1dff9caa9725ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Mon, 12 May 2025 10:49:23 +0200 Subject: [PATCH 041/579] [SYNCOPE-1878] Priority propagation fails only when ExecStatus.FAILURE --- .../java/propagation/PriorityPropagationTaskExecutor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java index 7735e0ceaf8..a95a20d09c9 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java @@ -147,7 +147,7 @@ public PropagationReporter execute( execStatus = ExecStatus.FAILURE; errorMessage = e.getMessage(); } - if (execStatus != ExecStatus.SUCCESS) { + if (execStatus == ExecStatus.FAILURE) { throw new PropagationException( taskInfo.getResource().getKey(), Optional.ofNullable(exec).map(Exec::getMessage).orElse(errorMessage)); From 88878f986404a20666a646c59515e672b2a8f6ea Mon Sep 17 00:00:00 2001 From: Andrea Patricelli Date: Mon, 12 May 2025 14:34:40 +0200 Subject: [PATCH 042/579] [SYNCOPE-1879] managing ConnectorObjectIdentification serialization/deserialization (#1076) --- ...ectorObjectIdentificationDeserializer.java | 67 +++++++++++++++++++ ...nnectorObjectIdentificationSerializer.java | 54 +++++++++++++++ .../api/serialization/POJOHelper.java | 4 ++ ...nObjectIdentificationDeserializerTest.java | 43 ++++++++++++ ...onnObjectIdentificationSerializerTest.java | 58 ++++++++++++++++ 5 files changed, 226 insertions(+) create mode 100644 core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/ConnectorObjectIdentificationDeserializer.java create mode 100644 core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/ConnectorObjectIdentificationSerializer.java create mode 100644 core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/serialization/ConnObjectIdentificationDeserializerTest.java create mode 100644 core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/serialization/ConnObjectIdentificationSerializerTest.java diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/ConnectorObjectIdentificationDeserializer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/ConnectorObjectIdentificationDeserializer.java new file mode 100644 index 00000000000..ef086e569b8 --- /dev/null +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/ConnectorObjectIdentificationDeserializer.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.provisioning.api.serialization; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import java.io.IOException; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.identityconnectors.framework.common.objects.Attribute; +import org.identityconnectors.framework.common.objects.AttributeBuilder; +import org.identityconnectors.framework.common.objects.ConnectorObjectIdentification; +import org.identityconnectors.framework.common.objects.Name; +import org.identityconnectors.framework.common.objects.ObjectClass; +import org.identityconnectors.framework.common.objects.Uid; + +public class ConnectorObjectIdentificationDeserializer + extends AbstractValueDeserializer { + @Override + public ConnectorObjectIdentification deserialize(final JsonParser jp, + final DeserializationContext deserializationContext) throws IOException { + + ObjectNode tree = jp.readValueAsTree(); + + String objectClass = tree.get("objectClass").asText(); + + Set attributes = new HashSet<>(); + JsonNode attributesNode = tree.get("attributes"); + if (attributesNode != null && attributesNode.isArray()) { + attributesNode.forEach(attrNode -> { + try { + String name = attrNode.get("name").asText(); + List values = doDeserialize(attrNode.get("value"), jp); + attributes.add(Uid.NAME.equals(name) + ? new Uid(values.isEmpty() || values.getFirst() == null + ? null : values.getFirst().toString()) + : Name.NAME.equals(name) + ? new Name(values.isEmpty() || values.getFirst() == null + ? null : values.getFirst().toString()) + : AttributeBuilder.build(name, values)); + } catch (IOException e) { + } + }); + } + + return new ConnectorObjectIdentification(new ObjectClass(objectClass), attributes); + } +} diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/ConnectorObjectIdentificationSerializer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/ConnectorObjectIdentificationSerializer.java new file mode 100644 index 00000000000..088ab5304e4 --- /dev/null +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/ConnectorObjectIdentificationSerializer.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.provisioning.api.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import java.io.IOException; +import org.identityconnectors.framework.common.objects.ConnectorObjectIdentification; + +public class ConnectorObjectIdentificationSerializer extends AbstractValueSerializer { + + @Override + public void serialize(final ConnectorObjectIdentification value, final JsonGenerator jgen, + final SerializerProvider serializerProvider) throws IOException { + jgen.writeStartObject(); + + jgen.writeStringField("objectClass", value.getObjectClass().getObjectClassValue()); + + jgen.writeFieldName("attributes"); + + jgen.writeStartArray(); + value.getAttributes().forEach(attr -> { + try { + jgen.writeStartObject(); + + jgen.writeStringField("name", attr.getName()); + + jgen.writeFieldName("value"); + doSerialize(attr.getValue(), jgen); + jgen.writeEndObject(); + } catch (IOException e) { + } + }); + jgen.writeEndArray(); + + jgen.writeEndObject(); + } +} diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/POJOHelper.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/POJOHelper.java index ba65dffa00f..f152a61663e 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/POJOHelper.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/POJOHelper.java @@ -28,6 +28,7 @@ import org.identityconnectors.common.security.GuardedString; import org.identityconnectors.framework.common.objects.Attribute; import org.identityconnectors.framework.common.objects.AttributeDelta; +import org.identityconnectors.framework.common.objects.ConnectorObjectIdentification; import org.identityconnectors.framework.common.objects.SyncToken; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,11 +48,14 @@ public final class POJOHelper { pojoModule.addSerializer(Attribute.class, new AttributeSerializer()); pojoModule.addSerializer(AttributeDelta.class, new AttributeDeltaSerializer()); pojoModule.addSerializer(SyncToken.class, new SyncTokenSerializer()); + pojoModule.addSerializer(ConnectorObjectIdentification.class, new ConnectorObjectIdentificationSerializer()); pojoModule.addSerializer(PropagationTaskInfo.class, new PropagationTaskInfoSerializer()); pojoModule.addDeserializer(GuardedString.class, new GuardedStringDeserializer()); pojoModule.addDeserializer(Attribute.class, new AttributeDeserializer()); pojoModule.addDeserializer(AttributeDelta.class, new AttributeDeltaDeserializer()); pojoModule.addDeserializer(SyncToken.class, new SyncTokenDeserializer()); + pojoModule.addDeserializer(ConnectorObjectIdentification.class, + new ConnectorObjectIdentificationDeserializer()); MAPPER = JsonMapper.builder(). addModule(pojoModule). diff --git a/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/serialization/ConnObjectIdentificationDeserializerTest.java b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/serialization/ConnObjectIdentificationDeserializerTest.java new file mode 100644 index 00000000000..6dd867ce1e4 --- /dev/null +++ b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/serialization/ConnObjectIdentificationDeserializerTest.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.provisioning.api.serialization; + +import java.io.IOException; +import java.util.Set; +import org.apache.syncope.core.provisioning.api.AbstractTest; +import org.identityconnectors.framework.common.objects.AttributeBuilder; +import org.identityconnectors.framework.common.objects.ConnectorObjectIdentification; +import org.identityconnectors.framework.common.objects.ObjectClass; +import org.identityconnectors.framework.common.objects.Uid; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class ConnObjectIdentificationDeserializerTest extends AbstractTest { + + @Test + public void deserialize() throws IOException { + ConnectorObjectIdentification source = new ConnectorObjectIdentification(ObjectClass.ACCOUNT, + Set.of(AttributeBuilder.build(Uid.NAME, "someuid"))); + + ConnectorObjectIdentification deserialized = + POJOHelper.deserialize(POJOHelper.serialize(source), ConnectorObjectIdentification.class); + + Assertions.assertEquals(deserialized, deserialized.getIdentification()); + } +} diff --git a/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/serialization/ConnObjectIdentificationSerializerTest.java b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/serialization/ConnObjectIdentificationSerializerTest.java new file mode 100644 index 00000000000..fe4608bc930 --- /dev/null +++ b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/serialization/ConnObjectIdentificationSerializerTest.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.provisioning.api.serialization; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import java.io.IOException; +import java.util.Set; +import org.apache.syncope.core.provisioning.api.AbstractTest; +import org.identityconnectors.framework.common.objects.AttributeBuilder; +import org.identityconnectors.framework.common.objects.ConnectorObjectIdentification; +import org.identityconnectors.framework.common.objects.ObjectClass; +import org.identityconnectors.framework.common.objects.Uid; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; + +public class ConnObjectIdentificationSerializerTest extends AbstractTest { + + @Test + public void serialize( + final @Mock JsonGenerator jgen, + final @Mock SerializerProvider sp) + throws IOException { + ConnectorObjectIdentification source = new ConnectorObjectIdentification(ObjectClass.ACCOUNT, + Set.of(AttributeBuilder.build(Uid.NAME, "someuid"))); + + new ConnectorObjectIdentificationSerializer().serialize(source, jgen, sp); + verify(jgen, times(2)).writeStartObject(); + verify(jgen).writeStringField(eq("objectClass"), eq(ObjectClass.ACCOUNT.getObjectClassValue())); + verify(jgen).writeFieldName("attributes"); + verify(jgen).writeFieldName("value"); + verify(jgen).writeStringField(eq("name"), eq(Uid.NAME)); + verify(jgen, times(2)).writeStartArray(); + verify(jgen).writeString("someuid"); + verify(jgen, times(2)).writeEndArray(); + verify(jgen, times(2)).writeEndObject(); + } +} From 17dfdfcd0a0b12396690b1fb25298fe30c5533b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Tue, 13 May 2025 08:34:31 +0200 Subject: [PATCH 043/579] Upgrading Tomcat --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 57d0ec38883..2b39b6fd6ee 100644 --- a/pom.xml +++ b/pom.xml @@ -505,7 +505,7 @@ under the License. 9805 60000 - 10.1.40 + 10.1.41 36.0.0.Final 6.2025.4 4.1.3 From 69fa6b65b093b1f1eeba1c29dfe67f50e2191bcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Tue, 13 May 2025 10:49:59 +0200 Subject: [PATCH 044/579] [SYNCOPE-1878] Refactoring PriorityPropagationTaskExecutor --- .../propagation/PropagationTaskCallable.java | 32 ------- .../DefaultPropagationTaskCallable.java | 88 ------------------- .../PriorityPropagationTaskExecutor.java | 66 ++++++++------ 3 files changed, 41 insertions(+), 145 deletions(-) delete mode 100644 core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskCallable.java delete mode 100644 core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationTaskCallable.java diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskCallable.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskCallable.java deleted file mode 100644 index c7a1877714d..00000000000 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/propagation/PropagationTaskCallable.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.provisioning.api.propagation; - -import java.util.concurrent.Callable; -import org.apache.syncope.core.persistence.api.entity.task.PropagationTask; -import org.apache.syncope.core.persistence.api.entity.task.TaskExec; - -public interface PropagationTaskCallable extends Callable> { - - void setTaskInfo(PropagationTaskInfo taskInfo); - - void setReporter(PropagationReporter reporter); - - void setExecutor(String executor); -} diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationTaskCallable.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationTaskCallable.java deleted file mode 100644 index 8f92e03e68e..00000000000 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationTaskCallable.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.provisioning.java.propagation; - -import java.util.Collection; -import java.util.stream.Collectors; -import org.apache.syncope.core.persistence.api.entity.task.PropagationTask; -import org.apache.syncope.core.persistence.api.entity.task.TaskExec; -import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter; -import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskCallable; -import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor; -import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskInfo; -import org.apache.syncope.core.spring.security.AuthContextUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; - -public class DefaultPropagationTaskCallable implements PropagationTaskCallable { - - protected static final Logger LOG = LoggerFactory.getLogger(PropagationTaskCallable.class); - - @Autowired - protected PropagationTaskExecutor taskExecutor; - - protected final String domain; - - protected final Collection authorities; - - protected PropagationTaskInfo taskInfo; - - protected PropagationReporter reporter; - - protected String executor; - - public DefaultPropagationTaskCallable() { - SecurityContext ctx = SecurityContextHolder.getContext(); - domain = AuthContextUtils.getDomain(); - authorities = ctx.getAuthentication().getAuthorities().stream(). - map(GrantedAuthority::getAuthority).collect(Collectors.toSet()); - } - - @Override - public void setTaskInfo(final PropagationTaskInfo taskInfo) { - this.taskInfo = taskInfo; - } - - @Override - public void setReporter(final PropagationReporter reporter) { - this.reporter = reporter; - } - - @Override - public void setExecutor(final String executor) { - this.executor = executor; - } - - @Override - public TaskExec call() { - return AuthContextUtils.callAs(domain, executor, authorities, () -> { - LOG.debug("Execution started for {}", taskInfo); - - TaskExec execution = taskExecutor.execute(taskInfo, reporter, executor); - - LOG.debug("Execution completed for {}, {}", taskInfo, execution); - - return execution; - }); - } -} diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java index a95a20d09c9..f4bfc86950a 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java @@ -23,11 +23,13 @@ import java.util.Comparator; import java.util.List; import java.util.Optional; +import java.util.Set; +import java.util.concurrent.Callable; import java.util.concurrent.CompletionService; import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.Future; +import java.util.stream.Collectors; import org.apache.syncope.common.lib.types.ExecStatus; -import org.apache.syncope.core.persistence.api.ApplicationContextProvider; import org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValidationManager; import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; @@ -43,12 +45,14 @@ import org.apache.syncope.core.provisioning.api.notification.NotificationManager; import org.apache.syncope.core.provisioning.api.propagation.PropagationException; import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter; -import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskCallable; import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskInfo; import org.apache.syncope.core.provisioning.java.pushpull.OutboundMatcher; import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils; +import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.core.spring.task.VirtualThreadPoolTaskExecutor; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; /** * Sorts the tasks to be executed according to related @@ -59,28 +63,6 @@ */ public class PriorityPropagationTaskExecutor extends AbstractPropagationTaskExecutor { - /** - * Creates new instances of {@link PropagationTaskCallable} for usage with - * {@link java.util.concurrent.CompletionService}. - * - * @param taskInfo to be executed - * @param reporter to report propagation execution status - * @param executor user that triggered the propagation execution - * @return new {@link PropagationTaskCallable} instance for usage with - * {@link java.util.concurrent.CompletionService} - */ - protected PropagationTaskCallable newPropagationTaskCallable( - final PropagationTaskInfo taskInfo, final PropagationReporter reporter, final String executor) { - - PropagationTaskCallable callable = ApplicationContextProvider.getBeanFactory(). - createBean(DefaultPropagationTaskCallable.class); - callable.setTaskInfo(taskInfo); - callable.setReporter(reporter); - callable.setExecutor(executor); - - return callable; - } - protected final VirtualThreadPoolTaskExecutor taskExecutor; public PriorityPropagationTaskExecutor( @@ -115,6 +97,40 @@ public PriorityPropagationTaskExecutor( this.taskExecutor = taskExecutor; } + /** + * Creates new instances of {@link Callable} for usage with{@link java.util.concurrent.CompletionService}. + * + * @param taskInfo to be executed + * @param reporter to report propagation execution status + * @param executor user that triggered the propagation execution + * @return new {@link Callable} instance for usage with {@link java.util.concurrent.CompletionService} + */ + protected Callable> newPropagationTaskCallable( + final PropagationTaskInfo taskInfo, final PropagationReporter reporter, final String executor) { + + String domain = AuthContextUtils.getDomain(); + Set authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities().stream(). + map(GrantedAuthority::getAuthority).collect(Collectors.toSet()); + + return () -> AuthContextUtils.callAs(domain, executor, authorities, () -> { + LOG.debug("Execution started for {}", taskInfo); + + TaskExec execution = this.execute(taskInfo, reporter, executor); + + LOG.debug("Execution completed for {} with results {}", taskInfo, execution); + + return execution; + }); + } + + protected boolean failed( + final PropagationTaskInfo taskInfpo, + final TaskExec exec, + final ExecStatus execStatus) { + + return execStatus == ExecStatus.FAILURE; + } + @Override public PropagationReporter execute( final Collection taskInfos, @@ -147,7 +163,7 @@ public PropagationReporter execute( execStatus = ExecStatus.FAILURE; errorMessage = e.getMessage(); } - if (execStatus == ExecStatus.FAILURE) { + if (failed(taskInfo, exec, execStatus)) { throw new PropagationException( taskInfo.getResource().getKey(), Optional.ofNullable(exec).map(Exec::getMessage).orElse(errorMessage)); From 40f3850eefe8d5a3e09f4680c3b5291558b9b6f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Tue, 13 May 2025 12:09:49 +0200 Subject: [PATCH 045/579] [SYNCOPE-1881] Ensure to fetch the SP metadata value from the matching AuthModule instance --- .../wizards/AuthModuleWizardBuilder.java | 31 ++++++++- .../saml/WASAML2ClientMetadataGenerator.java | 67 ++++++++++++++++--- .../pac4j/saml/WASAML2MetadataResolver.java | 4 +- 3 files changed, 90 insertions(+), 12 deletions(-) diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder.java b/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder.java index 2dac0c78751..6afacdc038f 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/wizards/AuthModuleWizardBuilder.java @@ -19,6 +19,8 @@ package org.apache.syncope.client.console.wizards; import java.io.Serializable; +import java.nio.charset.StandardCharsets; +import java.util.Base64; import java.util.List; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; @@ -205,8 +207,33 @@ protected PageReference getPageReference() { return pageRef; } }); - add(new XMLEditorPanel(null, - new PropertyModel<>(authModule, "conf.serviceProviderMetadata"), false, pageRef)); + add(new XMLEditorPanel(null, new IModel() { + + private static final long serialVersionUID = -6439061267623081672L; + + @Override + public String getObject() { + SAML2IdPAuthModuleConf conf = (SAML2IdPAuthModuleConf) authModule.getConf(); + if (StringUtils.isEmpty(conf.getServiceProviderMetadata())) { + return null; + } + + return new String( + Base64.getDecoder().decode(conf.getServiceProviderMetadata()), + StandardCharsets.UTF_8); + } + + @Override + public void setObject(final String object) { + SAML2IdPAuthModuleConf conf = (SAML2IdPAuthModuleConf) authModule.getConf(); + if (StringUtils.isEmpty(object)) { + conf.setServiceProviderMetadata(null); + } else { + conf.setServiceProviderMetadata(Base64.getEncoder(). + encodeToString(object.getBytes(StandardCharsets.UTF_8))); + } + } + }, false, pageRef)); } @Override diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientMetadataGenerator.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientMetadataGenerator.java index 9f90207dcaf..eaadfdd8a2d 100644 --- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientMetadataGenerator.java +++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2ClientMetadataGenerator.java @@ -20,11 +20,13 @@ import java.nio.charset.StandardCharsets; import java.util.Base64; +import java.util.Optional; import org.apache.commons.io.IOUtils; import org.apache.syncope.common.rest.api.service.wa.WASAML2SPService; import org.apache.syncope.wa.bootstrap.WARestClient; import org.opensaml.saml.metadata.resolver.MetadataResolver; import org.opensaml.saml.metadata.resolver.impl.AbstractMetadataResolver; +import org.opensaml.saml.saml2.metadata.EntityDescriptor; import org.pac4j.saml.client.SAML2Client; import org.pac4j.saml.metadata.BaseSAML2MetadataGenerator; import org.slf4j.Logger; @@ -48,6 +50,52 @@ public boolean storeMetadata(final String metadata, final boolean force) { return true; } + protected Optional metadataAvailable() { + try { + String encodedMetadata = waRestClient.getService(WASAML2SPService.class). + getSAML2SPMetadata(saml2Client.getName()).readEntity(String.class); + + LOG.debug("Retrieved metadata {}", encodedMetadata); + return Optional.of(new String(Base64.getDecoder().decode(encodedMetadata), StandardCharsets.UTF_8)); + } catch (Exception e) { + LOG.error("While attempting to read metadata for SP Entity {}", saml2Client.getName(), e); + return Optional.empty(); + } + } + + /** + * {@inheritDoc} + * + * @return {@code null} if metadata was found in Syncope Core via REST + */ + @Override + public EntityDescriptor buildEntityDescriptor() { + return metadataAvailable(). + map(m -> (EntityDescriptor) null). + orElseGet(() -> { + EntityDescriptor entityDescriptor = super.buildEntityDescriptor(); + entityDescriptor.setValidUntil(null); + if (signMetadata) { + signMetadata(entityDescriptor); + } + return entityDescriptor; + }); + } + + /** + * {@inheritDoc} + * + * return metadata from Syncope Core via REST, if available; otherwise, generate + */ + @Override + public String getMetadata(final EntityDescriptor entityDescriptor) throws Exception { + String metadata = metadataAvailable().orElse(null); + if (metadata == null) { + return super.getMetadata(entityDescriptor); + } + return metadata; + } + @Override protected AbstractMetadataResolver createMetadataResolver() { return new WASAML2MetadataResolver(waRestClient, saml2Client); @@ -55,15 +103,18 @@ protected AbstractMetadataResolver createMetadataResolver() { @Override public MetadataResolver buildMetadataResolver() throws Exception { - String encodedMetadata = Base64.getEncoder().encodeToString( - getMetadata(buildEntityDescriptor()).getBytes(StandardCharsets.UTF_8)); - LOG.debug("Encoded SP metadata {}", encodedMetadata); + EntityDescriptor entityDescriptor = buildEntityDescriptor(); + if (entityDescriptor != null) { + String encodedMetadata = Base64.getEncoder().encodeToString( + getMetadata(entityDescriptor).getBytes(StandardCharsets.UTF_8)); + LOG.debug("Encoded SP metadata {}", encodedMetadata); - try { - waRestClient.getService(WASAML2SPService.class).setSAML2SPMetadata( - saml2Client.getName(), IOUtils.toInputStream(encodedMetadata, StandardCharsets.UTF_8)); - } catch (Exception e) { - LOG.error("While storing SP {} metadata", saml2Client.getName(), e); + try { + waRestClient.getService(WASAML2SPService.class).setSAML2SPMetadata( + saml2Client.getName(), IOUtils.toInputStream(encodedMetadata, StandardCharsets.UTF_8)); + } catch (Exception e) { + LOG.error("While storing SP {} metadata", saml2Client.getName(), e); + } } return super.buildMetadataResolver(); diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2MetadataResolver.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2MetadataResolver.java index 1788e31baf9..da9b3ea7a08 100644 --- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2MetadataResolver.java +++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/pac4j/saml/WASAML2MetadataResolver.java @@ -51,10 +51,10 @@ protected byte[] fetchMetadata() throws ResolverException { String encodedMetadata = waRestClient.getService(WASAML2SPService.class). getSAML2SPMetadata(saml2Client.getName()).readEntity(String.class); - LOG.debug("Retrieved keystore {}", encodedMetadata); + LOG.debug("Retrieved metadata {}", encodedMetadata); return Base64.getDecoder().decode(encodedMetadata); } catch (Exception e) { - String message = "Unable to fetch SP metadata for " + saml2Client.getName(); + String message = "Unable to fetch SP metadata for SP entity " + saml2Client.getName(); LOG.error(message, e); throw new ResolverException(message); } From ed7468767f01e5bea3afccff3d396e1d64f18b82 Mon Sep 17 00:00:00 2001 From: Samuel Garofalo <72073457+SamuelGaro@users.noreply.github.com> Date: Tue, 13 May 2025 13:41:07 +0200 Subject: [PATCH 046/579] [SYNCOPE-1880] accept Prefer header with return-no-content value with SCIM Patch to return 204 (No Content) (#1078) --- .../cxf/service/AbstractSCIMService.java | 35 ++++++++++++++++++- .../cxf/service/SCIMGroupServiceImpl.java | 20 +++++++---- .../scimv2/cxf/service/SCIMServiceImpl.java | 5 +++ .../cxf/service/SCIMUserServiceImpl.java | 20 +++++++---- .../apache/syncope/fit/core/SCIMITCase.java | 28 +++++++++++++-- 5 files changed, 93 insertions(+), 15 deletions(-) diff --git a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractSCIMService.java b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractSCIMService.java index 2483bddddcd..7fb4a2fa572 100644 --- a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractSCIMService.java +++ b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractSCIMService.java @@ -31,6 +31,8 @@ import org.apache.syncope.common.lib.to.AnyTO; import org.apache.syncope.common.lib.to.GroupTO; import org.apache.syncope.common.lib.to.UserTO; +import org.apache.syncope.common.rest.api.Preference; +import org.apache.syncope.common.rest.api.RESTHeaders; import org.apache.syncope.core.logic.AbstractAnyLogic; import org.apache.syncope.core.logic.GroupLogic; import org.apache.syncope.core.logic.SCIMDataBinder; @@ -129,12 +131,33 @@ protected Response createResponse(final String key, final SCIMResource resource) build(); } - protected Response updateResponse(final String key, final SCIMResource resource) { + protected Response updateResponse(final String key, final SCIMResource resource, final boolean patch) { + if (patch) { + Response.ResponseBuilder builder; + switch (getPreference()) { + case RETURN_NO_CONTENT: + builder = Response.noContent(); + break; + + case RETURN_CONTENT: + case NONE: + default: + builder = Response.ok(uriInfo.getAbsolutePathBuilder().path(key).build()).entity(getResource(key)); + break; + } + if (getPreference() == Preference.RETURN_CONTENT || getPreference() == Preference.RETURN_NO_CONTENT) { + builder.header(RESTHeaders.PREFERENCE_APPLIED, getPreference().toString()); + } + + return builder.build(); + } return Response.ok(uriInfo.getAbsolutePathBuilder().path(key).build()). entity(resource). build(); } + protected abstract SCIMResource getResource(String key); + protected ResponseBuilder checkETag(final Resource resource, final String key) { OffsetDateTime lastChange = anyDAO(resource).findLastChange(key). orElseThrow(() -> new NotFoundException("Resource" + key + " not found")); @@ -220,4 +243,14 @@ protected ListResponse doSearch(final Resource type, final SCIMSearchRequest return response; } + + /** + * Reads {@code Prefer} header from request and parses into a {@code Preference} instance. + * + * @return a {@code Preference} instance matching the passed {@code Prefer} header, + * or {@code Preference.NONE} if missing. + */ + protected Preference getPreference() { + return Preference.fromString(messageContext.getHttpServletRequest().getHeader(RESTHeaders.PREFER)); + } } diff --git a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMGroupServiceImpl.java b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMGroupServiceImpl.java index 6ce4e0534e5..cffda6accb0 100644 --- a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMGroupServiceImpl.java +++ b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMGroupServiceImpl.java @@ -54,6 +54,7 @@ import org.apache.syncope.ext.scimv2.api.data.Member; import org.apache.syncope.ext.scimv2.api.data.SCIMGroup; import org.apache.syncope.ext.scimv2.api.data.SCIMPatchOp; +import org.apache.syncope.ext.scimv2.api.data.SCIMResource; import org.apache.syncope.ext.scimv2.api.data.SCIMSearchRequest; import org.apache.syncope.ext.scimv2.api.service.SCIMGroupService; import org.apache.syncope.ext.scimv2.api.type.ErrorType; @@ -167,11 +168,8 @@ public Response update(final String id, final SCIMPatchOp patch) { return updateResponse( id, - binder.toSCIMGroup( - groupLogic.read(id), - uriInfo.getAbsolutePathBuilder().path(id).build().toASCIIString(), - List.of(), - List.of())); + null, + true); } @Override @@ -213,7 +211,17 @@ public Response replace(final String id, final SCIMGroup group) { result.getEntity(), uriInfo.getAbsolutePathBuilder().path(result.getEntity().getKey()).build().toASCIIString(), List.of(), - List.of())); + List.of()), + false); + } + + @Override + protected SCIMResource getResource(final String key) { + return binder.toSCIMGroup( + groupLogic.read(key), + uriInfo.getAbsolutePathBuilder().path(key).build().toASCIIString(), + List.of(), + List.of()); } @Override diff --git a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMServiceImpl.java b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMServiceImpl.java index 511aac2cab0..f6f11c4f5f5 100644 --- a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMServiceImpl.java +++ b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMServiceImpl.java @@ -73,4 +73,9 @@ public Response schemas() { public Response schema(final String schema) { return Response.ok(scimLogic.schema(schema)).build(); } + + @Override + protected SCIMResource getResource(final String key) { + return null; + } } diff --git a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMUserServiceImpl.java b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMUserServiceImpl.java index 7f40129b8ce..dfa7f6fa629 100644 --- a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMUserServiceImpl.java +++ b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMUserServiceImpl.java @@ -40,6 +40,7 @@ import org.apache.syncope.ext.scimv2.api.BadRequestException; import org.apache.syncope.ext.scimv2.api.data.ListResponse; import org.apache.syncope.ext.scimv2.api.data.SCIMPatchOp; +import org.apache.syncope.ext.scimv2.api.data.SCIMResource; import org.apache.syncope.ext.scimv2.api.data.SCIMSearchRequest; import org.apache.syncope.ext.scimv2.api.data.SCIMUser; import org.apache.syncope.ext.scimv2.api.service.SCIMUserService; @@ -102,11 +103,8 @@ public Response update(final String id, final SCIMPatchOp patch) { return updateResponse( id, - binder.toSCIMUser( - userLogic.read(id), - uriInfo.getAbsolutePathBuilder().path(id).build().toASCIIString(), - List.of(), - List.of())); + null, + true); } @Override @@ -144,7 +142,17 @@ public Response replace(final String id, final SCIMUser user) { result.getEntity(), uriInfo.getAbsolutePathBuilder().path(result.getEntity().getKey()).build().toASCIIString(), List.of(), - List.of())); + List.of()), + false); + } + + @Override + protected SCIMResource getResource(final String key) { + return binder.toSCIMUser( + userLogic.read(key), + uriInfo.getAbsolutePathBuilder().path(key).build().toASCIIString(), + List.of(), + List.of()); } @Override diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SCIMITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SCIMITCase.java index 236dc3dcc62..27ed44eaa82 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SCIMITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SCIMITCase.java @@ -61,6 +61,8 @@ import org.apache.syncope.common.lib.to.ProvisioningResult; import org.apache.syncope.common.lib.to.UserTO; import org.apache.syncope.common.lib.types.PatchOperation; +import org.apache.syncope.common.rest.api.Preference; +import org.apache.syncope.common.rest.api.RESTHeaders; import org.apache.syncope.ext.scimv2.api.SCIMConstants; import org.apache.syncope.ext.scimv2.api.data.Group; import org.apache.syncope.ext.scimv2.api.data.ListResponse; @@ -694,8 +696,11 @@ public void updateUser() { + "\"value\":\"Password123!\"" + "}]" + "}"; - response = webClient().path("Users").path(user.getId()).invoke(HttpMethod.PATCH, body); - assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + response = webClient().path("Users").path(user.getId()) + .header(RESTHeaders.PREFER, Preference.RETURN_NO_CONTENT) + .invoke(HttpMethod.PATCH, body); + assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus()); + assertFalse(response.hasEntity()); } @Test @@ -862,6 +867,25 @@ public void updateGroup() { group = response.readEntity(SCIMGroup.class); assertTrue(group.getMembers().isEmpty()); + + // 4. add member + body = + "{" + + "\"schemas\":[\"urn:ietf:params:scim:api:messages:2.0:PatchOp\"]," + + "\"Operations\":[" + + "{" + + "\"op\":\"Add\"," + + "\"path\":\"members\"," + + "\"value\":[{" + + "\"value\":\"b3cbc78d-32e6-4bd4-92e0-bbe07566a2ee\"}]" + + "}" + + "]" + + "}"; + response = webClient().path("Groups").path(group.getId()) + .header(RESTHeaders.PREFER, Preference.RETURN_NO_CONTENT) + .invoke(HttpMethod.PATCH, body); + assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus()); + assertFalse(response.hasEntity()); } @Test From 1983d4a23b24daf38992951a0af713b80e4f6ace Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 May 2025 08:22:34 +0200 Subject: [PATCH 047/579] Bump swagger-core.version from 2.2.30 to 2.2.31 (#1079) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2b39b6fd6ee..d10bb6f6e89 100644 --- a/pom.xml +++ b/pom.xml @@ -446,7 +446,7 @@ under the License. 7.2.2 4.0.4 - 2.2.30 + 2.2.31 5.21.0 1.3.8 From ffaa6827008ad78296fd4d17f81ac1b2c94a548b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Wed, 14 May 2025 12:44:33 +0200 Subject: [PATCH 048/579] [SYNCOPE-1882] Not adding placeholder value for multivalue dropdown attributes --- .../syncope/client/console/wizards/any/PlainAttrs.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java index 75d78133dcd..334f28c229d 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java @@ -36,6 +36,7 @@ import org.apache.syncope.common.lib.to.MembershipTO; import org.apache.syncope.common.lib.to.PlainSchemaTO; import org.apache.syncope.common.lib.to.UserTO; +import org.apache.syncope.common.lib.types.AttrSchemaType; import org.apache.syncope.common.lib.types.SchemaType; import org.apache.wicket.extensions.markup.html.tabs.AbstractTab; import org.apache.wicket.markup.html.WebMarkupContainer; @@ -150,7 +151,9 @@ protected void setAttrs() { Attr attr = new Attr(); attr.setSchema(schema.getKey()); if (attrMap.get(schema.getKey()) == null || attrMap.get(schema.getKey()).getValues().isEmpty()) { - attr.getValues().add(""); + if (schema.getType() != AttrSchemaType.Dropdown && !schema.isMultivalue()) { + attr.getValues().add(StringUtils.EMPTY); + } } else { attr = attrMap.get(schema.getKey()); } @@ -172,7 +175,9 @@ protected void setAttrs(final MembershipTO membershipTO) { Attr attr = new Attr(); attr.setSchema(schema.getKey()); if (attrMap.get(schema.getKey()) == null || attrMap.get(schema.getKey()).getValues().isEmpty()) { - attr.getValues().add(StringUtils.EMPTY); + if (schema.getType() != AttrSchemaType.Dropdown && !schema.isMultivalue()) { + attr.getValues().add(StringUtils.EMPTY); + } } else { attr.getValues().addAll(attrMap.get(schema.getKey()).getValues()); } From b35f8309de7227fd53211b1c23564c0774eaf017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Thu, 15 May 2025 11:14:40 +0200 Subject: [PATCH 049/579] [SYNCOPE-1882] Fixing multivalue dropdown attribute check + SearchClausePanel improvements --- .../markup/html/form/AjaxPalettePanel.java | 8 +- .../ui/commons/panels/SyncopeFormPanel.java | 2 +- .../panels/search/AbstractSearchPanel.java | 7 +- .../panels/search/SearchClausePanel.java | 723 +++++++++--------- .../client/console/rest/SchemaRestClient.java | 26 +- .../console/wizards/any/PlainAttrs.java | 4 +- .../client/enduser/panels/any/PlainAttrs.java | 22 +- pom.xml | 4 +- 8 files changed, 390 insertions(+), 406 deletions(-) diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPalettePanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPalettePanel.java index eccd2d51a43..723d813209d 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPalettePanel.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/AjaxPalettePanel.java @@ -158,11 +158,9 @@ public List getUnselectedList() { List ids = builder.idExtractor.apply(getValue()).toList(); List unselected = new ArrayList<>(choices.size()); - choices.forEach(choice -> { - if (!ids.contains(renderer.getIdValue(choice, 0))) { - unselected.add(choice); - } - }); + choices.stream(). + filter(choice -> !ids.contains(renderer.getIdValue(choice, 0))). + forEach(unselected::add); return unselected; } diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/SyncopeFormPanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/SyncopeFormPanel.java index cf8d4a6b25c..386436fbd85 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/SyncopeFormPanel.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/SyncopeFormPanel.java @@ -165,7 +165,7 @@ public void setObject(final Date object) { public List getObject() { return Optional.ofNullable(prop.getValue()). map(v -> List.of(v.split(";"))). - orElseGet(List::of); + orElseGet(List::of); } @Override diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java index e3185493bf5..c399c170efe 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/AbstractSearchPanel.java @@ -247,9 +247,10 @@ protected void populate() { protected Map load() { Map dSchemaNames = new HashMap<>(); SearchableFields.get(typeKind.getTOClass()).forEach((key, type) -> { - PlainSchemaTO plain = new PlainSchemaTO(); - plain.setType(type); - dSchemaNames.put(key, plain); + PlainSchemaTO plainSchema = new PlainSchemaTO(); + plainSchema.setType(type); + plainSchema.setKey(key); + dSchemaNames.put(key, plainSchema); }); return dSchemaNames; } diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java index b68f0168eff..96262d306c5 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java @@ -22,7 +22,6 @@ import de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkbox.bootstraptoggle.BootstrapToggleConfig; import java.io.Serializable; import java.text.ParseException; -import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Locale; @@ -121,18 +120,223 @@ default List properties() { return List.of(); } - default void setFieldAccess( - FieldPanel value, + default void adjust( + Type type, AjaxTextFieldPanel property, + FieldPanel comparator, + FieldPanel value, LoadableDetachableModel>> properties) { value.setEnabled(true); - value.setModelObject(StringUtils.EMPTY); + value.setModelObject(null); property.setEnabled(true); // reload properties list properties.detach(); - property.setChoices(properties.getObject().stream().map(Pair::getKey).collect(Collectors.toList())); + property.setChoices(properties.getObject().stream().map(Pair::getKey).toList()); + } + } + + protected class ComparatorRenderer implements IChoiceRenderer { + + private static final long serialVersionUID = -9086043750227867686L; + + @Override + public Object getDisplayValue(final SearchClause.Comparator object) { + if (clause == null || clause.getObject() == null || clause.getObject().getType() == null) { + return object.toString(); + } + + String display; + + switch (clause.getObject().getType()) { + case ATTRIBUTE: + switch (object) { + case IS_NULL: + display = "NULL"; + break; + + case IS_NOT_NULL: + display = "NOT NULL"; + break; + + case EQUALS: + display = "=="; + break; + + case NOT_EQUALS: + display = "!="; + break; + + case LESS_THAN: + display = "<"; + break; + + case LESS_OR_EQUALS: + display = "<="; + break; + + case GREATER_THAN: + display = ">"; + break; + + case GREATER_OR_EQUALS: + display = ">="; + break; + + default: + display = StringUtils.EMPTY; + } + break; + + case GROUP_MEMBERSHIP: + switch (object) { + case EQUALS: + display = "IN"; + break; + + case NOT_EQUALS: + display = "NOT IN"; + break; + + default: + display = StringUtils.EMPTY; + } + break; + + case GROUP_MEMBER: + switch (object) { + case EQUALS: + display = "WITH"; + break; + + case NOT_EQUALS: + display = "WITHOUT"; + break; + + default: + display = StringUtils.EMPTY; + } + break; + + case AUX_CLASS: + case ROLE_MEMBERSHIP: + case RESOURCE: + switch (object) { + case EQUALS: + display = "HAS"; + break; + + case NOT_EQUALS: + display = "HAS NOT"; + break; + + default: + display = StringUtils.EMPTY; + } + break; + + case RELATIONSHIP: + switch (object) { + case IS_NOT_NULL: + display = "EXIST"; + break; + + case IS_NULL: + display = "NOT EXIST"; + break; + + case EQUALS: + display = "WITH"; + break; + + case NOT_EQUALS: + display = "WITHOUT"; + break; + + default: + display = StringUtils.EMPTY; + } + break; + + case CUSTOM: + display = customizer.comparatorDisplayValue(object); + break; + + default: + display = object.toString(); + } + return display; + } + + @Override + public String getIdValue(final SearchClause.Comparator object, final int index) { + return getDisplayValue(object).toString(); + } + + @Override + public SearchClause.Comparator getObject( + final String id, final IModel> choices) { + + if (id == null) { + return SearchClause.Comparator.EQUALS; + } + + final SearchClause.Comparator comparator; + switch (id) { + case "HAS": + case "IN": + case "WITH": + comparator = SearchClause.Comparator.EQUALS; + break; + + case "HAS NOT": + case "NOT IN": + case "WITHOUT": + comparator = SearchClause.Comparator.NOT_EQUALS; + break; + + case "NULL": + case "NOT EXIST": + comparator = SearchClause.Comparator.IS_NULL; + break; + + case "NOT NULL": + case "EXIST": + comparator = SearchClause.Comparator.IS_NOT_NULL; + break; + + case "==": + comparator = SearchClause.Comparator.EQUALS; + break; + + case "!=": + comparator = SearchClause.Comparator.NOT_EQUALS; + break; + + case "<": + comparator = SearchClause.Comparator.LESS_THAN; + break; + + case "<=": + comparator = SearchClause.Comparator.LESS_OR_EQUALS; + break; + + case ">": + comparator = SearchClause.Comparator.GREATER_THAN; + break; + + case ">=": + comparator = SearchClause.Comparator.GREATER_OR_EQUALS; + break; + + default: + // EQUALS to be used as default value + comparator = customizer.comparatorGetObject(id).orElse(SearchClause.Comparator.EQUALS); + break; + } + + return comparator; } } @@ -174,8 +378,7 @@ default void setFieldAccess( protected IEventSink resultContainer; - @SuppressWarnings({ "rawtypes", "unchecked" }) - private FieldPanel value; + private FieldPanel value; public SearchClausePanel( final String id, @@ -193,7 +396,7 @@ public SearchClausePanel( super(id, name, clause); - this.clause = clause == null ? new Model<>(null) : clause; + this.clause = Optional.ofNullable(clause).orElseGet(() -> new Model<>(null)); this.required = required; this.types = types; @@ -211,11 +414,9 @@ public SearchClausePanel( @Override public void onClick(final AjaxRequestTarget target) { - if (resultContainer == null) { - send(SearchClausePanel.this, Broadcast.BUBBLE, new SearchEvent(target)); - } else { - send(resultContainer, Broadcast.EXACT, new SearchEvent(target)); - } + Optional.ofNullable(resultContainer).ifPresentOrElse( + container -> send(container, Broadcast.EXACT, new SearchEvent(target)), + () -> send(SearchClausePanel.this, Broadcast.BUBBLE, new SearchEvent(target))); } }; @@ -281,7 +482,7 @@ protected List> load() { } switch (field.getModel().getObject().getType()) { - case ATTRIBUTE: + case ATTRIBUTE -> { Locale locale = SyncopeConsoleSession.get().getLocale(); List> names = dnames.getObject().entrySet().stream(). map(item -> Pair.of( @@ -293,42 +494,49 @@ protected List> load() { map(item -> Pair.of( item.getKey(), Optional.ofNullable(item.getValue().getLabel(locale)).orElseGet(item::getKey))). - toList()); + toList()); } return names.stream(). sorted(java.util.Comparator.comparing(name -> name.getValue().toLowerCase())). collect(Collectors.toList()); + } - case GROUP_MEMBERSHIP: - return groupInfo.getLeft().getObject().stream(). - map(item -> Pair.of(item, item)).collect(Collectors.toList()); + case GROUP_MEMBERSHIP -> { + return groupInfo.getLeft().getObject().stream().map(item -> Pair.of(item, item)).toList(); + } - case ROLE_MEMBERSHIP: + case ROLE_MEMBERSHIP -> { return Optional.ofNullable(roleNames). map(r -> r.getObject().stream().sorted().map(item -> Pair.of(item, item)). collect(Collectors.toList())). - orElseGet(List::of); + orElseGet(List::of); + } - case AUX_CLASS: + case AUX_CLASS -> { return auxClassNames.getObject().stream().sorted(). - map(item -> Pair.of(item, item)).collect(Collectors.toList()); + map(item -> Pair.of(item, item)).toList(); + } - case RESOURCE: + case RESOURCE -> { return resourceNames.getObject().stream().sorted(). - map(item -> Pair.of(item, item)).collect(Collectors.toList()); + map(item -> Pair.of(item, item)).toList(); + } - case RELATIONSHIP: - return relationshipTypeRestClient.list().stream().sorted(). + case RELATIONSHIP -> { + return relationshipTypeRestClient.list().stream(). map(item -> Pair.of(item.getKey(), item.getKey())). - collect(Collectors.toList()); + sorted().toList(); + } - case CUSTOM: + case CUSTOM -> { return customizer.properties().stream(). map(item -> Pair.of(item, item)). collect(Collectors.toList()); + } - default: + default -> { return List.of(); + } } } }; @@ -386,7 +594,6 @@ public FieldPanel setNewModel(final IModel model) { } @Override - @SuppressWarnings({ "rawtypes", "unchecked" }) public FieldPanel settingsDependingComponents() { SearchClause searchClause = this.clause.getObject(); @@ -448,8 +655,8 @@ protected void onUpdate(final AjaxRequestTarget target) { operatorContainer.add(searchButtonFragment); } - AjaxTextFieldPanel property = new AjaxTextFieldPanel("property", "property", - new PropertyModel<>(searchClause, "property"), true) { + AjaxTextFieldPanel property = new AjaxTextFieldPanel( + "property", "property", new PropertyModel<>(searchClause, "property")) { private static final long serialVersionUID = -7157802546272668001L; @@ -479,10 +686,8 @@ public String convertToString(final String key, final Locale locale) { }); } }; - - property.hideLabel().setOutputMarkupId(true).setEnabled(true); - property.setChoices(properties.getObject().stream().map(Pair::getValue).collect(Collectors.toList())); - field.add(property); + property.setChoices(properties.getObject().stream().map(Pair::getValue).toList()); + field.add(property.hideLabel().setOutputMarkupId(true).setEnabled(true)); property.getField().add(PREVENT_DEFAULT_RETURN); property.getField().add(new IndicatorAjaxEventBehavior(Constants.ON_KEYUP) { @@ -496,8 +701,7 @@ protected void onEvent(final AjaxRequestTarget target) { String[] inputAsArray = property.getField().getInputAsArray(); if (ArrayUtils.isEmpty(inputAsArray)) { - property.setChoices(properties.getObject().stream().map(Pair::getKey) - .collect(Collectors.toList())); + property.setChoices(properties.getObject().stream().map(Pair::getKey).toList()); } else if (groupInfo.getRight().getObject() > Constants.MAX_GROUP_LIST_SIZE) { String inputValue = inputAsArray.length > 1 && inputAsArray[1] != null ? inputAsArray[1] @@ -516,7 +720,7 @@ protected void onEvent(final AjaxRequestTarget target) { 1, Constants.MAX_GROUP_LIST_SIZE, new SortParam<>(Constants.NAME_FIELD_NAME, true), - null).stream().map(GroupTO::getName).collect(Collectors.toList())); + null).stream().map(GroupTO::getName).toList()); } } } @@ -548,21 +752,25 @@ protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) { comparator.setChoices(comparators); comparator.setNullValid(false).hideLabel().setOutputMarkupId(true); comparator.setRequired(required); - comparator.setChoiceRenderer(getComparatorRender(field.getModel())); + comparator.setChoiceRenderer(new ComparatorRenderer()); field.add(comparator); - renderSearchValueField(searchClause, property); + value = buildValue(searchClause, property); field.addOrReplace(value); + adjust(searchClause.getType(), property, comparator); + property.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { private static final long serialVersionUID = -1107858522700306810L; @Override protected void onUpdate(final AjaxRequestTarget target) { - renderSearchValueField(searchClause, property); + value = buildValue(searchClause, property); field.addOrReplace(value); target.add(value); + + adjust(searchClause.getType(), property, comparator); } }); @@ -584,7 +792,7 @@ protected void onUpdate(final AjaxRequestTarget target) { } SearchClausePanel.this.clause.setObject(searchClause); - setFieldAccess(searchClause.getType(), property, comparator, value); + adjust(searchClause.getType(), property, comparator); // reset property value in case and just in case of change of type property.setModelObject(StringUtils.EMPTY); @@ -608,7 +816,7 @@ protected void onUpdate(final AjaxRequestTarget target) { if (comparator.getModelObject() == SearchClause.Comparator.IS_NULL || comparator.getModelObject() == SearchClause.Comparator.IS_NOT_NULL) { - value.setModelObject(StringUtils.EMPTY); + value.setModelObject(null); value.setEnabled(false); } else { value.setEnabled(true); @@ -629,373 +837,154 @@ protected void onUpdate(final AjaxRequestTarget target) { } }); - setFieldAccess(searchClause.getType(), property, comparator, value); - return this; } - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void setFieldAccess( - final Type type, - final AjaxTextFieldPanel property, - final FieldPanel comparator, - final FieldPanel value) { - - if (type != null) { - property.setEnabled(true); - comparator.setEnabled(true); - value.setEnabled(true); - - switch (type) { - case ATTRIBUTE: - if (!comparator.isEnabled()) { - comparator.setEnabled(true); - comparator.setRequired(true); - } - - if (comparator.getModelObject() == SearchClause.Comparator.IS_NULL - || comparator.getModelObject() == SearchClause.Comparator.IS_NOT_NULL) { - value.setEnabled(false); - value.setModelObject(StringUtils.EMPTY); - } - - // reload properties list - properties.detach(); - property.setChoices( - properties.getObject().stream(). - map(Pair::getValue).collect(Collectors.toList())); - break; - - case ROLE_MEMBERSHIP: - value.setEnabled(false); - value.setModelObject(StringUtils.EMPTY); - - // reload properties list - properties.detach(); - property.setChoices(properties.getObject().stream().map(Pair::getKey).collect(Collectors.toList())); - break; - - case GROUP_MEMBERSHIP: - value.setEnabled(false); - value.setModelObject(StringUtils.EMPTY); - - // reload properties list - properties.detach(); - property.setChoices(properties.getObject().stream().map(Pair::getKey).collect(Collectors.toList())); - break; - - case GROUP_MEMBER: - value.setEnabled(true); - property.setEnabled(false); - property.setModelObject(StringUtils.EMPTY); - break; - - case AUX_CLASS: - case RESOURCE: - value.setEnabled(false); - value.setModelObject(StringUtils.EMPTY); - - // reload properties list - properties.detach(); - property.setChoices(properties.getObject().stream().map(Pair::getKey).collect(Collectors.toList())); - break; - - case RELATIONSHIP: - value.setEnabled(true); - value.setModelObject(StringUtils.EMPTY); - property.setEnabled(true); - - // reload properties list - properties.detach(); - property.setChoices(properties.getObject().stream().map(Pair::getKey).collect(Collectors.toList())); - break; - - case CUSTOM: - customizer.setFieldAccess(value, property, properties); - break; - - default: - break; - } + @SuppressWarnings("unchecked") + protected void adjust(final Type type, final AjaxTextFieldPanel property, final FieldPanel comparator) { + if (type == null) { + return; } - } - - private IChoiceRenderer getComparatorRender(final IModel clause) { - return new IChoiceRenderer<>() { - private static final long serialVersionUID = -9086043750227867686L; + property.setEnabled(true); + comparator.setEnabled(true); + value.setEnabled(true); - @Override - public Object getDisplayValue(final SearchClause.Comparator object) { - if (clause == null || clause.getObject() == null || clause.getObject().getType() == null) { - return object.toString(); + switch (type) { + case ATTRIBUTE -> { + if (!comparator.isEnabled()) { + comparator.setEnabled(true); + comparator.setRequired(true); } - String display; - - switch (clause.getObject().getType()) { - case ATTRIBUTE: - switch (object) { - case IS_NULL: - display = "NULL"; - break; - - case IS_NOT_NULL: - display = "NOT NULL"; - break; - - case EQUALS: - display = "=="; - break; - - case NOT_EQUALS: - display = "!="; - break; - - case LESS_THAN: - display = "<"; - break; - - case LESS_OR_EQUALS: - display = "<="; - break; - - case GREATER_THAN: - display = ">"; - break; - - case GREATER_OR_EQUALS: - display = ">="; - break; - - default: - display = StringUtils.EMPTY; - } - break; - - case GROUP_MEMBERSHIP: - switch (object) { - case EQUALS: - display = "IN"; - break; - - case NOT_EQUALS: - display = "NOT IN"; - break; - - default: - display = StringUtils.EMPTY; - } - break; - - case GROUP_MEMBER: - switch (object) { - case EQUALS: - display = "WITH"; - break; - - case NOT_EQUALS: - display = "WITHOUT"; - break; - - default: - display = StringUtils.EMPTY; - } - break; - - case AUX_CLASS: - case ROLE_MEMBERSHIP: - case RESOURCE: - switch (object) { - case EQUALS: - display = "HAS"; - break; - - case NOT_EQUALS: - display = "HAS NOT"; - break; - - default: - display = StringUtils.EMPTY; - } - break; - - case RELATIONSHIP: - switch (object) { - case IS_NOT_NULL: - display = "EXIST"; - break; + if (comparator.getModelObject() == SearchClause.Comparator.IS_NULL + || comparator.getModelObject() == SearchClause.Comparator.IS_NOT_NULL) { + value.setEnabled(false); + value.setModelObject(null); + } - case IS_NULL: - display = "NOT EXIST"; - break; + // reload properties list + properties.detach(); + property.setChoices(properties.getObject().stream().map(Pair::getValue).toList()); + } - case EQUALS: - display = "WITH"; - break; + case ROLE_MEMBERSHIP -> { + value.setEnabled(false); + value.setModelObject(null); - case NOT_EQUALS: - display = "WITHOUT"; - break; + // reload properties list + properties.detach(); + property.setChoices(properties.getObject().stream().map(Pair::getKey).toList()); + } - default: - display = StringUtils.EMPTY; - } - break; + case GROUP_MEMBERSHIP -> { + value.setEnabled(false); + value.setModelObject(null); - case CUSTOM: - display = customizer.comparatorDisplayValue(object); - break; - - default: - display = object.toString(); - } - return display; + // reload properties list + properties.detach(); + property.setChoices(properties.getObject().stream().map(Pair::getKey).toList()); } - @Override - public String getIdValue(final SearchClause.Comparator object, final int index) { - return getDisplayValue(object).toString(); + case GROUP_MEMBER -> { + value.setEnabled(true); + property.setEnabled(false); + property.setModelObject(StringUtils.EMPTY); } - @Override - public SearchClause.Comparator getObject( - final String id, final IModel> choices) { + case AUX_CLASS, RESOURCE -> { + value.setEnabled(false); + value.setModelObject(null); - if (id == null) { - return SearchClause.Comparator.EQUALS; - } + // reload properties list + properties.detach(); + property.setChoices(properties.getObject().stream().map(Pair::getKey).toList()); + } - final SearchClause.Comparator comparator; - switch (id) { - case "HAS": - case "IN": - case "WITH": - comparator = SearchClause.Comparator.EQUALS; - break; - - case "HAS NOT": - case "NOT IN": - case "WITHOUT": - comparator = SearchClause.Comparator.NOT_EQUALS; - break; - - case "NULL": - case "NOT EXIST": - comparator = SearchClause.Comparator.IS_NULL; - break; - - case "NOT NULL": - case "EXIST": - comparator = SearchClause.Comparator.IS_NOT_NULL; - break; - - case "==": - comparator = SearchClause.Comparator.EQUALS; - break; - - case "!=": - comparator = SearchClause.Comparator.NOT_EQUALS; - break; - - case "<": - comparator = SearchClause.Comparator.LESS_THAN; - break; - - case "<=": - comparator = SearchClause.Comparator.LESS_OR_EQUALS; - break; - - case ">": - comparator = SearchClause.Comparator.GREATER_THAN; - break; - - case ">=": - comparator = SearchClause.Comparator.GREATER_OR_EQUALS; - break; + case RELATIONSHIP -> { + value.setEnabled(true); + value.setModelObject(null); + property.setEnabled(true); - default: - // EQUALS to be used as default value - comparator = customizer.comparatorGetObject(id).orElse(SearchClause.Comparator.EQUALS); - break; - } + // reload properties list + properties.detach(); + property.setChoices(properties.getObject().stream().map(Pair::getKey).toList()); + } + + case CUSTOM -> + customizer.adjust(type, property, comparator, value, properties); - return comparator; + default -> { } - }; + } } - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void renderSearchValueField( - final SearchClause searchClause, - final AjaxTextFieldPanel property) { - - PlainSchemaTO plainSchema = anames.getObject().get(property.getModelObject()); - if (plainSchema == null) { - PlainSchemaTO defaultPlainTO = new PlainSchemaTO(); - defaultPlainTO.setType(AttrSchemaType.String); - plainSchema = property.getModelObject() == null ? defaultPlainTO - : dnames.getObject().getOrDefault(property.getModelObject(), defaultPlainTO); - } + @SuppressWarnings("unchecked") + protected FieldPanel buildValue(final SearchClause searchClause, final AjaxTextFieldPanel property) { + PlainSchemaTO plainSchema = Optional.ofNullable(anames.getObject().get(property.getModelObject())). + orElseGet(() -> { + PlainSchemaTO defaultPlainTO = new PlainSchemaTO(); + defaultPlainTO.setType(AttrSchemaType.String); + return Optional.ofNullable(property.getModelObject()). + map(k -> dnames.getObject().getOrDefault(k, defaultPlainTO)). + orElse(defaultPlainTO); + }); + FieldPanel result; switch (plainSchema.getType()) { case Boolean: - value = new AjaxTextFieldPanel( + result = new AjaxTextFieldPanel( "value", "value", new PropertyModel<>(searchClause, "value"), true); - ((AjaxTextFieldPanel) value).setChoices(Arrays.asList("true", "false")); + ((AjaxTextFieldPanel) result).setChoices(List.of("true", "false")); break; case Date: - FastDateFormat fdf = plainSchema.getConversionPattern() == null + FastDateFormat formatter = StringUtils.isBlank(plainSchema.getConversionPattern()) ? DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT : FastDateFormat.getInstance(plainSchema.getConversionPattern()); - value = new AjaxDateTimeFieldPanel( + result = new AjaxDateTimeFieldPanel( "value", "value", - new PropertyModel(searchClause, "value") { + new PropertyModel<>(searchClause, "value") { - private static final long serialVersionUID = 1177692285167186690L; + private static final long serialVersionUID = -3743432456095828573L; @Override - public Object getObject() { - String date = (String) super.getObject(); + public Date getObject() { try { - return date != null ? fdf.parse(date) : null; - } catch (ParseException ex) { - LOG.error("Date parse error {}", date, ex); + return StringUtils.isBlank(searchClause.getValue()) + ? null + : formatter.parse(searchClause.getValue()); + } catch (ParseException e) { + LOG.error("Unparsable date: {}", searchClause.getValue(), e); + return null; } - return null; } @Override - public void setObject(final Object object) { - if (object instanceof Date) { - String valueDate = fdf.format(object); - super.setObject(valueDate); - } else { - super.setObject(object); - } + public void setObject(final Date object) { + Optional.ofNullable(object).ifPresent(date -> searchClause.setValue(formatter.format(date))); } }, DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT); break; case Enum: - value = new AjaxDropDownChoicePanel<>( + result = new AjaxDropDownChoicePanel<>( "value", "value", - new PropertyModel(searchClause, "value"), + new PropertyModel<>(searchClause, "value"), true); - ((AjaxDropDownChoicePanel) value).setChoices( + ((AjaxDropDownChoicePanel) result).setChoices( plainSchema.getEnumValues().keySet().stream().sorted().toList()); if (!plainSchema.getEnumValues().isEmpty()) { Map valueMap = plainSchema.getEnumValues(); - ((AjaxDropDownChoicePanel) value).setChoiceRenderer(new IChoiceRenderer() { + ((AjaxDropDownChoicePanel) result).setChoiceRenderer(new IChoiceRenderer() { private static final long serialVersionUID = -3724971416312135885L; @@ -1019,44 +1008,44 @@ public String getObject( break; case Long: - value = new AjaxNumberFieldPanel.Builder().enableOnChange().build( + result = new AjaxNumberFieldPanel.Builder().enableOnChange().build( "value", "Value", Long.class, - new PropertyModel(searchClause, "value")); + new PropertyModel<>(searchClause, "value")); - value.add(new AttributeModifier("class", "field value search-spinner")); + result.add(new AttributeModifier("class", "field value search-spinner")); break; case Double: - value = new AjaxNumberFieldPanel.Builder().enableOnChange().step(0.1).build( + result = new AjaxNumberFieldPanel.Builder().enableOnChange().step(0.1).build( "value", "value", Double.class, - new PropertyModel(searchClause, "value")); - value.add(new AttributeModifier("class", "field value search-spinner")); + new PropertyModel<>(searchClause, "value")); + result.add(new AttributeModifier("class", "field value search-spinner")); break; default: - value = new AjaxTextFieldPanel( + result = new AjaxTextFieldPanel( "value", "value", new PropertyModel<>(searchClause, "value"), true); break; } - value.hideLabel().setOutputMarkupId(true); - value.getField().add(PREVENT_DEFAULT_RETURN); - value.getField().add(new IndicatorAjaxEventBehavior(Constants.ON_KEYDOWN) { + result.hideLabel().setOutputMarkupId(true); + result.getField().add(PREVENT_DEFAULT_RETURN); + result.getField().add(new IndicatorAjaxEventBehavior(Constants.ON_KEYDOWN) { private static final long serialVersionUID = -7133385027739964990L; @Override protected void onEvent(final AjaxRequestTarget target) { target.focusComponent(null); - value.getField().inputChanged(); - value.getField().validate(); - if (value.getField().isValid()) { - value.getField().valid(); - value.getField().updateModel(); + result.getField().inputChanged(); + result.getField().validate(); + if (result.getField().isValid()) { + result.getField().valid(); + result.getField().updateModel(); } } @@ -1066,6 +1055,8 @@ protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) { AJAX_SUBMIT_ON_RETURN.accept(attributes); } }); + + return result; } @Override diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java index 8609cd22b61..8ec815ad158 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java @@ -20,11 +20,11 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.to.AnyTO; -import org.apache.syncope.common.lib.to.AnyTypeTO; import org.apache.syncope.common.lib.to.RealmTO; import org.apache.syncope.common.lib.to.SchemaTO; import org.apache.syncope.common.lib.types.AnyTypeKind; @@ -40,25 +40,17 @@ public class SchemaRestClient extends BaseRestClient { private static final long serialVersionUID = -2479730152700312373L; - public List getSchemas( - final SchemaType schemaType, final AnyTypeKind kind) { - - AnyTypeService client = getService(AnyTypeService.class); - + public List getSchemas(final SchemaType schemaType, final AnyTypeKind kind) { List classes = new ArrayList<>(); switch (kind) { - case USER: - case GROUP: - AnyTypeTO type = client.read(kind.name()); - if (type != null) { - classes.addAll(type.getClasses()); - } - break; - - default: - getService(AnyTypeService.class).list().stream().filter( - anyType -> anyType.getKind() != AnyTypeKind.USER && anyType.getKind() != AnyTypeKind.GROUP). + case USER, GROUP -> + Optional.ofNullable(getService(AnyTypeService.class).read(kind.name())). + ifPresent(anyType -> classes.addAll(anyType.getClasses())); + + default -> + getService(AnyTypeService.class).list().stream(). + filter(anyType -> anyType.getKind() == AnyTypeKind.ANY_OBJECT). forEach(anyType -> classes.addAll(anyType.getClasses())); } diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java index 334f28c229d..af58c4ec978 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java @@ -151,7 +151,7 @@ protected void setAttrs() { Attr attr = new Attr(); attr.setSchema(schema.getKey()); if (attrMap.get(schema.getKey()) == null || attrMap.get(schema.getKey()).getValues().isEmpty()) { - if (schema.getType() != AttrSchemaType.Dropdown && !schema.isMultivalue()) { + if (schema.getType() != AttrSchemaType.Dropdown || !schema.isMultivalue()) { attr.getValues().add(StringUtils.EMPTY); } } else { @@ -175,7 +175,7 @@ protected void setAttrs(final MembershipTO membershipTO) { Attr attr = new Attr(); attr.setSchema(schema.getKey()); if (attrMap.get(schema.getKey()) == null || attrMap.get(schema.getKey()).getValues().isEmpty()) { - if (schema.getType() != AttrSchemaType.Dropdown && !schema.isMultivalue()) { + if (schema.getType() != AttrSchemaType.Dropdown || !schema.isMultivalue()) { attr.getValues().add(StringUtils.EMPTY); } } else { diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/PlainAttrs.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/PlainAttrs.java index dd715ffd946..45ef210a09c 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/PlainAttrs.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/PlainAttrs.java @@ -134,20 +134,20 @@ protected List getAttrsFromTO(final MembershipTO membershipTO) { @Override protected void setAttrs() { - List plainAttrs = new ArrayList<>(); - Map attrMap = EntityTOUtils.buildAttrMap(userTO.getPlainAttrs()); - plainAttrs.addAll(schemas.values().stream().map(schema -> { - Attr attrTO = new Attr(); - attrTO.setSchema(schema.getKey()); + List plainAttrs = schemas.values().stream().map(schema -> { + Attr attr = new Attr(); + attr.setSchema(schema.getKey()); if (attrMap.get(schema.getKey()) == null || attrMap.get(schema.getKey()).getValues().isEmpty()) { - attrTO.getValues().add(""); + if (schema.getType() != AttrSchemaType.Dropdown || !schema.isMultivalue()) { + attr.getValues().add(StringUtils.EMPTY); + } } else { - attrTO = attrMap.get(schema.getKey()); + attr = attrMap.get(schema.getKey()); } - return attrTO; - }).toList()); + return attr; + }).toList(); userTO.getPlainAttrs().clear(); userTO.getPlainAttrs().addAll(plainAttrs); @@ -163,7 +163,9 @@ protected void setAttrs(final MembershipTO membershipTO) { Attr attr = new Attr(); attr.setSchema(schema.getKey()); if (attrMap.get(schema.getKey()) == null || attrMap.get(schema.getKey()).getValues().isEmpty()) { - attr.getValues().add(StringUtils.EMPTY); + if (schema.getType() != AttrSchemaType.Dropdown || !schema.isMultivalue()) { + attr.getValues().add(StringUtils.EMPTY); + } } else { attr.getValues().addAll(attrMap.get(schema.getKey()).getValues()); } diff --git a/pom.xml b/pom.xml index d10bb6f6e89..236f8f95e89 100644 --- a/pom.xml +++ b/pom.xml @@ -446,7 +446,7 @@ under the License. 7.2.2 4.0.4 - 2.2.31 + 2.2.32 5.21.0 1.3.8 @@ -506,7 +506,7 @@ under the License. 60000 10.1.41 - 36.0.0.Final + 36.0.1.Final 6.2025.4 4.1.3 From 4265c0d6209538cf2bdeb01217a4d4933a0aec28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Thu, 15 May 2025 12:27:55 +0200 Subject: [PATCH 050/579] [SYNCOPE-1883] Storing username along with GoogleMfaAuthAccount (#1081) --- .../panels/search/SearchClausePanel.java | 24 +++- .../client/enduser/panels/any/PlainAttrs.java | 1 - .../common/lib/wa/GoogleMfaAuthAccount.java | 122 ++++++++++++------ .../common/lib/wa/GoogleMfaAuthToken.java | 24 ++-- .../wa/GoogleMfaAuthAccountService.java | 42 +++--- .../logic/wa/GoogleMfaAuthAccountLogic.java | 11 +- .../wa/GoogleMfaAuthAccountServiceImpl.java | 10 +- .../jpa/inner/AuthProfileTest.java | 5 +- .../neo4j/inner/AuthProfileTest.java | 5 +- .../core/wa/GoogleMfaAuthAccountITCase.java | 25 ++-- .../WAGoogleMfaAuthCredentialRepository.java | 74 +++++------ .../gauth/WAGoogleMfaAuthTokenRepository.java | 23 ++-- 12 files changed, 202 insertions(+), 164 deletions(-) diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java index 96262d306c5..fba724f0915 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/SearchClausePanel.java @@ -44,6 +44,7 @@ import org.apache.syncope.client.lib.SyncopeClient; import org.apache.syncope.client.ui.commons.Constants; import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior; +import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDateFieldPanel; import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDateTimeFieldPanel; import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel; import org.apache.syncope.client.ui.commons.markup.html.form.AjaxNumberFieldPanel; @@ -947,10 +948,7 @@ protected FieldPanel buildValue(final SearchClause searchClause, final AjaxTe ? DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT : FastDateFormat.getInstance(plainSchema.getConversionPattern()); - result = new AjaxDateTimeFieldPanel( - "value", - "value", - new PropertyModel<>(searchClause, "value") { + PropertyModel dateModel = new PropertyModel<>(searchClause, "value") { private static final long serialVersionUID = -3743432456095828573L; @@ -970,7 +968,23 @@ public Date getObject() { public void setObject(final Date object) { Optional.ofNullable(object).ifPresent(date -> searchClause.setValue(formatter.format(date))); } - }, DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT); + }; + + if (plainSchema.getConversionPattern() == null + || StringUtils.containsIgnoreCase(plainSchema.getConversionPattern(), "H")) { + + result = new AjaxDateTimeFieldPanel( + "value", + "value", + dateModel, + formatter); + } else { + result = new AjaxDateFieldPanel( + "value", + "value", + dateModel, + formatter); + } break; case Enum: diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/PlainAttrs.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/PlainAttrs.java index 45ef210a09c..6e60bee248a 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/PlainAttrs.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/any/PlainAttrs.java @@ -18,7 +18,6 @@ */ package org.apache.syncope.client.enduser.panels.any; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/wa/GoogleMfaAuthAccount.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/wa/GoogleMfaAuthAccount.java index fc01b3d5e4e..82ca852d513 100644 --- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/wa/GoogleMfaAuthAccount.java +++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/wa/GoogleMfaAuthAccount.java @@ -18,7 +18,7 @@ */ package org.apache.syncope.common.lib.wa; -import java.time.OffsetDateTime; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.builder.EqualsBuilder; @@ -34,13 +34,18 @@ public static class Builder { private final GoogleMfaAuthAccount instance = new GoogleMfaAuthAccount(); - public GoogleMfaAuthAccount.Builder registrationDate(final OffsetDateTime date) { - instance.setRegistrationDate(date); + public GoogleMfaAuthAccount.Builder id(final Long id) { + instance.setId(id); return this; } - public GoogleMfaAuthAccount.Builder scratchCodes(final List codes) { - instance.setScratchCodes(codes); + public GoogleMfaAuthAccount.Builder name(final String name) { + instance.setName(name); + return this; + } + + public GoogleMfaAuthAccount.Builder username(final String username) { + instance.setUsername(username); return this; } @@ -54,13 +59,18 @@ public GoogleMfaAuthAccount.Builder validationCode(final Integer code) { return this; } - public GoogleMfaAuthAccount.Builder id(final Long id) { - instance.setId(id); + public GoogleMfaAuthAccount.Builder scratchCodes(final List codes) { + instance.setScratchCodes(codes); return this; } - public GoogleMfaAuthAccount.Builder name(final String name) { - instance.setName(name); + public GoogleMfaAuthAccount.Builder registrationDate(final ZonedDateTime date) { + instance.setRegistrationDate(date); + return this; + } + + public GoogleMfaAuthAccount.Builder source(final String source) { + instance.setSource(source); return this; } @@ -69,17 +79,29 @@ public GoogleMfaAuthAccount build() { } } - private String secretKey; + private long id; private String name; - private int validationCode; + private String username; - private long id; + private String secretKey; + + private int validationCode; private List scratchCodes = new ArrayList<>(0); - private OffsetDateTime registrationDate; + private ZonedDateTime registrationDate; + + private String source; + + public long getId() { + return id; + } + + public void setId(final long id) { + this.id = id; + } public String getName() { return name; @@ -89,12 +111,12 @@ public void setName(final String name) { this.name = name; } - public long getId() { - return id; + public String getUsername() { + return username; } - public void setId(final long id) { - this.id = id; + public void setUsername(final String username) { + this.username = username; } public String getSecretKey() { @@ -121,24 +143,34 @@ public void setScratchCodes(final List scratchCodes) { this.scratchCodes = scratchCodes; } - public OffsetDateTime getRegistrationDate() { + public ZonedDateTime getRegistrationDate() { return registrationDate; } - public void setRegistrationDate(final OffsetDateTime registrationDate) { + public void setRegistrationDate(final ZonedDateTime registrationDate) { this.registrationDate = registrationDate; } + public String getSource() { + return source; + } + + public void setSource(final String source) { + this.source = source; + } + @Override public int hashCode() { - return new HashCodeBuilder() - .append(secretKey) - .append(name) - .append(id) - .append(scratchCodes) - .append(validationCode) - .append(registrationDate) - .toHashCode(); + return new HashCodeBuilder(). + append(id). + append(name). + append(username). + append(secretKey). + append(validationCode). + append(scratchCodes). + append(registrationDate). + append(source). + build(); } @Override @@ -153,25 +185,29 @@ public boolean equals(final Object obj) { return false; } GoogleMfaAuthAccount other = (GoogleMfaAuthAccount) obj; - return new EqualsBuilder() - .append(this.secretKey, other.secretKey) - .append(this.name, other.name) - .append(this.id, other.id) - .append(this.scratchCodes, other.scratchCodes) - .append(this.registrationDate, other.registrationDate) - .append(this.validationCode, other.validationCode) - .isEquals(); + return new EqualsBuilder(). + append(id, other.id). + append(name, other.name). + append(username, other.username). + append(secretKey, other.secretKey). + append(validationCode, other.validationCode). + append(scratchCodes, other.scratchCodes). + append(registrationDate, other.registrationDate). + append(source, other.source). + build(); } @Override public String toString() { - return new ToStringBuilder(this) - .append("name", name) - .append("secretKey", secretKey) - .append("id", id) - .append("scratchCodes", scratchCodes) - .append("registrationDate", registrationDate) - .append("validationCode", validationCode) - .toString(); + return new ToStringBuilder(this). + append(id). + append(name). + append(username). + append(secretKey). + append(validationCode). + append(scratchCodes). + append(registrationDate). + append(source). + build(); } } diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/wa/GoogleMfaAuthToken.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/wa/GoogleMfaAuthToken.java index 470103a5982..9e4d2663490 100644 --- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/wa/GoogleMfaAuthToken.java +++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/wa/GoogleMfaAuthToken.java @@ -69,10 +69,10 @@ public void setIssueDate(final LocalDateTime issueDate) { @Override public int hashCode() { - return new HashCodeBuilder() - .append(otp) - .append(issueDate) - .toHashCode(); + return new HashCodeBuilder(). + append(otp). + append(issueDate). + build(); } @Override @@ -87,17 +87,17 @@ public boolean equals(final Object obj) { return false; } GoogleMfaAuthToken other = (GoogleMfaAuthToken) obj; - return new EqualsBuilder() - .append(this.otp, other.otp) - .append(this.issueDate, other.issueDate) - .isEquals(); + return new EqualsBuilder(). + append(otp, other.otp). + append(issueDate, other.issueDate). + build(); } @Override public String toString() { - return new ToStringBuilder(this) - .append("token", otp) - .append("issueDate", issueDate) - .toString(); + return new ToStringBuilder(this). + append("token", otp). + append("issueDate", issueDate). + build(); } } diff --git a/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/wa/GoogleMfaAuthAccountService.java b/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/wa/GoogleMfaAuthAccountService.java index b003a4992e8..8b3b751950a 100644 --- a/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/wa/GoogleMfaAuthAccountService.java +++ b/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/wa/GoogleMfaAuthAccountService.java @@ -40,54 +40,50 @@ @SecurityRequirements({ @SecurityRequirement(name = "BasicAuthentication"), @SecurityRequirement(name = "Bearer") }) -@Path("wa/gauth") +@Path("wa/gauth/accts") public interface GoogleMfaAuthAccountService extends JAXRSService { - @DELETE + @GET @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) - @Path("accts/{owner}") - void delete(@NotNull @PathParam("owner") String owner); + PagedResult list(); - @DELETE + @GET @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) - @Path("accts/devices/{id}") - void delete(@NotNull @PathParam("id") long id); + @Path("{owner}") + PagedResult read(@NotNull @PathParam("owner") String owner); - @DELETE + @GET + @Path("devices/{id}") @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) - @Path("accts") - void deleteAll(); + GoogleMfaAuthAccount read(@NotNull @PathParam("id") long id); @POST - @Path("accts/{owner}") @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) - void create(@NotNull @PathParam("owner") String owner, @NotNull GoogleMfaAuthAccount acct); + void create(@NotNull GoogleMfaAuthAccount acct); @PUT - @Path("accts/{owner}") @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) - void update(@NotNull @PathParam("owner") String owner, @NotNull GoogleMfaAuthAccount acct); + void update(@NotNull GoogleMfaAuthAccount acct); - @GET + @DELETE @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) - @Path("accts/{owner}") - PagedResult read(@NotNull @PathParam("owner") String owner); + @Path("{owner}") + void delete(@NotNull @PathParam("owner") String owner); - @GET - @Path("accts/id/{id}") + @DELETE @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) - GoogleMfaAuthAccount read(@NotNull @PathParam("id") long id); + @Path("devices/{id}") + void delete(@NotNull @PathParam("id") long id); - @GET - @Path("accts") + @DELETE @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML }) - PagedResult list(); + void deleteAll(); } diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/GoogleMfaAuthAccountLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/GoogleMfaAuthAccountLogic.java index ae59dfd8df7..2877126edd8 100644 --- a/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/GoogleMfaAuthAccountLogic.java +++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/wa/GoogleMfaAuthAccountLogic.java @@ -91,8 +91,8 @@ public void deleteAll() { } @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')") - public void create(final String owner, final GoogleMfaAuthAccount account) { - AuthProfile profile = authProfile(owner); + public void create(final GoogleMfaAuthAccount account) { + AuthProfile profile = authProfile(account.getUsername()); List accounts = profile.getGoogleMfaAuthAccounts(); accounts.add(account); @@ -101,9 +101,10 @@ public void create(final String owner, final GoogleMfaAuthAccount account) { } @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')") - public void update(final String owner, final GoogleMfaAuthAccount account) { - AuthProfile authProfile = authProfileDAO.findByOwner(owner). - orElseThrow(() -> new NotFoundException("Could not find account for Owner " + owner)); + public void update(final GoogleMfaAuthAccount account) { + AuthProfile authProfile = authProfileDAO.findByOwner(account.getUsername()). + orElseThrow(() -> new NotFoundException("Could not find account for Owner " + account.getUsername())); + List accounts = authProfile.getGoogleMfaAuthAccounts(); if (accounts.removeIf(acct -> acct.getId() == account.getId())) { accounts.add(account); diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/GoogleMfaAuthAccountServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/GoogleMfaAuthAccountServiceImpl.java index 8e9b967469f..4324c40d131 100644 --- a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/GoogleMfaAuthAccountServiceImpl.java +++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/wa/GoogleMfaAuthAccountServiceImpl.java @@ -49,16 +49,16 @@ public void deleteAll() { } @Override - public void create(final String owner, final GoogleMfaAuthAccount acct) { - logic.create(owner, acct); + public void create(final GoogleMfaAuthAccount acct) { + logic.create(acct); } @Override - public void update(final String owner, final GoogleMfaAuthAccount acct) { - logic.update(owner, acct); + public void update(final GoogleMfaAuthAccount acct) { + logic.update(acct); } - private PagedResult build(final List read) { + protected PagedResult build(final List read) { PagedResult result = new PagedResult<>(); result.setPage(1); result.setSize(read.size()); diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthProfileTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthProfileTest.java index 4a930eda6d9..104d916e534 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthProfileTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AuthProfileTest.java @@ -23,7 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.time.LocalDateTime; -import java.time.OffsetDateTime; +import java.time.ZonedDateTime; import java.util.List; import java.util.Optional; import java.util.stream.IntStream; @@ -182,11 +182,12 @@ private AuthProfile createAuthProfileWithAccount(final String owner) { AuthProfile profile = entityFactory.newEntity(AuthProfile.class); profile.setOwner(owner); GoogleMfaAuthAccount account = new GoogleMfaAuthAccount.Builder() - .registrationDate(OffsetDateTime.now()) + .registrationDate(ZonedDateTime.now()) .scratchCodes(List.of(1, 2, 3, 4, 5)) .secretKey(SecureRandomUtils.generateRandomUUID().toString()) .validationCode(123456) .name(SecureRandomUtils.generateRandomUUID().toString()) + .username(owner) .build(); profile.setGoogleMfaAuthAccounts(List.of(account)); return authProfileDAO.save(profile); diff --git a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/AuthProfileTest.java b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/AuthProfileTest.java index afb48b26f8c..659a6cd81ec 100644 --- a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/AuthProfileTest.java +++ b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/AuthProfileTest.java @@ -23,7 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.time.LocalDateTime; -import java.time.OffsetDateTime; +import java.time.ZonedDateTime; import java.util.List; import java.util.Optional; import java.util.stream.IntStream; @@ -186,11 +186,12 @@ private AuthProfile createAuthProfileWithAccount(final String owner) { AuthProfile profile = entityFactory.newEntity(AuthProfile.class); profile.setOwner(owner); GoogleMfaAuthAccount account = new GoogleMfaAuthAccount.Builder() - .registrationDate(OffsetDateTime.now()) + .registrationDate(ZonedDateTime.now()) .scratchCodes(List.of(1, 2, 3, 4, 5)) .secretKey(SecureRandomUtils.generateRandomUUID().toString()) .validationCode(123456) .name(SecureRandomUtils.generateRandomUUID().toString()) + .username(owner) .build(); profile.setGoogleMfaAuthAccounts(List.of(account)); return authProfileDAO.save(profile); diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/wa/GoogleMfaAuthAccountITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/wa/GoogleMfaAuthAccountITCase.java index d054b562818..26373b9c5ec 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/wa/GoogleMfaAuthAccountITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/wa/GoogleMfaAuthAccountITCase.java @@ -23,7 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; -import java.time.OffsetDateTime; +import java.time.ZonedDateTime; import java.util.List; import java.util.UUID; import org.apache.syncope.common.lib.SyncopeClientException; @@ -36,9 +36,10 @@ public class GoogleMfaAuthAccountITCase extends AbstractITCase { - private static GoogleMfaAuthAccount createGoogleMfaAuthAccount() { + private static GoogleMfaAuthAccount createGoogleMfaAuthAccount(final String username) { return new GoogleMfaAuthAccount.Builder() - .registrationDate(OffsetDateTime.now()) + .username(username) + .registrationDate(ZonedDateTime.now()) .scratchCodes(List.of(1, 2, 3, 4, 5)) .secretKey(SecureRandomUtils.generateRandomUUID().toString()) .validationCode(123456) @@ -53,15 +54,15 @@ public void setup() { @Test public void create() { - GoogleMfaAuthAccount acct = createGoogleMfaAuthAccount(); - assertDoesNotThrow(() -> GOOGLE_MFA_AUTH_ACCOUNT_SERVICE.create(UUID.randomUUID().toString(), acct)); + GoogleMfaAuthAccount acct = createGoogleMfaAuthAccount(UUID.randomUUID().toString()); + assertDoesNotThrow(() -> GOOGLE_MFA_AUTH_ACCOUNT_SERVICE.create(acct)); } @Test public void count() { String owner = UUID.randomUUID().toString(); - GoogleMfaAuthAccount acct = createGoogleMfaAuthAccount(); - GOOGLE_MFA_AUTH_ACCOUNT_SERVICE.create(owner, acct); + GoogleMfaAuthAccount acct = createGoogleMfaAuthAccount(owner); + GOOGLE_MFA_AUTH_ACCOUNT_SERVICE.create(acct); PagedResult list = GOOGLE_MFA_AUTH_ACCOUNT_SERVICE.list(); assertFalse(list.getResult().isEmpty()); assertEquals(1, list.getTotalCount()); @@ -74,8 +75,8 @@ public void count() { @Test public void delete() { String owner = UUID.randomUUID().toString(); - GoogleMfaAuthAccount acct = createGoogleMfaAuthAccount(); - GOOGLE_MFA_AUTH_ACCOUNT_SERVICE.create(owner, acct); + GoogleMfaAuthAccount acct = createGoogleMfaAuthAccount(owner); + GOOGLE_MFA_AUTH_ACCOUNT_SERVICE.create(acct); GOOGLE_MFA_AUTH_ACCOUNT_SERVICE.delete(owner); assertThrows(SyncopeClientException.class, () -> GOOGLE_MFA_AUTH_ACCOUNT_SERVICE.read(owner)); } @@ -83,12 +84,12 @@ public void delete() { @Test public void update() { String owner = UUID.randomUUID().toString(); - GoogleMfaAuthAccount acct = createGoogleMfaAuthAccount(); - GOOGLE_MFA_AUTH_ACCOUNT_SERVICE.create(owner, acct); + GoogleMfaAuthAccount acct = createGoogleMfaAuthAccount(owner); + GOOGLE_MFA_AUTH_ACCOUNT_SERVICE.create(acct); acct = GOOGLE_MFA_AUTH_ACCOUNT_SERVICE.read(acct.getId()); acct.setSecretKey("NewSecret"); acct.setScratchCodes(List.of(9, 8, 7, 6, 5)); - GOOGLE_MFA_AUTH_ACCOUNT_SERVICE.update(owner, acct); + GOOGLE_MFA_AUTH_ACCOUNT_SERVICE.update(acct); assertEquals(1, GOOGLE_MFA_AUTH_ACCOUNT_SERVICE.list().getTotalCount()); acct = GOOGLE_MFA_AUTH_ACCOUNT_SERVICE.read(owner).getResult().getFirst(); assertEquals(acct.getSecretKey(), acct.getSecretKey()); diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/gauth/WAGoogleMfaAuthCredentialRepository.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/gauth/WAGoogleMfaAuthCredentialRepository.java index fbfcb77ae74..288d1cffc08 100644 --- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/gauth/WAGoogleMfaAuthCredentialRepository.java +++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/gauth/WAGoogleMfaAuthCredentialRepository.java @@ -19,7 +19,7 @@ package org.apache.syncope.wa.starter.gauth; import com.warrenstrange.googleauth.IGoogleAuthenticator; -import java.time.OffsetDateTime; +import java.time.ZonedDateTime; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; @@ -48,37 +48,23 @@ public WAGoogleMfaAuthCredentialRepository( this.waRestClient = waRestClient; } - protected GoogleMfaAuthAccount mapGoogleMfaAuthAccount(final OneTimeTokenAccount otta) { - return new GoogleMfaAuthAccount.Builder(). - registrationDate(OffsetDateTime.now()). - scratchCodes(otta.getScratchCodes().stream().map(Number::intValue).toList()). - validationCode(otta.getValidationCode()). - secretKey(otta.getSecretKey()). - id(otta.getId()). - build(); - } - protected GoogleAuthenticatorAccount mapGoogleMfaAuthAccount(final GoogleMfaAuthAccount gmfaa) { return GoogleAuthenticatorAccount.builder(). + id(gmfaa.getId()). + name(gmfaa.getName()). + username(gmfaa.getUsername()). secretKey(gmfaa.getSecretKey()). validationCode(gmfaa.getValidationCode()). scratchCodes(gmfaa.getScratchCodes().stream().map(Number::intValue).collect(Collectors.toList())). - name(gmfaa.getName()). - id(gmfaa.getId()). + registrationDate(gmfaa.getRegistrationDate()). + source(gmfaa.getSource()). build(); } - protected GoogleMfaAuthAccountService service() { - return waRestClient.getService(GoogleMfaAuthAccountService.class); - } - @Override public OneTimeTokenAccount get(final long id) { try { - GoogleMfaAuthAccount account = service().read(id); - if (account != null) { - return mapGoogleMfaAuthAccount(account); - } + return mapGoogleMfaAuthAccount(waRestClient.getService(GoogleMfaAuthAccountService.class).read(id)); } catch (SyncopeClientException e) { if (e.getType() == ClientExceptionType.NotFound) { LOG.info("Could not locate account for id {}", id); @@ -92,7 +78,7 @@ public OneTimeTokenAccount get(final long id) { @Override public OneTimeTokenAccount get(final String username, final long id) { try { - return service().read(username). + return waRestClient.getService(GoogleMfaAuthAccountService.class).read(username). getResult().stream(). filter(account -> account.getId() == id). map(this::mapGoogleMfaAuthAccount). @@ -111,7 +97,7 @@ public OneTimeTokenAccount get(final String username, final long id) { @Override public Collection get(final String username) { try { - return service().read(username). + return waRestClient.getService(GoogleMfaAuthAccountService.class).read(username). getResult().stream(). map(this::mapGoogleMfaAuthAccount). toList(); @@ -127,42 +113,48 @@ public Collection get(final String username) { @Override public Collection load() { - return service().list(). + return waRestClient.getService(GoogleMfaAuthAccountService.class).list(). getResult().stream(). map(this::mapGoogleMfaAuthAccount). toList(); } - @Override - public OneTimeTokenAccount save(final OneTimeTokenAccount otta) { - GoogleMfaAuthAccount account = new GoogleMfaAuthAccount.Builder(). - registrationDate(OffsetDateTime.now()). - scratchCodes(otta.getScratchCodes().stream().map(Number::intValue).toList()). - validationCode(otta.getValidationCode()). - secretKey(otta.getSecretKey()). - name(otta.getName()). + protected GoogleMfaAuthAccount mapOneTimeTokenAccount(final OneTimeTokenAccount otta) { + return new GoogleMfaAuthAccount.Builder(). id(otta.getId()). + name(otta.getName()). + username(otta.getUsername()). + secretKey(otta.getSecretKey()). + validationCode(otta.getValidationCode()). + scratchCodes(otta.getScratchCodes().stream().map(Number::intValue).toList()). + registrationDate(ZonedDateTime.now()). + source(otta.getSource()). build(); - service().create(otta.getUsername(), account); - return mapGoogleMfaAuthAccount(account); + } + + @Override + public OneTimeTokenAccount save(final OneTimeTokenAccount otta) { + GoogleMfaAuthAccount account = mapOneTimeTokenAccount(otta); + waRestClient.getService(GoogleMfaAuthAccountService.class).create(account); + return otta; } @Override public OneTimeTokenAccount update(final OneTimeTokenAccount tokenAccount) { - GoogleMfaAuthAccount acct = mapGoogleMfaAuthAccount(tokenAccount); - service().update(tokenAccount.getUsername(), acct); + GoogleMfaAuthAccount acct = mapOneTimeTokenAccount(tokenAccount); + waRestClient.getService(GoogleMfaAuthAccountService.class).update(acct); return tokenAccount; } @Override public void deleteAll() { - service().deleteAll(); + waRestClient.getService(GoogleMfaAuthAccountService.class).deleteAll(); } @Override public void delete(final String username) { try { - service().delete(username); + waRestClient.getService(GoogleMfaAuthAccountService.class).delete(username); } catch (SyncopeClientException e) { if (e.getType() == ClientExceptionType.NotFound) { LOG.info("Could not locate account for owner {}", username); @@ -174,18 +166,18 @@ public void delete(final String username) { @Override public void delete(final long id) { - service().delete(id); + waRestClient.getService(GoogleMfaAuthAccountService.class).delete(id); } @Override public long count() { - return service().list().getTotalCount(); + return waRestClient.getService(GoogleMfaAuthAccountService.class).list().getTotalCount(); } @Override public long count(final String username) { try { - return service().read(username).getTotalCount(); + return waRestClient.getService(GoogleMfaAuthAccountService.class).read(username).getTotalCount(); } catch (SyncopeClientException e) { if (e.getType() == ClientExceptionType.NotFound) { LOG.info("Could not locate account for owner {}", username); diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/gauth/WAGoogleMfaAuthTokenRepository.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/gauth/WAGoogleMfaAuthTokenRepository.java index 6148dc0ee03..d495531b4d1 100644 --- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/gauth/WAGoogleMfaAuthTokenRepository.java +++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/gauth/WAGoogleMfaAuthTokenRepository.java @@ -40,13 +40,10 @@ public WAGoogleMfaAuthTokenRepository(final WARestClient waRestClient, final lon this.expireTokensInSeconds = expireTokensInSeconds; } - protected GoogleMfaAuthTokenService service() { - return waRestClient.getService(GoogleMfaAuthTokenService.class); - } - @Override protected void cleanInternal() { - service().delete(LocalDateTime.now().minusSeconds(expireTokensInSeconds)); + waRestClient.getService(GoogleMfaAuthTokenService.class). + delete(LocalDateTime.now().minusSeconds(expireTokensInSeconds)); } @Override @@ -55,14 +52,14 @@ public GoogleAuthenticatorToken store(final GoogleAuthenticatorToken token) { token(token.getToken()). issueDate(token.getIssuedDateTime()). build(); - service().store(token.getUserId(), tokenTO); + waRestClient.getService(GoogleMfaAuthTokenService.class).store(token.getUserId(), tokenTO); return token; } @Override public GoogleAuthenticatorToken get(final String username, final Integer otp) { try { - GoogleMfaAuthToken tokenTO = service().read(username, otp); + GoogleMfaAuthToken tokenTO = waRestClient.getService(GoogleMfaAuthTokenService.class).read(username, otp); GoogleAuthenticatorToken token = new GoogleAuthenticatorToken(tokenTO.getOtp(), username); token.setIssuedDateTime(tokenTO.getIssueDate()); return token; @@ -74,31 +71,31 @@ public GoogleAuthenticatorToken get(final String username, final Integer otp) { @Override public void remove(final String username, final Integer otp) { - service().delete(username, otp); + waRestClient.getService(GoogleMfaAuthTokenService.class).delete(username, otp); } @Override public void remove(final String username) { - service().delete(username); + waRestClient.getService(GoogleMfaAuthTokenService.class).delete(username); } @Override public void remove(final Integer otp) { - service().delete(otp); + waRestClient.getService(GoogleMfaAuthTokenService.class).delete(otp); } @Override public void removeAll() { - service().delete((LocalDateTime) null); + waRestClient.getService(GoogleMfaAuthTokenService.class).delete((LocalDateTime) null); } @Override public long count(final String username) { - return service().read(username).getTotalCount(); + return waRestClient.getService(GoogleMfaAuthTokenService.class).read(username).getTotalCount(); } @Override public long count() { - return service().list().getTotalCount(); + return waRestClient.getService(GoogleMfaAuthTokenService.class).list().getTotalCount(); } } From ab51c3eb108635431eae62db3e0f86f9aaefa8a5 Mon Sep 17 00:00:00 2001 From: Andrea Patricelli Date: Thu, 15 May 2025 16:56:57 +0200 Subject: [PATCH 051/579] installing bash on all docker jdk-alpine images --- docker/console/src/main/resources/Dockerfile | 2 ++ docker/core/src/main/resources/Dockerfile | 2 ++ docker/enduser/src/main/resources/Dockerfile | 2 ++ docker/sra/src/main/resources/Dockerfile | 2 ++ docker/wa/src/main/resources/Dockerfile | 2 ++ 5 files changed, 10 insertions(+) diff --git a/docker/console/src/main/resources/Dockerfile b/docker/console/src/main/resources/Dockerfile index d6ba109082b..c2e81ed0153 100644 --- a/docker/console/src/main/resources/Dockerfile +++ b/docker/console/src/main/resources/Dockerfile @@ -18,6 +18,8 @@ FROM eclipse-temurin:21-jdk-alpine LABEL org.opencontainers.image.authors="dev@syncope.apache.org" +RUN apk update && apk add bash + RUN set -x RUN mkdir /opt/syncope diff --git a/docker/core/src/main/resources/Dockerfile b/docker/core/src/main/resources/Dockerfile index 7978a026d16..7919bc7ea33 100644 --- a/docker/core/src/main/resources/Dockerfile +++ b/docker/core/src/main/resources/Dockerfile @@ -18,6 +18,8 @@ FROM eclipse-temurin:21-jdk-alpine LABEL org.opencontainers.image.authors="dev@syncope.apache.org" +RUN apk update && apk add bash + RUN set -x RUN mkdir /opt/syncope diff --git a/docker/enduser/src/main/resources/Dockerfile b/docker/enduser/src/main/resources/Dockerfile index d0ac13b6ece..94a2ab81dcc 100644 --- a/docker/enduser/src/main/resources/Dockerfile +++ b/docker/enduser/src/main/resources/Dockerfile @@ -18,6 +18,8 @@ FROM eclipse-temurin:21-jdk-alpine LABEL org.opencontainers.image.authors="dev@syncope.apache.org" +RUN apk update && apk add bash + RUN set -x RUN mkdir /opt/syncope diff --git a/docker/sra/src/main/resources/Dockerfile b/docker/sra/src/main/resources/Dockerfile index a72d949b6ec..8212b2b6d7f 100644 --- a/docker/sra/src/main/resources/Dockerfile +++ b/docker/sra/src/main/resources/Dockerfile @@ -18,6 +18,8 @@ FROM eclipse-temurin:21-jdk-alpine LABEL org.opencontainers.image.authors="dev@syncope.apache.org" +RUN apk update && apk add bash + RUN set -x RUN mkdir /opt/syncope diff --git a/docker/wa/src/main/resources/Dockerfile b/docker/wa/src/main/resources/Dockerfile index b3c71766938..4789c2ec09e 100644 --- a/docker/wa/src/main/resources/Dockerfile +++ b/docker/wa/src/main/resources/Dockerfile @@ -18,6 +18,8 @@ FROM eclipse-temurin:21-jdk-alpine LABEL org.opencontainers.image.authors="dev@syncope.apache.org" +RUN apk update && apk add bash + RUN set -x RUN mkdir /opt/syncope From 8083a21fadc247c4a3736ab5ee6da8141207b607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Fri, 16 May 2025 19:10:51 +0200 Subject: [PATCH 052/579] [SYNCOPE-1866] AuthProfile management in Enduser (#1083) --- .../AuthProfileDirectoryPanel.java | 43 --- .../AuthProfileItemDirectoryPanel.java | 15 +- .../AuthProfileWizardBuilder.java | 4 +- .../console/rest/AuthProfileRestClient.java | 4 - client/am/enduser/pom.xml | 84 ++++++ .../client/enduser/AMEnduserContext.java | 34 +++ .../client/enduser/pages/AuthProfile.java | 221 +++++++++++++++ .../enduser/rest/AuthProfileRestClient.java | 45 +++ .../client/enduser/pages/AuthProfile.html | 257 ++++++++++++++++++ .../enduser/pages/AuthProfile.properties | 35 +++ .../enduser/pages/AuthProfile_it.properties | 35 +++ .../enduser/pages/AuthProfile_ja.properties | 35 +++ .../pages/AuthProfile_pt_BR.properties | 35 +++ .../enduser/pages/AuthProfile_ru.properties | 35 +++ client/am/pom.xml | 1 + .../console/topology/TopologyTogglePanel.java | 2 +- .../markup/html/form/ConfirmBehavior.java | 6 +- .../form/IndicatingOnConfirmAjaxLink.java | 2 +- .../client/console/pages/BasePage.java | 2 +- .../panels/DelegationSelectionPanel.java | 2 +- .../wicket/markup/html/form/ActionPanel.java | 1 + client/idrepo/enduser/pom.xml | 6 + .../enduser/panels/ChangePasswordPanel.java | 3 +- .../client/enduser/panels/Sidebar.html | 2 +- .../test/resources/enduser-debug.properties | 4 +- .../common/lib/wa/ImpersonationAccount.java | 8 +- .../common/lib/wa/MfaTrustedDevice.java | 18 +- .../lib/wa/WebAuthnDeviceCredential.java | 10 +- .../api/service/AuthProfileSelfService.java | 72 +++++ .../service/wa/GoogleMfaAuthTokenService.java | 16 +- .../syncope/core/logic/AuthProfileLogic.java | 51 +++- .../core/rest/cxf/AMRESTCXFContext.java | 8 + .../service/AuthProfileSelfServiceImpl.java | 47 ++++ .../cxf/service/AuthProfileServiceImpl.java | 10 +- .../panels/UserRequestDirectoryPanel.java | 2 +- .../client/enduser/pages/Flowable.java | 37 +-- .../client/enduser/pages/Flowable.html | 17 +- .../syncope/fit/console/AnyObjectsITCase.java | 2 +- .../syncope/fit/console/GroupsITCase.java | 2 +- .../syncope/fit/console/UsersITCase.java | 2 +- 40 files changed, 1065 insertions(+), 150 deletions(-) create mode 100644 client/am/enduser/pom.xml create mode 100644 client/am/enduser/src/main/java/org/apache/syncope/client/enduser/AMEnduserContext.java create mode 100644 client/am/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AuthProfile.java create mode 100644 client/am/enduser/src/main/java/org/apache/syncope/client/enduser/rest/AuthProfileRestClient.java create mode 100644 client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile.html create mode 100644 client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile.properties create mode 100644 client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile_it.properties create mode 100644 client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile_ja.properties create mode 100644 client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile_pt_BR.properties create mode 100644 client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile_ru.properties rename client/idrepo/{console/src/main/java/org/apache/syncope/client/console/wicket => common-ui/src/main/java/org/apache/syncope/client/ui/commons}/markup/html/form/ConfirmBehavior.java (93%) rename client/idrepo/{console/src/main/java/org/apache/syncope/client/console/wicket => common-ui/src/main/java/org/apache/syncope/client/ui/commons}/markup/html/form/IndicatingOnConfirmAjaxLink.java (96%) create mode 100644 common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AuthProfileSelfService.java create mode 100644 core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuthProfileSelfServiceImpl.java diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileDirectoryPanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileDirectoryPanel.java index f6e02fe5802..fa3dde612d4 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileDirectoryPanel.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileDirectoryPanel.java @@ -19,7 +19,6 @@ package org.apache.syncope.client.console.authprofiles; import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal; -import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; @@ -39,7 +38,6 @@ import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink; import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel; import org.apache.syncope.client.ui.commons.Constants; -import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel; import org.apache.syncope.client.ui.commons.pages.BaseWebPage; import org.apache.syncope.common.lib.to.AuthProfileTO; import org.apache.syncope.common.lib.types.AMEntitlement; @@ -50,15 +48,12 @@ import org.apache.syncope.common.lib.wa.WebAuthnDeviceCredential; import org.apache.wicket.PageReference; import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy; import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder; import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn; -import org.apache.wicket.extensions.wizard.WizardModel; import org.apache.wicket.model.CompoundPropertyModel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; -import org.apache.wicket.model.PropertyModel; import org.apache.wicket.model.ResourceModel; import org.apache.wicket.model.StringResourceModel; @@ -91,9 +86,6 @@ protected void onConfigure() { }); addOuterObject(authProfileModal); - addNewItemPanelBuilder(new CreateAuthProfileWizardBuilder(pageRef), true); - MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, AMEntitlement.AUTH_PROFILE_CREATE); - disableCheckBoxes(); initResultTable(); } @@ -467,39 +459,4 @@ public IModel model(final AuthProfileTO object) { return new CompoundPropertyModel<>(object); } } - - private class CreateAuthProfileWizardBuilder extends AuthProfileWizardBuilder { - - private static final long serialVersionUID = -2478221092672979490L; - - private class NewAuthProfileStep extends AuthProfileWizardBuilder.Step { - - private static final long serialVersionUID = 6290450377240300418L; - - NewAuthProfileStep(final AuthProfileTO modelObject) { - super(modelObject); - - AjaxTextFieldPanel owner = new AjaxTextFieldPanel( - "bean", "owner", new PropertyModel<>(modelObject, "owner")); - owner.addRequiredLabel(); - addOrReplace(owner); - } - } - - CreateAuthProfileWizardBuilder(final PageReference pageRef) { - super(new AuthProfileTO(), new StepModel<>(), pageRef); - } - - @Override - protected WizardModel buildModelSteps(final AuthProfileTO modelObject, final WizardModel wizardModel) { - wizardModel.add(new NewAuthProfileStep(modelObject)); - return wizardModel; - } - - @Override - protected Serializable onApplyInternal(final AuthProfileTO modelObject) { - restClient.create(modelObject); - return modelObject; - } - } } diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileItemDirectoryPanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileItemDirectoryPanel.java index 475d1ad60d7..cfa57a04ea7 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileItemDirectoryPanel.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileItemDirectoryPanel.java @@ -75,8 +75,6 @@ public AuthProfileItemDirectoryPanel( enableUtilityButton(); setFooterVisibility(false); - addNewItemPanelBuilder(new AuthProfileItemWizardBuilder(pageRef), true); - disableCheckBoxes(); initResultTable(); } @@ -90,9 +88,8 @@ public AuthProfileItemDirectoryPanel( @Override @SuppressWarnings("unchecked") public void onEvent(final IEvent event) { - if (event.getPayload() instanceof ExitEvent) { - AjaxRequestTarget target = ExitEvent.class.cast(event.getPayload()).getTarget(); - authProfileModal.close(target); + if (event.getPayload() instanceof ExitEvent exitEvent) { + authProfileModal.close(exitEvent.getTarget()); } else if (event.getPayload() instanceof final AjaxWizard.EditItemActionEvent payload) { payload.getTarget().ifPresent(actionTogglePanel::close); } @@ -194,12 +191,12 @@ protected Serializable onApplyInternal(final I modelObject) { List values = (List) wrapper.getPropertyValue("scratchCodes"); if (values != null) { List converted = values.stream().map(value -> { - if (value instanceof Integer) { - return Integer.class.cast(value); + if (value instanceof Integer integer) { + return integer; } - if (value instanceof String) { + if (value instanceof String string) { try { - return Integer.valueOf((String) value); + return Integer.valueOf(string); } catch (NumberFormatException e) { LOG.error("Could not convert to Integer: {}", value, e); } diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileWizardBuilder.java b/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileWizardBuilder.java index 08475c41109..41a5ff99586 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileWizardBuilder.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileWizardBuilder.java @@ -29,7 +29,7 @@ public abstract class AuthProfileWizardBuilder extends BaseAjaxWizardBuilder { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = -723891643398238220L; protected final StepModel model; @@ -46,7 +46,7 @@ protected WizardModel buildModelSteps(final T modelObject, final WizardModel wiz protected static class StepModel extends Model { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = -3300650579312254364L; private T initialModelObject; diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/rest/AuthProfileRestClient.java b/client/am/console/src/main/java/org/apache/syncope/client/console/rest/AuthProfileRestClient.java index d2b062bc114..d6801145edd 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/rest/AuthProfileRestClient.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/rest/AuthProfileRestClient.java @@ -38,10 +38,6 @@ public AuthProfileTO read(final String key) { return getService(AuthProfileService.class).read(key); } - public void create(final AuthProfileTO authProfile) { - getService(AuthProfileService.class).create(authProfile); - } - public void update(final AuthProfileTO authProfile) { getService(AuthProfileService.class).update(authProfile); } diff --git a/client/am/enduser/pom.xml b/client/am/enduser/pom.xml new file mode 100644 index 00000000000..2eb52d5089a --- /dev/null +++ b/client/am/enduser/pom.xml @@ -0,0 +1,84 @@ + + + + + 4.0.0 + + + org.apache.syncope.client + syncope-client-am + 4.0.0-SNAPSHOT + + + Apache Syncope Client AM Enduser + Apache Syncope Client AM Enduser + org.apache.syncope.client.am + syncope-client-am-enduser + jar + + + ${basedir}/../../.. + + + + + jakarta.servlet + jakarta.servlet-api + provided + + + + org.apache.syncope.client.idrepo + syncope-client-idrepo-enduser + ${project.version} + + + org.apache.syncope.client.am + syncope-client-am-lib + ${project.version} + + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + + + + src/main/resources + true + + org/apache/syncope/**/*.properties + + + + src/main/resources + false + + org/apache/syncope/**/*.properties + + + + + diff --git a/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/AMEnduserContext.java b/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/AMEnduserContext.java new file mode 100644 index 00000000000..3b840e520fd --- /dev/null +++ b/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/AMEnduserContext.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.enduser; + +import org.apache.syncope.client.enduser.rest.AuthProfileRestClient; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration(proxyBeanMethods = false) +public class AMEnduserContext { + + @ConditionalOnMissingBean + @Bean + public AuthProfileRestClient authProfileRestClient() { + return new AuthProfileRestClient(); + } +} diff --git a/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AuthProfile.java b/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AuthProfile.java new file mode 100644 index 00000000000..8a1a08a0209 --- /dev/null +++ b/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AuthProfile.java @@ -0,0 +1,221 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.enduser.pages; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import org.apache.syncope.client.enduser.rest.AuthProfileRestClient; +import org.apache.syncope.client.ui.commons.Constants; +import org.apache.syncope.client.ui.commons.annotations.ExtPage; +import org.apache.syncope.client.ui.commons.markup.html.form.IndicatingOnConfirmAjaxLink; +import org.apache.syncope.common.lib.to.AuthProfileTO; +import org.apache.syncope.common.lib.wa.GoogleMfaAuthAccount; +import org.apache.syncope.common.lib.wa.GoogleMfaAuthToken; +import org.apache.syncope.common.lib.wa.ImpersonationAccount; +import org.apache.syncope.common.lib.wa.MfaTrustedDevice; +import org.apache.syncope.common.lib.wa.WebAuthnDeviceCredential; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.navigation.paging.AjaxPagingNavigator; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.repeater.Item; +import org.apache.wicket.markup.repeater.data.DataView; +import org.apache.wicket.markup.repeater.data.ListDataProvider; +import org.apache.wicket.request.mapper.parameter.PageParameters; +import org.apache.wicket.spring.injection.annot.SpringBean; + +@ExtPage(label = "Auth Profile", icon = "fa fa-passport", listEntitlement = "") +public class AuthProfile extends BaseExtPage { + + private static final long serialVersionUID = -3147262161518280928L; + + protected static final String AUTH_PROFILE = "page.authProfile"; + + protected static final int ROWS_PER_PAGE = 5; + + @SpringBean + protected AuthProfileRestClient restClient; + + public AuthProfile(final PageParameters parameters) { + super(parameters, AUTH_PROFILE); + + Optional authProfile = restClient.read(); + + WebMarkupContainer container = new WebMarkupContainer("content"); + contentWrapper.add(container.setOutputMarkupId(true)); + + DataView impersonationAccounts = new DataView<>( + "impersonationAccounts", new ListDataProvider<>( + authProfile.map(AuthProfileTO::getImpersonationAccounts).orElseGet(() -> List.of()))) { + + private static final long serialVersionUID = 6127875313385810666L; + + @Override + public void populateItem(final Item item) { + item.add(new Label("impersonated", item.getModelObject().getImpersonated())); + item.add(new IndicatingOnConfirmAjaxLink<>( + "impersonationAccountDelete", Constants.CONFIRM_DELETE, true) { + + private static final long serialVersionUID = 1632838687547839512L; + + @Override + public void onClick(final AjaxRequestTarget target) { + authProfile.ifPresent(p -> { + p.getImpersonationAccounts().remove(item.getModelObject()); + restClient.update(p); + target.add(container); + }); + } + }); + } + }; + impersonationAccounts.setItemsPerPage(ROWS_PER_PAGE); + container.add(impersonationAccounts.setOutputMarkupPlaceholderTag(true)); + container.add(new AjaxPagingNavigator("impersonationAccountsNavigator", impersonationAccounts)); + + DataView googleMfaAuthTokens = new DataView<>( + "googleMfaAuthTokens", new ListDataProvider<>( + authProfile.map(AuthProfileTO::getGoogleMfaAuthTokens).orElseGet(() -> List.of()))) { + + private static final long serialVersionUID = 6127875313385810666L; + + @Override + public void populateItem(final Item item) { + item.add(new Label("otp", item.getModelObject().getOtp())); + item.add(new Label("issueDate", item.getModelObject().getIssueDate())); + item.add(new IndicatingOnConfirmAjaxLink<>( + "googleMfaAuthTokenDelete", Constants.CONFIRM_DELETE, true) { + + private static final long serialVersionUID = 1632838687547839512L; + + @Override + public void onClick(final AjaxRequestTarget target) { + authProfile.ifPresent(p -> { + p.getGoogleMfaAuthTokens().remove(item.getModelObject()); + restClient.update(p); + target.add(container); + }); + } + }); + } + }; + googleMfaAuthTokens.setItemsPerPage(ROWS_PER_PAGE); + container.add(googleMfaAuthTokens.setOutputMarkupPlaceholderTag(true)); + container.add(new AjaxPagingNavigator("googleMfaAuthTokensNavigator", googleMfaAuthTokens)); + + DataView googleMfaAuthAccounts = new DataView<>( + "googleMfaAuthAccounts", new ListDataProvider<>( + authProfile.map(AuthProfileTO::getGoogleMfaAuthAccounts).orElseGet(() -> List.of()))) { + + private static final long serialVersionUID = 6127875313385810666L; + + @Override + public void populateItem(final Item item) { + item.add(new Label("id", item.getModelObject().getId())); + item.add(new Label("name", item.getModelObject().getName())); + item.add(new Label("secretKey", item.getModelObject().getSecretKey())); + item.add(new Label("validationCode", item.getModelObject().getValidationCode())); + item.add(new Label("scratchCodes", item.getModelObject().getScratchCodes().stream(). + map(String::valueOf).collect(Collectors.joining(", ")))); + item.add(new Label("registrationDate", item.getModelObject().getRegistrationDate())); + item.add(new Label("source", item.getModelObject().getSource())); + item.add(new IndicatingOnConfirmAjaxLink<>( + "googleMfaAuthAccountDelete", Constants.CONFIRM_DELETE, true) { + + private static final long serialVersionUID = 1632838687547839512L; + + @Override + public void onClick(final AjaxRequestTarget target) { + authProfile.ifPresent(p -> { + p.getGoogleMfaAuthAccounts().remove(item.getModelObject()); + restClient.update(p); + target.add(container); + }); + } + }); + } + }; + googleMfaAuthAccounts.setItemsPerPage(ROWS_PER_PAGE); + container.add(googleMfaAuthAccounts.setOutputMarkupPlaceholderTag(true)); + container.add(new AjaxPagingNavigator("googleMfaAuthAccountsNavigator", googleMfaAuthAccounts)); + + DataView mfaTrustedDevices = new DataView<>( + "mfaTrustedDevices", new ListDataProvider<>( + authProfile.map(AuthProfileTO::getMfaTrustedDevices).orElseGet(() -> List.of()))) { + + private static final long serialVersionUID = 6127875313385810666L; + + @Override + public void populateItem(final Item item) { + item.add(new Label("id", item.getModelObject().getId())); + item.add(new Label("name", item.getModelObject().getName())); + item.add(new Label("deviceFingerprint", item.getModelObject().getDeviceFingerprint())); + item.add(new Label("recordDate", item.getModelObject().getRecordDate())); + item.add(new Label("expirationDate", item.getModelObject().getExpirationDate())); + item.add(new IndicatingOnConfirmAjaxLink<>( + "mfaTrustedDeviceDelete", Constants.CONFIRM_DELETE, true) { + + private static final long serialVersionUID = 1632838687547839512L; + + @Override + public void onClick(final AjaxRequestTarget target) { + authProfile.ifPresent(p -> { + p.getMfaTrustedDevices().remove(item.getModelObject()); + restClient.update(p); + target.add(container); + }); + } + }); + } + }; + mfaTrustedDevices.setItemsPerPage(ROWS_PER_PAGE); + container.add(mfaTrustedDevices.setOutputMarkupPlaceholderTag(true)); + container.add(new AjaxPagingNavigator("mfaTrustedDevicesNavigator", mfaTrustedDevices)); + + DataView webAuthnDeviceCredentials = new DataView<>( + "webAuthnDeviceCredentials", new ListDataProvider<>( + authProfile.map(AuthProfileTO::getWebAuthnDeviceCredentials).orElseGet(() -> List.of()))) { + + private static final long serialVersionUID = 6127875313385810666L; + + @Override + public void populateItem(final Item item) { + item.add(new Label("identifier", item.getModelObject().getIdentifier())); + item.add(new IndicatingOnConfirmAjaxLink<>( + "webAuthnDeviceCredentialDelete", Constants.CONFIRM_DELETE, true) { + + private static final long serialVersionUID = 1632838687547839512L; + + @Override + public void onClick(final AjaxRequestTarget target) { + authProfile.ifPresent(p -> { + p.getWebAuthnDeviceCredentials().remove(item.getModelObject()); + restClient.update(p); + target.add(container); + }); + } + }); + } + }; + webAuthnDeviceCredentials.setItemsPerPage(ROWS_PER_PAGE); + container.add(webAuthnDeviceCredentials.setOutputMarkupPlaceholderTag(true)); + container.add(new AjaxPagingNavigator("webAuthnDeviceCredentialsNavigator", webAuthnDeviceCredentials)); + } +} diff --git a/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/rest/AuthProfileRestClient.java b/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/rest/AuthProfileRestClient.java new file mode 100644 index 00000000000..413247746fa --- /dev/null +++ b/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/rest/AuthProfileRestClient.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.enduser.rest; + +import java.util.Optional; +import org.apache.syncope.common.lib.to.AuthProfileTO; +import org.apache.syncope.common.rest.api.service.AuthProfileSelfService; + +public class AuthProfileRestClient extends BaseRestClient { + + private static final long serialVersionUID = 4139153766778113329L; + + public Optional read() { + try { + return Optional.of(getService(AuthProfileSelfService.class).read()); + } catch (Exception e) { + LOG.debug("While attempting to read the auth profile", e); + return Optional.empty(); + } + } + + public void update(final AuthProfileTO authProfile) { + getService(AuthProfileSelfService.class).update(authProfile); + } + + public void delete() { + getService(AuthProfileSelfService.class).delete(); + } +} diff --git a/client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile.html b/client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile.html new file mode 100644 index 00000000000..fdbe3b190ab --- /dev/null +++ b/client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile.html @@ -0,0 +1,257 @@ + + + + +
+
+
+
+
+
+

+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + +
+ +
+ + + + + + +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + +
+ +
+ + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+ diff --git a/client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile.properties b/client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile.properties new file mode 100644 index 00000000000..5bf4119b60e --- /dev/null +++ b/client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile.properties @@ -0,0 +1,35 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +page.authProfile=Auth Profile +impersonation.accounts.title=Impersonation Accounts +google.mfa.authtokens.title=Google MFA Tokens +google.mfa.authaccounts.title=Google MFA Accounts +mfa.trusted.devices.title=MFA Trusted Devices +webauthn.device.credentials.title=WebAuthn Device Credentials +otp=OTP +issueDate=Issue Date +impersonated=Impersonated +id=Id +name=Name +secretKey=Secret Key +validationCode=Validation Code +scratchCodes=Scratch Codes +registrationDate=Registration Date +source=Source +deviceFingerprint=Fingerprint +recordDate=Record Date +expirationDate=Expiration Date diff --git a/client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile_it.properties b/client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile_it.properties new file mode 100644 index 00000000000..bb47fe6606f --- /dev/null +++ b/client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile_it.properties @@ -0,0 +1,35 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +page.authProfile=Auth Profile +impersonation.accounts.title=Account di impersonificazione +google.mfa.authtokens.title=Token MFA Google +google.mfa.authaccounts.title=Account MFA Google +mfa.trusted.devices.title=Dispositivi MFA +webauthn.device.credentials.title=Credenziali dispositivi WebAuthn +otp=OTP +issueDate=Data di emissione +impersonated=Impersonificato +id=Id +name=Nome +secretKey=Chiave segreta +validationCode=Codice di validazione +scratchCodes=Codici Scratch +registrationDate=Data di registrazione +source=Origine +deviceFingerprint=Fingerprint +recordDate=Data di registrazione +expirationDate=Data di scadenza diff --git a/client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile_ja.properties b/client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile_ja.properties new file mode 100644 index 00000000000..5bf4119b60e --- /dev/null +++ b/client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile_ja.properties @@ -0,0 +1,35 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +page.authProfile=Auth Profile +impersonation.accounts.title=Impersonation Accounts +google.mfa.authtokens.title=Google MFA Tokens +google.mfa.authaccounts.title=Google MFA Accounts +mfa.trusted.devices.title=MFA Trusted Devices +webauthn.device.credentials.title=WebAuthn Device Credentials +otp=OTP +issueDate=Issue Date +impersonated=Impersonated +id=Id +name=Name +secretKey=Secret Key +validationCode=Validation Code +scratchCodes=Scratch Codes +registrationDate=Registration Date +source=Source +deviceFingerprint=Fingerprint +recordDate=Record Date +expirationDate=Expiration Date diff --git a/client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile_pt_BR.properties b/client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile_pt_BR.properties new file mode 100644 index 00000000000..5bf4119b60e --- /dev/null +++ b/client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile_pt_BR.properties @@ -0,0 +1,35 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +page.authProfile=Auth Profile +impersonation.accounts.title=Impersonation Accounts +google.mfa.authtokens.title=Google MFA Tokens +google.mfa.authaccounts.title=Google MFA Accounts +mfa.trusted.devices.title=MFA Trusted Devices +webauthn.device.credentials.title=WebAuthn Device Credentials +otp=OTP +issueDate=Issue Date +impersonated=Impersonated +id=Id +name=Name +secretKey=Secret Key +validationCode=Validation Code +scratchCodes=Scratch Codes +registrationDate=Registration Date +source=Source +deviceFingerprint=Fingerprint +recordDate=Record Date +expirationDate=Expiration Date diff --git a/client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile_ru.properties b/client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile_ru.properties new file mode 100644 index 00000000000..5bf4119b60e --- /dev/null +++ b/client/am/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/AuthProfile_ru.properties @@ -0,0 +1,35 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +page.authProfile=Auth Profile +impersonation.accounts.title=Impersonation Accounts +google.mfa.authtokens.title=Google MFA Tokens +google.mfa.authaccounts.title=Google MFA Accounts +mfa.trusted.devices.title=MFA Trusted Devices +webauthn.device.credentials.title=WebAuthn Device Credentials +otp=OTP +issueDate=Issue Date +impersonated=Impersonated +id=Id +name=Name +secretKey=Secret Key +validationCode=Validation Code +scratchCodes=Scratch Codes +registrationDate=Registration Date +source=Source +deviceFingerprint=Fingerprint +recordDate=Record Date +expirationDate=Expiration Date diff --git a/client/am/pom.xml b/client/am/pom.xml index dfbac940de8..5fc1715969a 100644 --- a/client/am/pom.xml +++ b/client/am/pom.xml @@ -40,5 +40,6 @@ under the License. lib console + enduser diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java index ab8db42b800..22d07abea0d 100644 --- a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java +++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java @@ -35,12 +35,12 @@ import org.apache.syncope.client.console.tasks.PullTasks; import org.apache.syncope.client.console.tasks.PushTasks; import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal; -import org.apache.syncope.client.console.wicket.markup.html.form.IndicatingOnConfirmAjaxLink; import org.apache.syncope.client.console.wizards.resources.ConnectorWizardBuilder; import org.apache.syncope.client.console.wizards.resources.ResourceProvision; import org.apache.syncope.client.console.wizards.resources.ResourceProvisionPanel; import org.apache.syncope.client.console.wizards.resources.ResourceWizardBuilder; import org.apache.syncope.client.ui.commons.Constants; +import org.apache.syncope.client.ui.commons.markup.html.form.IndicatingOnConfirmAjaxLink; import org.apache.syncope.client.ui.commons.pages.BaseWebPage; import org.apache.syncope.client.ui.commons.wizards.AjaxWizard; import org.apache.syncope.common.lib.SyncopeClientException; diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ConfirmBehavior.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/ConfirmBehavior.java similarity index 93% rename from client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ConfirmBehavior.java rename to client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/ConfirmBehavior.java index c4f0218a57b..0a59c422af7 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ConfirmBehavior.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/ConfirmBehavior.java @@ -16,14 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.syncope.client.console.wicket.markup.html.form; +package org.apache.syncope.client.ui.commons.markup.html.form; import static de.agilecoders.wicket.jquery.JQuery.$; import de.agilecoders.wicket.jquery.function.JavaScriptInlineFunction; import java.util.ArrayList; -import org.apache.syncope.client.console.SyncopeConsoleSession; import org.apache.wicket.Component; +import org.apache.wicket.Session; import org.apache.wicket.behavior.Behavior; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.head.JavaScriptHeaderItem; @@ -63,7 +63,7 @@ public void renderHead(final Component component, final IHeaderResponse response + " className: 'btn-danger'" + " }" + "}," - + "locale: '" + SyncopeConsoleSession.get().getLocale().getLanguage() + "'," + + "locale: '" + Session.get().getLocale().getLanguage() + "'," + "callback: function(result) {" + " if (result == true) {" + " proceed = true;" diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/IndicatingOnConfirmAjaxLink.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/IndicatingOnConfirmAjaxLink.java similarity index 96% rename from client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/IndicatingOnConfirmAjaxLink.java rename to client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/IndicatingOnConfirmAjaxLink.java index d3ae2a383fb..8df5ef4adf0 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/IndicatingOnConfirmAjaxLink.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/markup/html/form/IndicatingOnConfirmAjaxLink.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.syncope.client.console.wicket.markup.html.form; +package org.apache.syncope.client.ui.commons.markup.html.form; import org.apache.syncope.client.ui.commons.Constants; import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink; diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java index d8386ad6933..8490ed6aeaf 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java @@ -31,10 +31,10 @@ import org.apache.syncope.client.console.panels.DelegationSelectionPanel; import org.apache.syncope.client.console.rest.SyncopeRestClient; import org.apache.syncope.client.console.wicket.markup.head.MetaHeaderItem; -import org.apache.syncope.client.console.wicket.markup.html.form.IndicatingOnConfirmAjaxLink; import org.apache.syncope.client.console.widgets.ExtAlertWidget; import org.apache.syncope.client.ui.commons.Constants; import org.apache.syncope.client.ui.commons.annotations.ExtPage; +import org.apache.syncope.client.ui.commons.markup.html.form.IndicatingOnConfirmAjaxLink; import org.apache.syncope.client.ui.commons.pages.BaseWebPage; import org.apache.syncope.common.lib.SyncopeConstants; import org.apache.syncope.common.lib.types.IdRepoEntitlement; diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DelegationSelectionPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DelegationSelectionPanel.java index 177430975ab..6bc123d6571 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DelegationSelectionPanel.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DelegationSelectionPanel.java @@ -20,7 +20,7 @@ import org.apache.syncope.client.console.SyncopeConsoleSession; import org.apache.syncope.client.console.pages.Dashboard; -import org.apache.syncope.client.console.wicket.markup.html.form.IndicatingOnConfirmAjaxLink; +import org.apache.syncope.client.ui.commons.markup.html.form.IndicatingOnConfirmAjaxLink; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.ComponentTag; import org.apache.wicket.markup.html.basic.Label; diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionPanel.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionPanel.java index 3a33c3bafa0..20bd29068a8 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionPanel.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionPanel.java @@ -25,6 +25,7 @@ import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink.ActionType; import org.apache.syncope.client.console.wicket.markup.html.link.VeilPopupSettings; import org.apache.syncope.client.ui.commons.Constants; +import org.apache.syncope.client.ui.commons.markup.html.form.IndicatingOnConfirmAjaxLink; import org.apache.wicket.AttributeModifier; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy; diff --git a/client/idrepo/enduser/pom.xml b/client/idrepo/enduser/pom.xml index 0585d5fb5ea..ec57bb935a9 100644 --- a/client/idrepo/enduser/pom.xml +++ b/client/idrepo/enduser/pom.xml @@ -294,6 +294,12 @@ under the License. ${project.version} + + org.apache.syncope.client.am + syncope-client-am-enduser + ${project.version} + + org.apache.syncope.ext.flowable syncope-ext-flowable-client-enduser diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/ChangePasswordPanel.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/ChangePasswordPanel.java index b9f5111f1e9..05482d42d02 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/ChangePasswordPanel.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/ChangePasswordPanel.java @@ -33,6 +33,7 @@ import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.form.AjaxButton; import org.apache.wicket.core.util.string.CssUtils; +import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.Button; import org.apache.wicket.markup.html.form.Form; @@ -68,7 +69,7 @@ public ChangePasswordPanel(final String id, final NotificationPanel notification private static final long serialVersionUID = 418292023846536149L; @Override - protected void appendDefaultButtonField() { + protected void addDefaultSubmitButtonHandler(final IHeaderResponse headerResponse) { AppendingStringBuffer buffer = new AppendingStringBuffer(); String cssClass = getString(CssUtils.key(Form.class, "hidden-fields")); diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/Sidebar.html b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/Sidebar.html index 6b62f0746ec..5aaf7de9654 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/Sidebar.html +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/Sidebar.html @@ -19,7 +19,7 @@ --> - - diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyObjectsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyObjectsITCase.java index a03979406dd..b10afdd8eec 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyObjectsITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/AnyObjectsITCase.java @@ -20,8 +20,8 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; -import org.apache.syncope.client.console.wicket.markup.html.form.IndicatingOnConfirmAjaxLink; import org.apache.syncope.client.ui.commons.Constants; +import org.apache.syncope.client.ui.commons.markup.html.form.IndicatingOnConfirmAjaxLink; import org.apache.wicket.Component; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.TextField; diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/GroupsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/GroupsITCase.java index b3e46d24a0b..b6c10c3efbe 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/GroupsITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/GroupsITCase.java @@ -22,8 +22,8 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import org.apache.commons.lang3.StringUtils; -import org.apache.syncope.client.console.wicket.markup.html.form.IndicatingOnConfirmAjaxLink; import org.apache.syncope.client.ui.commons.Constants; +import org.apache.syncope.client.ui.commons.markup.html.form.IndicatingOnConfirmAjaxLink; import org.apache.wicket.Component; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.TextField; diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java index d5824b1bd34..901ccbf10b5 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java @@ -23,8 +23,8 @@ import static org.junit.jupiter.api.Assertions.assertNull; import java.util.Calendar; -import org.apache.syncope.client.console.wicket.markup.html.form.IndicatingOnConfirmAjaxLink; import org.apache.syncope.client.ui.commons.Constants; +import org.apache.syncope.client.ui.commons.markup.html.form.IndicatingOnConfirmAjaxLink; import org.apache.wicket.Component; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.TextField; From 8e8241078d65f7092bc02160ccb66a9cf49c8c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Sat, 17 May 2025 09:11:06 +0200 Subject: [PATCH 053/579] [SYNCOPE-1866] Setting the new syncope-client-am-enduser module --- .../main/resources/archetype-resources/enduser/pom.xml | 4 ++-- archetype/src/main/resources/archetype-resources/pom.xml | 4 ++-- docker/enduser/pom.xml | 4 ++-- fit/core-reference/pom.xml | 8 ++++---- fit/enduser-reference/pom.xml | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/archetype/src/main/resources/archetype-resources/enduser/pom.xml b/archetype/src/main/resources/archetype-resources/enduser/pom.xml index 9acecc71fd1..7a977b3a31c 100644 --- a/archetype/src/main/resources/archetype-resources/enduser/pom.xml +++ b/archetype/src/main/resources/archetype-resources/enduser/pom.xml @@ -44,8 +44,8 @@ under the License. - org.apache.syncope.client.idrepo - syncope-client-idrepo-enduser + org.apache.syncope.client.am + syncope-client-am-enduser diff --git a/archetype/src/main/resources/archetype-resources/pom.xml b/archetype/src/main/resources/archetype-resources/pom.xml index ddbaf396583..25a71bc0e92 100644 --- a/archetype/src/main/resources/archetype-resources/pom.xml +++ b/archetype/src/main/resources/archetype-resources/pom.xml @@ -90,8 +90,8 @@ under the License. - org.apache.syncope.client.idrepo - syncope-client-idrepo-enduser + org.apache.syncope.client.am + syncope-client-am-enduser ${syncope.version} diff --git a/docker/enduser/pom.xml b/docker/enduser/pom.xml index 3d3681c60e1..0b97845ad1b 100644 --- a/docker/enduser/pom.xml +++ b/docker/enduser/pom.xml @@ -39,8 +39,8 @@ under the License. - org.apache.syncope.client.idrepo - syncope-client-idrepo-enduser + org.apache.syncope.client.am + syncope-client-am-enduser ${project.version} diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml index 00227f1455f..752681a4f17 100644 --- a/fit/core-reference/pom.xml +++ b/fit/core-reference/pom.xml @@ -109,8 +109,8 @@ under the License. test - org.apache.syncope.client.idrepo - syncope-client-idrepo-enduser + org.apache.syncope.client.am + syncope-client-am-enduser ${project.version} test @@ -1323,8 +1323,8 @@ under the License. - org.apache.syncope.client.idrepo - syncope-client-idrepo-enduser + org.apache.syncope.client.am + syncope-client-am-enduser ${project.version} diff --git a/fit/enduser-reference/pom.xml b/fit/enduser-reference/pom.xml index ae50c55e202..f262aefc05f 100644 --- a/fit/enduser-reference/pom.xml +++ b/fit/enduser-reference/pom.xml @@ -41,8 +41,8 @@ under the License. - org.apache.syncope.client.idrepo - syncope-client-idrepo-enduser + org.apache.syncope.client.am + syncope-client-am-enduser ${project.version} From cc9f4f61f76e41812eb0aa994c123a0745b52e77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Mon, 19 May 2025 13:47:10 +0200 Subject: [PATCH 054/579] [SYNCOPE-1884] Handling Encrypted plain values during propagation --- .../java/DefaultMappingManager.java | 56 +++++++++++++++---- .../syncope/fit/core/UserIssuesITCase.java | 9 +-- 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java index 222fff943e5..813861b37fb 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java @@ -528,7 +528,17 @@ public Pair prepareAttr( List objValues = new ArrayList<>(); for (PlainAttrValue value : values) { - if (FrameworkUtil.isSupportedAttributeType(schemaType.getType())) { + if (intAttrName.getSchema() instanceof PlainSchema schema && schemaType == AttrSchemaType.Encrypted) { + String decoded = null; + try { + decoded = encryptorManager.getInstance(schema.getSecretKey()). + decode(value.getStringValue(), schema.getCipherAlgorithm()); + } catch (Exception e) { + LOG.warn("Could not decode value for {} with algorithm", + intAttrName.getSchema(), schema.getCipherAlgorithm(), e); + } + objValues.add(Optional.ofNullable(decoded).orElse(value.getStringValue())); + } else if (FrameworkUtil.isSupportedAttributeType(schemaType.getType())) { objValues.add(value.getValue()); } else { PlainSchema plainSchema = intAttrName.getSchema() instanceof final PlainSchema schema @@ -545,15 +555,23 @@ public Pair prepareAttr( Pair result; if (item.isConnObjectKey()) { result = Pair.of(objValues.isEmpty() ? null : objValues.getFirst().toString(), null); - } else if (item.isPassword() && any instanceof User) { - result = getPasswordAttrValue(passwordAccountGetter.apply((User) any), password). + } else if (item.isPassword() && any instanceof User user) { + result = getPasswordAttrValue(passwordAccountGetter.apply(user), password). map(passwordAttrValue -> Pair.of( (String) null, AttributeBuilder.buildPassword(passwordAttrValue.toCharArray()))). orElse(null); + } else if (objValues.isEmpty()) { + result = Pair.of( + null, + AttributeBuilder.build(item.getExtAttrName())); + } else if (OperationalAttributes.PASSWORD_NAME.equals(item.getExtAttrName())) { + result = Pair.of( + null, + AttributeBuilder.buildPassword(objValues.getFirst().toString().toCharArray())); } else { - result = Pair.of(null, objValues.isEmpty() - ? AttributeBuilder.build(item.getExtAttrName()) - : AttributeBuilder.build(item.getExtAttrName(), objValues)); + result = Pair.of( + null, + AttributeBuilder.build(item.getExtAttrName(), objValues)); } return result; @@ -595,7 +613,17 @@ public Pair prepareAttr( List objValues = new ArrayList<>(); for (PlainAttrValue value : values) { - if (FrameworkUtil.isSupportedAttributeType(schemaType.getType())) { + if (intAttrName.getSchema() instanceof PlainSchema schema && schemaType == AttrSchemaType.Encrypted) { + String decoded = null; + try { + decoded = encryptorManager.getInstance(schema.getSecretKey()). + decode(value.getStringValue(), schema.getCipherAlgorithm()); + } catch (Exception e) { + LOG.warn("Could not decode value for {} with algorithm", + intAttrName.getSchema(), schema.getCipherAlgorithm(), e); + } + objValues.add(Optional.ofNullable(decoded).orElse(value.getStringValue())); + } else if (FrameworkUtil.isSupportedAttributeType(schemaType.getType())) { objValues.add(value.getValue()); } else { PlainSchema plainSchema = intAttrName.getSchema() instanceof final PlainSchema schema @@ -612,10 +640,18 @@ public Pair prepareAttr( Pair result; if (item.isConnObjectKey()) { result = Pair.of(objValues.isEmpty() ? null : objValues.getFirst().toString(), null); + } else if (objValues.isEmpty()) { + result = Pair.of( + null, + AttributeBuilder.build(item.getExtAttrName())); + } else if (OperationalAttributes.PASSWORD_NAME.equals(item.getExtAttrName())) { + result = Pair.of( + null, + AttributeBuilder.buildPassword(objValues.iterator().next().toString().toCharArray())); } else { - result = Pair.of(null, objValues.isEmpty() - ? AttributeBuilder.build(item.getExtAttrName()) - : AttributeBuilder.build(item.getExtAttrName(), objValues)); + result = Pair.of( + null, + AttributeBuilder.build(item.getExtAttrName(), objValues)); } return result; diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java index 9765a45e485..a005e94de19 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java @@ -38,7 +38,6 @@ import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Set; import java.util.UUID; import java.util.concurrent.TimeUnit; @@ -681,7 +680,7 @@ public void issueSYNCOPE357() throws IOException { // 1. create group with LDAP resource GroupCR groupCR = new GroupCR(); groupCR.setName("SYNCOPE357-" + getUUIDString()); - groupCR.setRealm("/"); + groupCR.setRealm(SyncopeConstants.ROOT_REALM); groupCR.getResources().add(RESOURCE_NAME_LDAP); GroupTO groupTO = createGroup(groupCR).getEntity(); @@ -704,13 +703,11 @@ public void issueSYNCOPE357() throws IOException { RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey()); assertNotNull(connObj); Attr registeredAddress = connObj.getAttr("registeredAddress").orElseThrow(); - assertNotNull(registeredAddress); assertEquals(userTO.getPlainAttr("obscure").orElseThrow().getValues(), registeredAddress.getValues()); - Optional jpegPhoto = connObj.getAttr("jpegPhoto"); - assertTrue(jpegPhoto.isPresent()); + Attr jpegPhoto = connObj.getAttr("jpegPhoto").orElseThrow(); assertEquals( userTO.getPlainAttr("photo").orElseThrow().getValues().getFirst(), - jpegPhoto.orElseThrow().getValues().getFirst()); + jpegPhoto.getValues().getFirst()); // 4. remove group GROUP_SERVICE.delete(groupTO.getKey()); From 5e72cc39dc70e35abd20d8dfb550d0c5d88385bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Tue, 20 May 2025 08:10:25 +0200 Subject: [PATCH 055/579] Upgrading OpenJPA --- .../syncope/core/provisioning/java/DefaultMappingManager.java | 4 ++-- pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java index 813861b37fb..6a47dd04af2 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultMappingManager.java @@ -534,7 +534,7 @@ public Pair prepareAttr( decoded = encryptorManager.getInstance(schema.getSecretKey()). decode(value.getStringValue(), schema.getCipherAlgorithm()); } catch (Exception e) { - LOG.warn("Could not decode value for {} with algorithm", + LOG.warn("Could not decode value for {} with algorithm {}", intAttrName.getSchema(), schema.getCipherAlgorithm(), e); } objValues.add(Optional.ofNullable(decoded).orElse(value.getStringValue())); @@ -619,7 +619,7 @@ public Pair prepareAttr( decoded = encryptorManager.getInstance(schema.getSecretKey()). decode(value.getStringValue(), schema.getCipherAlgorithm()); } catch (Exception e) { - LOG.warn("Could not decode value for {} with algorithm", + LOG.warn("Could not decode value for {} with algorithm {}", intAttrName.getSchema(), schema.getCipherAlgorithm(), e); } objValues.add(Optional.ofNullable(decoded).orElse(value.getStringValue())); diff --git a/pom.xml b/pom.xml index 236f8f95e89..1f8b93062c7 100644 --- a/pom.xml +++ b/pom.xml @@ -418,7 +418,7 @@ under the License. 3.4.5 4.2.1 - 4.1.0 + 4.1.1 1.9.3 From ab6e3256c9e0e14cf9b0466214f755ea9fda0b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Tue, 20 May 2025 17:18:51 +0200 Subject: [PATCH 056/579] [SYNCOPE-1885] Enabling password reset notifications for DefaultUserWorkflowAdapter (#1085) --- archetype/pom.xml | 2 +- .../DefaultNotificationManager.java | 20 ++-- .../workflow/api/UserWorkflowAdapter.java | 4 + .../java/DefaultUserWorkflowAdapter.java | 30 +++++- .../core/workflow/java/WorkflowContext.java | 7 +- .../workflow/java/WorkflowTestContext.java | 12 ++- .../impl/FlowableUserWorkflowAdapter.java | 8 +- .../apache/syncope/fit/AbstractITCase.java | 60 ++++++++++++ .../core/AbstractNotificationTaskITCase.java | 93 ------------------- .../fit/core/NotificationTaskITCase.java | 9 +- .../apache/syncope/fit/core/SCIMITCase.java | 2 +- .../syncope/fit/core/UserSelfITCase.java | 31 ++++++- 12 files changed, 155 insertions(+), 123 deletions(-) delete mode 100644 fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractNotificationTaskITCase.java diff --git a/archetype/pom.xml b/archetype/pom.xml index 5ff22d221fa..823c663de42 100644 --- a/archetype/pom.xml +++ b/archetype/pom.xml @@ -34,7 +34,7 @@ under the License. maven-archetype - 3.3.1 + 3.4.0 ${basedir}/.. diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManager.java index 953f98af747..0ceaa46fe76 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManager.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/DefaultNotificationManager.java @@ -282,30 +282,22 @@ public List createTasks( any = userDAO.findById(userTO.getKey()); } else if (output instanceof UserTO userTO) { any = userDAO.findById(userTO.getKey()); - } else if (output instanceof final Pair pair - && pair.getRight() instanceof final UserTO userTO) { - + } else if (output instanceof final Pair pair && pair.getRight() instanceof final UserTO userTO) { any = userDAO.findById(userTO.getKey()); - } else if (output instanceof final ProvisioningResult provisioningResult1 - && provisioningResult1.getEntity() instanceof UserTO) { - - any = userDAO.findById(provisioningResult1.getEntity().getKey()); + } else if (output instanceof final ProvisioningResult result && result.getEntity() instanceof UserTO) { + any = userDAO.findById(result.getEntity().getKey()); } else if (before instanceof AnyObjectTO anyObjectTO) { any = anyObjectDAO.findById(anyObjectTO.getKey()); } else if (output instanceof AnyObjectTO anyObjectTO) { any = anyObjectDAO.findById(anyObjectTO.getKey()); - } else if (output instanceof final ProvisioningResult result - && result.getEntity() instanceof AnyObjectTO) { - + } else if (output instanceof final ProvisioningResult result && result.getEntity() instanceof AnyObjectTO) { any = anyObjectDAO.findById(result.getEntity().getKey()); } else if (before instanceof GroupTO groupTO) { any = groupDAO.findById(groupTO.getKey()); } else if (output instanceof GroupTO groupTO) { any = groupDAO.findById(groupTO.getKey()); - } else if (output instanceof final ProvisioningResult provisioningResult - && provisioningResult.getEntity() instanceof GroupTO) { - - any = groupDAO.findById(provisioningResult.getEntity().getKey()); + } else if (output instanceof final ProvisioningResult result && result.getEntity() instanceof GroupTO) { + any = groupDAO.findById(result.getEntity().getKey()); } AnyType anyType = any.map(Any::getType).orElse(null); diff --git a/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java b/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java index 13a9d3ebf70..288d61e1dc4 100644 --- a/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java +++ b/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/UserWorkflowAdapter.java @@ -28,6 +28,10 @@ */ public interface UserWorkflowAdapter extends WorkflowAdapter { + String REQUEST_PASSWORD_RESET = "requestPasswordReset"; + + String CONFIRM_PASSWORD_RESET = "confirmPasswordReset"; + /** * Create an user. * diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java index e70bc198bf7..6bc00db8353 100644 --- a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java +++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java @@ -23,6 +23,7 @@ import org.apache.syncope.common.lib.request.PasswordPatch; import org.apache.syncope.common.lib.request.UserCR; import org.apache.syncope.common.lib.request.UserUR; +import org.apache.syncope.common.lib.types.OpEvent; import org.apache.syncope.common.lib.types.ResourceOperation; import org.apache.syncope.core.persistence.api.EncryptorManager; import org.apache.syncope.core.persistence.api.dao.GroupDAO; @@ -34,6 +35,7 @@ import org.apache.syncope.core.provisioning.api.UserWorkflowResult; import org.apache.syncope.core.provisioning.api.data.UserDataBinder; import org.apache.syncope.core.provisioning.api.event.EntityLifecycleEvent; +import org.apache.syncope.core.provisioning.api.notification.NotificationManager; import org.apache.syncope.core.provisioning.api.rules.RuleProvider; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.core.spring.security.SecurityProperties; @@ -48,6 +50,8 @@ public class DefaultUserWorkflowAdapter extends AbstractUserWorkflowAdapter { protected final ConfParamOps confParamOps; + protected final NotificationManager notificationManager; + public DefaultUserWorkflowAdapter( final UserDataBinder dataBinder, final UserDAO userDAO, @@ -58,7 +62,8 @@ public DefaultUserWorkflowAdapter( final RuleProvider ruleProvider, final ConfParamOps confParamOps, final ApplicationEventPublisher publisher, - final EncryptorManager encryptorManager) { + final EncryptorManager encryptorManager, + final NotificationManager notificationManager) { super( dataBinder, @@ -71,6 +76,7 @@ public DefaultUserWorkflowAdapter( publisher, encryptorManager); this.confParamOps = confParamOps; + this.notificationManager = notificationManager; } @Override @@ -187,6 +193,18 @@ protected void doRequestPasswordReset(final User user, final String updater, fin user.generateToken( confParamOps.get(AuthContextUtils.getDomain(), "token.length", 256, Integer.class), confParamOps.get(AuthContextUtils.getDomain(), "token.expireTime", 60, Integer.class)); + + notificationManager.createTasks( + updater, + OpEvent.CategoryType.CUSTOM, + null, + null, + REQUEST_PASSWORD_RESET, + OpEvent.Outcome.SUCCESS, + dataBinder.getUserTO(user, true), + null, + user.getToken()); + metadata(user, updater, context); User updated = userDAO.save(user); @@ -204,6 +222,16 @@ protected UserWorkflowResult> doConfirmPasswordReset( user.removeToken(); + notificationManager.createTasks( + updater, + OpEvent.CategoryType.CUSTOM, + null, + null, + CONFIRM_PASSWORD_RESET, + OpEvent.Outcome.SUCCESS, + dataBinder.getUserTO(user, true), + null); + UserUR userUR = new UserUR(); userUR.setKey(user.getKey()); userUR.setPassword(new PasswordPatch.Builder(). diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/WorkflowContext.java b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/WorkflowContext.java index 692dbcbd9e5..dfdad122c69 100644 --- a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/WorkflowContext.java +++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/WorkflowContext.java @@ -28,6 +28,7 @@ import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder; import org.apache.syncope.core.provisioning.api.data.GroupDataBinder; import org.apache.syncope.core.provisioning.api.data.UserDataBinder; +import org.apache.syncope.core.provisioning.api.notification.NotificationManager; import org.apache.syncope.core.provisioning.api.rules.RuleProvider; import org.apache.syncope.core.spring.security.SecurityProperties; import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter; @@ -53,7 +54,8 @@ public UserWorkflowAdapter uwfAdapter( final RuleProvider ruleProvider, final ConfParamOps confParamOps, final ApplicationEventPublisher publisher, - final EncryptorManager encryptorManager) { + final EncryptorManager encryptorManager, + final NotificationManager notificationManager) { return new DefaultUserWorkflowAdapter( userDataBinder, @@ -65,7 +67,8 @@ public UserWorkflowAdapter uwfAdapter( ruleProvider, confParamOps, publisher, - encryptorManager); + encryptorManager, + notificationManager); } @ConditionalOnMissingBean diff --git a/core/workflow-java/src/test/java/org/apache/syncope/core/workflow/java/WorkflowTestContext.java b/core/workflow-java/src/test/java/org/apache/syncope/core/workflow/java/WorkflowTestContext.java index 93df7c1b7a3..6f16ea8120e 100644 --- a/core/workflow-java/src/test/java/org/apache/syncope/core/workflow/java/WorkflowTestContext.java +++ b/core/workflow-java/src/test/java/org/apache/syncope/core/workflow/java/WorkflowTestContext.java @@ -42,6 +42,7 @@ import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder; import org.apache.syncope.core.provisioning.api.data.GroupDataBinder; import org.apache.syncope.core.provisioning.api.data.UserDataBinder; +import org.apache.syncope.core.provisioning.api.notification.NotificationManager; import org.apache.syncope.core.spring.security.SecurityContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; @@ -94,14 +95,12 @@ public UserDataBinder userDataBinder(final RealmSearchDAO realmSearchDAO) { @Bean public GroupDataBinder groupDataBinder() { - GroupDataBinder dataBinder = mock(GroupDataBinder.class); - return dataBinder; + return mock(GroupDataBinder.class); } @Bean public AnyObjectDataBinder anyObjectDataBinder() { - AnyObjectDataBinder dataBinder = mock(AnyObjectDataBinder.class); - return dataBinder; + return mock(AnyObjectDataBinder.class); } @Bean @@ -118,4 +117,9 @@ public ConfParamOps confParamOps() { public DomainOps domainOps(final DomainRegistry domainRegistry) { return new DummyDomainOps(domainRegistry); } + + @Bean + public NotificationManager notificationManager() { + return mock(NotificationManager.class); + } } diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserWorkflowAdapter.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserWorkflowAdapter.java index 5429541d3b5..eee1c2cabe5 100644 --- a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserWorkflowAdapter.java +++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserWorkflowAdapter.java @@ -417,8 +417,8 @@ protected UserWorkflowResult doReactivate(final User user, final String protected void doRequestPasswordReset(final User user, final String updater, final String context) { Map variables = new HashMap<>(3); variables.put(FlowableRuntimeUtils.USER_TO, dataBinder.getUserTO(user, true)); - variables.put(FlowableRuntimeUtils.TASK, "requestPasswordReset"); - variables.put(FlowableRuntimeUtils.EVENT, "requestPasswordReset"); + variables.put(FlowableRuntimeUtils.TASK, REQUEST_PASSWORD_RESET); + variables.put(FlowableRuntimeUtils.EVENT, REQUEST_PASSWORD_RESET); String procInstID = FlowableRuntimeUtils.getWFProcInstID(engine, user.getKey()); @@ -443,8 +443,8 @@ protected UserWorkflowResult> doConfirmPasswordReset( variables.put(FlowableRuntimeUtils.TOKEN, token); variables.put(FlowableRuntimeUtils.PASSWORD, password); variables.put(FlowableRuntimeUtils.USER_TO, dataBinder.getUserTO(user, true)); - variables.put(FlowableRuntimeUtils.TASK, "confirmPasswordReset"); - variables.put(FlowableRuntimeUtils.EVENT, "confirmPasswordReset"); + variables.put(FlowableRuntimeUtils.TASK, CONFIRM_PASSWORD_RESET); + variables.put(FlowableRuntimeUtils.EVENT, CONFIRM_PASSWORD_RESET); String procInstID = FlowableRuntimeUtils.getWFProcInstID(engine, user.getKey()); diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java index 5813a6d0dc4..b1412cf586f 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java @@ -37,6 +37,11 @@ import com.unboundid.ldap.sdk.SearchResult; import com.unboundid.ldap.sdk.SearchResultEntry; import com.unboundid.ldap.sdk.SearchScope; +import jakarta.mail.Flags; +import jakarta.mail.Folder; +import jakarta.mail.Message; +import jakarta.mail.Session; +import jakarta.mail.Store; import jakarta.ws.rs.core.GenericType; import jakarta.ws.rs.core.HttpHeaders; import jakarta.ws.rs.core.MediaType; @@ -393,6 +398,10 @@ public void initialize(final ConfigurableApplicationContext ctx) { protected static ImpersonationService IMPERSONATION_SERVICE; + private static final String POP3_HOST = "localhost"; + + private static int POP3_PORT; + protected static boolean IS_FLOWABLE_ENABLED = false; protected static boolean IS_ELASTICSEARCH_ENABLED = false; @@ -524,6 +533,19 @@ public static void anonymousSetup() throws IOException { } } + @BeforeAll + public static void conf() { + Properties props = new Properties(); + try (InputStream propStream = AbstractITCase.class.getResourceAsStream("/test.properties")) { + props.load(propStream); + } catch (Exception e) { + LOG.error("Could not load /test.properties", e); + } + + POP3_PORT = Integer.parseInt(props.getProperty("testmail.pop3port")); + assertNotNull(POP3_PORT); + } + @BeforeAll public static void restSetup() { CLIENT_FACTORY = new SyncopeClientFactoryBean().setAddress(ADDRESS); @@ -1082,6 +1104,44 @@ protected static Optional getRealm(final String fullPath) { filter(realm -> fullPath.equals(realm.getFullPath())).findFirst(); } + private static boolean pop3(final String sender, final String subject, final String mailAddress) throws Exception { + boolean found = false; + try (Store store = Session.getDefaultInstance(System.getProperties()).getStore("pop3")) { + store.connect(POP3_HOST, POP3_PORT, mailAddress, mailAddress); + + Folder inbox = store.getFolder("INBOX"); + assertNotNull(inbox); + inbox.open(Folder.READ_WRITE); + + for (Message message : inbox.getMessages()) { + if (sender.equals(message.getFrom()[0].toString()) && subject.equals(message.getSubject())) { + found = true; + message.setFlag(Flags.Flag.DELETED, true); + } + } + + inbox.close(true); + } + return found; + } + + protected static void verifyMail( + final String sender, + final String subject, + final String mailAddress, + final int maxWaitSeconds) throws Exception { + + Mutable read = new MutableObject<>(false); + await().atMost(maxWaitSeconds, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> { + try { + read.setValue(pop3(sender, subject, mailAddress)); + return read.getValue(); + } catch (Exception e) { + return false; + } + }); + } + @Autowired protected ConfParamOps confParamOps; diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractNotificationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractNotificationTaskITCase.java deleted file mode 100644 index f9fd733b8db..00000000000 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractNotificationTaskITCase.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.fit.core; - -import static org.awaitility.Awaitility.await; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import jakarta.mail.Flags; -import jakarta.mail.Folder; -import jakarta.mail.Message; -import jakarta.mail.Session; -import jakarta.mail.Store; -import java.io.InputStream; -import java.util.Properties; -import java.util.concurrent.TimeUnit; -import org.apache.commons.lang3.mutable.Mutable; -import org.apache.commons.lang3.mutable.MutableObject; -import org.junit.jupiter.api.BeforeAll; - -public abstract class AbstractNotificationTaskITCase extends AbstractTaskITCase { - - private static final String POP3_HOST = "localhost"; - - private static int POP3_PORT; - - @BeforeAll - public static void conf() { - Properties props = new Properties(); - try (InputStream propStream = AbstractNotificationTaskITCase.class.getResourceAsStream("/test.properties")) { - props.load(propStream); - } catch (Exception e) { - LOG.error("Could not load /test.properties", e); - } - - POP3_PORT = Integer.parseInt(props.getProperty("testmail.pop3port")); - assertNotNull(POP3_PORT); - } - - private static boolean pop3(final String sender, final String subject, final String mailAddress) throws Exception { - boolean found = false; - try (Store store = Session.getDefaultInstance(System.getProperties()).getStore("pop3")) { - store.connect(POP3_HOST, POP3_PORT, mailAddress, mailAddress); - - Folder inbox = store.getFolder("INBOX"); - assertNotNull(inbox); - inbox.open(Folder.READ_WRITE); - - Message[] messages = inbox.getMessages(); - for (Message message : messages) { - if (sender.equals(message.getFrom()[0].toString()) && subject.equals(message.getSubject())) { - found = true; - message.setFlag(Flags.Flag.DELETED, true); - } - } - - inbox.close(true); - } - return found; - } - - protected static void verifyMail( - final String sender, - final String subject, - final String mailAddress, - final int maxWaitSeconds) throws Exception { - - Mutable read = new MutableObject<>(false); - await().atMost(maxWaitSeconds, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> { - try { - read.setValue(pop3(sender, subject, mailAddress)); - return read.getValue(); - } catch (Exception e) { - return false; - } - }); - } -} diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java index 4637d8a806b..05ddbae7c02 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java @@ -49,7 +49,7 @@ import org.apache.syncope.fit.core.reference.TestNotificationRecipientsProvider; import org.junit.jupiter.api.Test; -public class NotificationTaskITCase extends AbstractNotificationTaskITCase { +public class NotificationTaskITCase extends AbstractTaskITCase { @Test public void notifyByMail() throws Exception { @@ -109,7 +109,12 @@ public void notifyByMailWithRetry() throws Exception { int preExecs = taskTO.getExecutions().size(); // 4. verify notification could not be delivered - execTask(TASK_SERVICE, TaskType.NOTIFICATION, taskTO.getKey(), NotificationJob.Status.NOT_SENT.name(), 5, + execTask( + TASK_SERVICE, + TaskType.NOTIFICATION, + taskTO.getKey(), + NotificationJob.Status.NOT_SENT.name(), + 5, false); taskTO = TASK_SERVICE.read(TaskType.NOTIFICATION, taskTO.getKey(), true); diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SCIMITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SCIMITCase.java index 27ed44eaa82..999b2c8dc37 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SCIMITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SCIMITCase.java @@ -285,7 +285,7 @@ public void read() throws IOException { } @Test - public void conf() { + public void scimConf() { SCIMConf conf = SCIM_CONF_SERVICE.get(); assertNotNull(conf); diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java index f14f79aacdf..f6f944796f4 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java @@ -50,6 +50,7 @@ import org.apache.syncope.common.lib.request.UserCR; import org.apache.syncope.common.lib.request.UserUR; import org.apache.syncope.common.lib.to.MembershipTO; +import org.apache.syncope.common.lib.to.NotificationTaskTO; import org.apache.syncope.common.lib.to.PagedResult; import org.apache.syncope.common.lib.to.ProvisioningResult; import org.apache.syncope.common.lib.to.UserRequestForm; @@ -58,6 +59,9 @@ import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.ClientExceptionType; import org.apache.syncope.common.lib.types.PatchOperation; +import org.apache.syncope.common.lib.types.TaskType; +import org.apache.syncope.common.rest.api.beans.ExecSpecs; +import org.apache.syncope.common.rest.api.beans.TaskQuery; import org.apache.syncope.common.rest.api.beans.UserRequestQuery; import org.apache.syncope.common.rest.api.service.AccessTokenService; import org.apache.syncope.common.rest.api.service.UserRequestService; @@ -70,6 +74,22 @@ public class UserSelfITCase extends AbstractITCase { + private static void checkNotification( + final String email, + final String notification, + final String subject) throws Exception { + + await().atMost(MAX_WAIT_SECONDS, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> { + PagedResult tasks = TASK_SERVICE.search(new TaskQuery.Builder(TaskType.NOTIFICATION). + notification(notification).build()); + return tasks.getResult().stream().filter(t -> t.getRecipients().contains(email) && !t.isExecuted()). + findFirst().map(t -> TASK_SERVICE.execute( + new ExecSpecs.Builder().key(t.getKey()).build()).getStatus() != null). + orElse(false); + }); + verifyMail("admin@syncope.apache.org", subject, email, MAX_WAIT_SECONDS); + } + @Test public void selfRegistrationAllowed() { assertTrue(ANONYMOUS_CLIENT.platform().isSelfRegAllowed()); @@ -304,7 +324,7 @@ public void delete() { } @Test - public void passwordReset() { + public void passwordReset() throws Exception { // 0. ensure that password request DOES require security question confParamOps.set(SyncopeConstants.MASTER_DOMAIN, "passwordReset.securityQuestion", true); @@ -344,6 +364,11 @@ public void passwordReset() { } // 4. get token (normally sent via e-mail, now reading as admin) + String email = user.getPlainAttr("email").orElseThrow().getValues().getFirst(); + if (!IS_NEO4J_PERSISTENCE) { + checkNotification(email, "e00945b5-1184-4d43-8e45-4318a8dcdfd4", "Password Reset request"); + } + String token = await().atMost(MAX_WAIT_SECONDS, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until( () -> USER_SERVICE.read(read.getKey()).getToken(), StringUtils::isNotBlank); @@ -358,6 +383,10 @@ public void passwordReset() { } ANONYMOUS_CLIENT.getService(UserSelfService.class).confirmPasswordReset(token, "newPassword123"); + if (!IS_NEO4J_PERSISTENCE) { + checkNotification(email, "bef0c250-e8a7-4848-bb63-2564fc409ce2", "Password Reset successful"); + } + // 6. verify that password was reset and token removed authClient = CLIENT_FACTORY.create(user.getUsername(), "newPassword123"); assertNull(authClient.self().getRight().getToken()); From 81638a53e3809a7c907fc3476803bd75bbc23f20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Wed, 21 May 2025 15:17:18 +0200 Subject: [PATCH 057/579] Improving Enduser UI for User Request management --- .../html/form/BpmnProcessesAjaxPanel.java | 42 ----------- .../client/enduser/pages/Flowable.java | 71 +++++++++---------- .../enduser/panels/UserRequestDetails.java | 13 ++-- .../enduser/rest/UserRequestRestClient.java | 35 ++++----- .../client/enduser/pages/Flowable.properties | 3 +- .../enduser/pages/Flowable_it.properties | 3 +- .../enduser/pages/Flowable_ja.properties | 1 + .../enduser/pages/Flowable_pt_BR.properties | 3 +- .../enduser/pages/Flowable_ru.properties | 1 + .../enduser/panels/UserRequestDetails.html | 23 +++++- 10 files changed, 83 insertions(+), 112 deletions(-) delete mode 100644 ext/flowable/client-enduser/src/main/java/org/apache/syncope/client/enduser/markup/html/form/BpmnProcessesAjaxPanel.java diff --git a/ext/flowable/client-enduser/src/main/java/org/apache/syncope/client/enduser/markup/html/form/BpmnProcessesAjaxPanel.java b/ext/flowable/client-enduser/src/main/java/org/apache/syncope/client/enduser/markup/html/form/BpmnProcessesAjaxPanel.java deleted file mode 100644 index 41b72835af8..00000000000 --- a/ext/flowable/client-enduser/src/main/java/org/apache/syncope/client/enduser/markup/html/form/BpmnProcessesAjaxPanel.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.client.enduser.markup.html.form; - -import java.util.Optional; -import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel; -import org.apache.wicket.behavior.Behavior; -import org.apache.wicket.model.IModel; - -public class BpmnProcessesAjaxPanel extends AjaxTextFieldPanel { - - private static final long serialVersionUID = 9082907182704884397L; - - public BpmnProcessesAjaxPanel( - final String id, final String name, final IModel model) { - - this(id, name, model, null); - } - - public BpmnProcessesAjaxPanel( - final String id, final String name, final IModel model, final Behavior behavior) { - - super(id, name, model, false); - Optional.ofNullable(behavior).ifPresent(field::add); - } -} diff --git a/ext/flowable/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/Flowable.java b/ext/flowable/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/Flowable.java index 5b99ee44baa..30d9cd28279 100644 --- a/ext/flowable/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/Flowable.java +++ b/ext/flowable/client-enduser/src/main/java/org/apache/syncope/client/enduser/pages/Flowable.java @@ -23,13 +23,13 @@ import java.util.function.Predicate; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.client.enduser.SyncopeEnduserSession; -import org.apache.syncope.client.enduser.markup.html.form.BpmnProcessesAjaxPanel; import org.apache.syncope.client.enduser.panels.UserRequestDetails; import org.apache.syncope.client.enduser.rest.BpmnProcessRestClient; import org.apache.syncope.client.enduser.rest.UserRequestRestClient; import org.apache.syncope.client.ui.commons.Constants; import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior; import org.apache.syncope.client.ui.commons.annotations.ExtPage; +import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel; import org.apache.syncope.client.ui.commons.wicket.markup.html.bootstrap.tabs.Accordion; import org.apache.syncope.common.lib.to.BpmnProcess; import org.apache.syncope.common.lib.to.UserRequest; @@ -69,33 +69,6 @@ public Flowable(final PageParameters parameters) { WebMarkupContainer container = new WebMarkupContainer("content"); contentWrapper.add(container.setOutputMarkupId(true)); - // list of accordions containing request form (if any) and delete button - DataView urDataView = new DataView<>( - "userRequests", new URDataProvider(ROWS_PER_PAGE, "bpmnProcess")) { - - private static final long serialVersionUID = -5002600396458362774L; - - @Override - protected void populateItem(final Item item) { - UserRequest userRequest = item.getModelObject(); - item.add(new Accordion("userRequestDetails", List.of(new AbstractTab( - new StringResourceModel("user.requests.accordion", container, Model.of(userRequest))) { - - private static final long serialVersionUID = 1037272333056449378L; - - @Override - public WebMarkupContainer getPanel(final String panelId) { - // find the form associated to the current request, if any - return new UserRequestDetails(panelId, userRequest, container, notificationPanel); - } - }), Model.of(-1)).setOutputMarkupId(true)); - } - }; - urDataView.setItemsPerPage(ROWS_PER_PAGE); - urDataView.setOutputMarkupId(true); - container.add(urDataView); - container.add(new AjaxPagingNavigator("navigator", urDataView)); - Model bpmnProcessModel = new Model<>(); AjaxLink startButton = new AjaxLink<>("start") { @@ -105,7 +78,7 @@ public WebMarkupContainer getPanel(final String panelId) { public void onClick(final AjaxRequestTarget target) { if (StringUtils.isNotBlank(bpmnProcessModel.getObject())) { try { - userRequestRestClient.startRequest(bpmnProcessModel.getObject(), null); + userRequestRestClient.startRequest(bpmnProcessModel.getObject()); } catch (Exception e) { LOG.error("Unable to start bpmnProcess [{}]", bpmnProcessModel.getObject(), e); SyncopeEnduserSession.get() @@ -116,13 +89,12 @@ public void onClick(final AjaxRequestTarget target) { } } }; - - startButton.setEnabled(false); - container.add(startButton); + container.add(startButton.setEnabled(false)); // autocomplete select with bpmnProcesses - BpmnProcessesAjaxPanel bpmnProcesses = new BpmnProcessesAjaxPanel("bpmnProcesses", "bpmnProcesses", - bpmnProcessModel, new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + AjaxTextFieldPanel bpmnProcesses = new AjaxTextFieldPanel( + "bpmnProcesses", "bpmnProcesses", bpmnProcessModel, false); + bpmnProcesses.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { private static final long serialVersionUID = -1107858522700306810L; @@ -134,8 +106,33 @@ protected void onUpdate(final AjaxRequestTarget target) { }); bpmnProcesses.setChoices(bpmnProcessRestClient.getDefinitions().stream(). filter(Predicate.not(BpmnProcess::isUserWorkflow)). - map(BpmnProcess::getKey).toList()); + map(BpmnProcess::getKey).sorted().toList()); container.add(bpmnProcesses); + + // list of accordions containing request form (if any) and delete button + DataView urDataView = new DataView<>( + "userRequests", new URDataProvider(ROWS_PER_PAGE, "bpmnProcess")) { + + private static final long serialVersionUID = -5002600396458362774L; + + @Override + protected void populateItem(final Item item) { + UserRequest userRequest = item.getModelObject(); + item.add(new Accordion("userRequestDetails", List.of(new AbstractTab( + new StringResourceModel("user.requests.accordion", container, Model.of(userRequest))) { + + private static final long serialVersionUID = 1037272333056449378L; + + @Override + public WebMarkupContainer getPanel(final String panelId) { + return new UserRequestDetails(panelId, userRequest, container, notificationPanel); + } + }), Model.of(-1)).setOutputMarkupId(true)); + } + }; + urDataView.setItemsPerPage(ROWS_PER_PAGE); + container.add(urDataView.setOutputMarkupId(true)); + container.add(new AjaxPagingNavigator("navigator", urDataView)); } protected class URDataProvider implements IDataProvider { @@ -154,9 +151,9 @@ public URDataProvider(final int paginatorRows, final String sortParam) { @Override public Iterator iterator(final long first, final long count) { int page = ((int) first / paginatorRows); - return userRequestRestClient.listRequests((page < 0 ? 0 : page) + 1, + return userRequestRestClient.listRequests( + (page < 0 ? 0 : page) + 1, paginatorRows, - SyncopeEnduserSession.get().getSelfTO().getUsername(), new SortParam<>(sortParam, true)).iterator(); } diff --git a/ext/flowable/client-enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserRequestDetails.java b/ext/flowable/client-enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserRequestDetails.java index ae03ab3fa52..c834a440b5d 100644 --- a/ext/flowable/client-enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserRequestDetails.java +++ b/ext/flowable/client-enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserRequestDetails.java @@ -60,15 +60,14 @@ public UserRequestDetails( super(id); UserRequestForm formTO = userRequest.getHasForm() - ? userRequestRestClient.getForm( - SyncopeEnduserSession.get().getSelfTO().getUsername(), - userRequest.getTaskId()).orElse(null) + ? userRequestRestClient.getForm(userRequest.getTaskId()).orElse(null) : null; - if (formTO == null || formTO.getProperties() == null || formTO.getProperties().isEmpty()) { - add(new Fragment("fragContainer", "formDetails", UserRequestDetails.this) - .add(new Label("executionId", userRequest.getExecutionId())) - .add(new Label("startTime", userRequest.getStartTime()))); + if (formTO == null || formTO.getProperties().isEmpty()) { + add(new Fragment("fragContainer", "requestDetails", UserRequestDetails.this). + add(new Label("executionId", userRequest.getExecutionId())). + add(new Label("activityId", userRequest.getActivityId())). + add(new Label("startTime", userRequest.getStartTime()))); } else { Form form = new Form<>("userRequestWrapForm"); diff --git a/ext/flowable/client-enduser/src/main/java/org/apache/syncope/client/enduser/rest/UserRequestRestClient.java b/ext/flowable/client-enduser/src/main/java/org/apache/syncope/client/enduser/rest/UserRequestRestClient.java index e136f978bdb..078e208d28c 100644 --- a/ext/flowable/client-enduser/src/main/java/org/apache/syncope/client/enduser/rest/UserRequestRestClient.java +++ b/ext/flowable/client-enduser/src/main/java/org/apache/syncope/client/enduser/rest/UserRequestRestClient.java @@ -21,7 +21,6 @@ import jakarta.ws.rs.core.GenericType; import java.util.List; import java.util.Optional; -import org.apache.commons.lang3.StringUtils; import org.apache.cxf.jaxrs.client.WebClient; import org.apache.cxf.transport.http.asyncclient.AsyncHTTPConduit; import org.apache.syncope.client.enduser.SyncopeEnduserSession; @@ -38,25 +37,23 @@ public class UserRequestRestClient extends BaseRestClient { private static final long serialVersionUID = -4785231164900813921L; public long countRequests() { - return getService(UserRequestService.class). - listRequests(new UserRequestQuery.Builder() - .user(SyncopeEnduserSession.get().getSelfTO().getUsername()) - .page(1) - .size(0) - .build()).getTotalCount(); + return getService(UserRequestService.class).listRequests( + new UserRequestQuery.Builder(). + user(SyncopeEnduserSession.get().getSelfTO().getUsername()). + page(1).size(0).build()). + getTotalCount(); } public List listRequests( final int page, final int size, - final String username, final SortParam sort) { - return getService(UserRequestService.class).listRequests(new UserRequestQuery.Builder(). - user(StringUtils.isBlank(username) - ? SyncopeEnduserSession.get().getSelfTO().getUsername() - : username). - page(page).size(size).orderBy(toOrderBy(sort)).build()).getResult(); + return getService(UserRequestService.class).listRequests( + new UserRequestQuery.Builder(). + user(SyncopeEnduserSession.get().getSelfTO().getUsername()). + page(page).size(size).orderBy(toOrderBy(sort)).build()). + getResult(); } public void cancelRequest(final String executionId, final String reason) { @@ -75,11 +72,9 @@ public List listForms(final int page, final int size, final Sor getResult(); } - public Optional getForm(final String username, final String taskId) { - return Optional.ofNullable(getService(UserRequestService.class).getForm(StringUtils.isBlank(username) - ? SyncopeEnduserSession.get().getSelfTO().getUsername() - : username, - taskId)); + public Optional getForm(final String taskId) { + return Optional.ofNullable(getService(UserRequestService.class). + getForm(SyncopeEnduserSession.get().getSelfTO().getUsername(), taskId)); } public ProvisioningResult submitForm(final UserRequestForm form) { @@ -88,12 +83,12 @@ public ProvisioningResult submitForm(final UserRequestForm form) { }); } - public void startRequest(final String bpmnProcess, final String user) { + public void startRequest(final String bpmnProcess) { UserRequestService service = getService(UserRequestService.class); WebClient.getConfig(WebClient.client(service)). getRequestContext().put(AsyncHTTPConduit.USE_ASYNC, Boolean.FALSE); - service.startRequest(bpmnProcess, user, null); + service.startRequest(bpmnProcess, null, null); WebClient.getConfig(WebClient.client(service)). getRequestContext().put(AsyncHTTPConduit.USE_ASYNC, Boolean.TRUE); diff --git a/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable.properties b/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable.properties index 61a1f703f38..17cc65dccff 100644 --- a/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable.properties +++ b/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable.properties @@ -17,8 +17,9 @@ user.requests.accordion=${bpmnProcess} (${activityId}) bpmn.process.title=Requests submit=Submit -executionId=Execution ID +executionId=Execution Id startTime=Start time delete=Delete start=Start requests.to.be.approved=Your active requests +activityId=Activity Id diff --git a/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable_it.properties b/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable_it.properties index 5f11651a868..aba7051a6d2 100644 --- a/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable_it.properties +++ b/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable_it.properties @@ -17,8 +17,9 @@ user.requests.accordion=${bpmnProcess} (${activityId}) bpmn.process.title=Richieste submit=Salva -executionId=Execution ID +executionId=Id esecuzione startTime=Eseguito il delete=Cancella start=Esegui requests.to.be.approved=Richieste in lavorazione +activityId=Id attivit\u00e0 diff --git a/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable_ja.properties b/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable_ja.properties index 64bcf41d230..2a8e4033b7b 100644 --- a/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable_ja.properties +++ b/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable_ja.properties @@ -22,3 +22,4 @@ startTime=\u59cb\u307e\u308b\u6642\u9593 delete=\u30af\u30ea\u30a2 start=\u958b\u59cb requests.to.be.approved=\u3042\u306a\u305f\u306e\u30a2\u30af\u30c6\u30a3\u30d6\u306a\u30ea\u30af\u30a8\u30b9\u30c8 +activityId=Activity Id diff --git a/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable_pt_BR.properties b/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable_pt_BR.properties index 947d75efb6e..57b7d626835 100644 --- a/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable_pt_BR.properties +++ b/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable_pt_BR.properties @@ -17,8 +17,9 @@ user.requests.accordion=${bpmnProcess} (${activityId}) bpmn.process.title=Os pedidos submit=Enviar -executionId=Execution ID +executionId=Execution Id startTime=Hora de in\u00edcio delete=Limpa start=Come\u00e7ar requests.to.be.approved=Seus pedidos ativos +activityId=Activity Id diff --git a/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable_ru.properties b/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable_ru.properties index 5dba97663f7..87cfaccc4ac 100644 --- a/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable_ru.properties +++ b/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/pages/Flowable_ru.properties @@ -22,3 +22,4 @@ startTime=\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0 delete=\u0440\u0430\u0441\u0441\u0435\u0435\u0442\u0441\u044f start=\u041d\u0430\u0447\u043d\u0438\u0442\u0435 requests.to.be.approved=\u0412\u0430\u0448\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b +activityId=Activity Id diff --git a/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserRequestDetails.html b/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserRequestDetails.html index 2fe17c09287..c1318ba8153 100644 --- a/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserRequestDetails.html +++ b/ext/flowable/client-enduser/src/main/resources/org/apache/syncope/client/enduser/panels/UserRequestDetails.html @@ -21,6 +21,7 @@
+
@@ -29,10 +30,26 @@
- - : - : + + + + + + + + + + + + + + + + + +
+
From 81dc44ac50bd3ec2b39f3276bb0b2267d3d39eff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Thu, 22 May 2025 14:34:41 +0200 Subject: [PATCH 058/579] Upgrading Spring Boot --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1f8b93062c7..bd08af46cf8 100644 --- a/pom.xml +++ b/pom.xml @@ -415,7 +415,7 @@ under the License. 1.80 10.3 - 3.4.5 + 3.4.6 4.2.1 4.1.1 From fda75b966a5e359e7d4cf3668826c5f1b5d56722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Fri, 23 May 2025 08:06:22 +0200 Subject: [PATCH 059/579] Upgrading CXF and Swagger UI --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index bd08af46cf8..414252301a8 100644 --- a/pom.xml +++ b/pom.xml @@ -411,7 +411,7 @@ under the License. 1.0.0 0.1.0 - 4.1.1 + 4.1.2 1.80 10.3 @@ -447,7 +447,7 @@ under the License. 4.0.4 2.2.32 - 5.21.0 + 5.22.0 1.3.8 1.4.1-1 From af496def64c94bcc897158a75e4648277a5ad6e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Fri, 23 May 2025 10:29:55 +0200 Subject: [PATCH 060/579] Updating CHANGES for release --- CHANGES | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/CHANGES b/CHANGES index a7087493681..a823168d339 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,40 @@ Apache Syncope - CHANGES Licensed under Apache License 2.0 - http://www.apache.org/licenses/LICENSE-2.0 -------------------------------------------------------------------------------- +Release Notes - Syncope - Version 4.0.0 +================================================================================ + +** Bug + * [SYNCOPE-1868] - NPE when performing provision without changing password + * [SYNCOPE-1871] - Realm selection shows only one of allowed sub-trees + * [SYNCOPE-1873] - LocalDateTime fields not properly handled in BeanPanel + * [SYNCOPE-1875] - SAML delegated authentication: metadata keeps getting re-generated + * [SYNCOPE-1878] - Priority propagation failing with NOT_ATTEMPTED + * [SYNCOPE-1879] - Serialization error while auditing Pull data + * [SYNCOPE-1881] - WA: SP Metadata not fetched from Core + * [SYNCOPE-1882] - Multivalue dropdown attributes show additional empty selectable value + * [SYNCOPE-1883] - Google MFA authentication does not validate scratch codes + * [SYNCOPE-1884] - Errors with Encrypted plain values + +** New Feature + * [SYNCOPE-1617] - Debezium support + * [SYNCOPE-1861] - OpenLDAP Sync Replication support + * [SYNCOPE-1874] - Realm attributes + +** Improvement + * [SYNCOPE-1621] - Allow export for individual items in XML + * [SYNCOPE-1841] - Read-only multi value schema must not show new and delete button + * [SYNCOPE-1869] - Support evaluation order for client apps + * [SYNCOPE-1870] - Generic exception handling (RestServiceExceptionMapper) + * [SYNCOPE-1872] - Allow setting of force execution for MFA authentication + * [SYNCOPE-1880] - SCIM endpoints ignore the Prefer header + * [SYNCOPE-1885] - Self password reset does not trigger notification tasks without Flowable extension + +** Task + * [SYNCOPE-1866] - Implement AuthProfile management in Enduser + * [SYNCOPE-1876] - Remove Virtual Attributes + * [SYNCOPE-1877] - Include SAML SP keystore and metadata in AuthModule configuration + Release Notes - Syncope - Version 4.0.0-M1 ================================================================================ From 50459abc5d8e978574ce3b6a7857d3a9c72d5032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Fri, 23 May 2025 10:30:43 +0200 Subject: [PATCH 061/579] Updating downloads site page for release --- src/site/xdoc/downloads.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/site/xdoc/downloads.xml b/src/site/xdoc/downloads.xml index 5881b13ba93..8d37659b00c 100644 --- a/src/site/xdoc/downloads.xml +++ b/src/site/xdoc/downloads.xml @@ -36,8 +36,8 @@ under the License. It is good practice to verify the integrity of the distribution files.

- -

Release date: March 7th 2025

+ +

Release date: May 23rd 2025

Release notes

@@ -61,29 +61,29 @@ under the License. - syncope-4.0.0-M1-source-release.zip + syncope-4.0.0-source-release.zip - asc - sha512 + asc + sha512 - syncope-standalone-4.0.0-M1-distribution.zip + syncope-standalone-4.0.0-distribution.zip - asc - sha512 + asc + sha512 - syncope-core-persistence-jpa-upgrader-4.0.0-M1.jar + syncope-core-persistence-jpa-upgrader-4.0.0.jar - asc - sha512 + asc + sha512 From b0c019c1256bf433bf60e3211ee8711dae03e6bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Fri, 23 May 2025 10:39:16 +0200 Subject: [PATCH 062/579] prepare release syncope-4.0.0 --- archetype/pom.xml | 2 +- client/am/console/pom.xml | 2 +- client/am/enduser/pom.xml | 2 +- client/am/lib/pom.xml | 2 +- client/am/pom.xml | 2 +- client/idm/console/pom.xml | 2 +- client/idm/lib/pom.xml | 2 +- client/idm/pom.xml | 2 +- client/idrepo/common-ui/pom.xml | 2 +- client/idrepo/console/pom.xml | 2 +- client/idrepo/enduser/pom.xml | 2 +- client/idrepo/lib/pom.xml | 2 +- client/idrepo/pom.xml | 2 +- client/pom.xml | 2 +- common/am/lib/pom.xml | 2 +- common/am/pom.xml | 2 +- common/am/rest-api/pom.xml | 2 +- common/idm/lib/pom.xml | 2 +- common/idm/pom.xml | 2 +- common/idm/rest-api/pom.xml | 2 +- common/idrepo/lib/pom.xml | 2 +- common/idrepo/pom.xml | 2 +- common/idrepo/rest-api/pom.xml | 2 +- common/keymaster/client-api/pom.xml | 2 +- common/keymaster/client-zookeeper/pom.xml | 2 +- common/keymaster/pom.xml | 2 +- common/keymaster/self/client-self/pom.xml | 2 +- common/keymaster/self/pom.xml | 2 +- common/keymaster/self/rest-api/pom.xml | 2 +- common/pom.xml | 2 +- core/am/logic/pom.xml | 2 +- core/am/pom.xml | 2 +- core/am/rest-cxf/pom.xml | 2 +- core/idm/logic/pom.xml | 2 +- core/idm/pom.xml | 2 +- core/idm/rest-cxf/pom.xml | 2 +- core/idrepo/logic/pom.xml | 2 +- core/idrepo/pom.xml | 2 +- core/idrepo/rest-cxf/pom.xml | 2 +- core/persistence-api/pom.xml | 2 +- core/persistence-common/pom.xml | 2 +- core/persistence-jpa-upgrader/pom.xml | 2 +- core/persistence-jpa/pom.xml | 2 +- core/persistence-neo4j/pom.xml | 2 +- core/pom.xml | 2 +- core/provisioning-api/pom.xml | 2 +- core/provisioning-java/pom.xml | 2 +- core/self-keymaster-starter/pom.xml | 2 +- core/spring/pom.xml | 2 +- core/starter/pom.xml | 2 +- core/workflow-api/pom.xml | 2 +- core/workflow-java/pom.xml | 2 +- docker/console/pom.xml | 2 +- docker/core/pom.xml | 2 +- docker/enduser/pom.xml | 2 +- docker/pom.xml | 2 +- docker/sra/pom.xml | 2 +- docker/wa/pom.xml | 2 +- ext/elasticsearch/client-elasticsearch/pom.xml | 2 +- ext/elasticsearch/persistence/pom.xml | 2 +- ext/elasticsearch/pom.xml | 2 +- ext/elasticsearch/provisioning-java/pom.xml | 2 +- ext/flowable/client-console/pom.xml | 2 +- ext/flowable/client-enduser/pom.xml | 2 +- ext/flowable/common-lib/pom.xml | 2 +- ext/flowable/flowable-bpmn/pom.xml | 2 +- ext/flowable/logic/pom.xml | 2 +- ext/flowable/pom.xml | 2 +- ext/flowable/rest-api/pom.xml | 2 +- ext/flowable/rest-cxf/pom.xml | 2 +- ext/oidcc4ui/client-common-ui/pom.xml | 2 +- ext/oidcc4ui/client-console/pom.xml | 2 +- ext/oidcc4ui/client-enduser/pom.xml | 2 +- ext/oidcc4ui/common-lib/pom.xml | 2 +- ext/oidcc4ui/logic/pom.xml | 2 +- ext/oidcc4ui/persistence-api/pom.xml | 2 +- ext/oidcc4ui/persistence-jpa/pom.xml | 2 +- ext/oidcc4ui/pom.xml | 2 +- ext/oidcc4ui/provisioning-api/pom.xml | 2 +- ext/oidcc4ui/provisioning-java/pom.xml | 2 +- ext/oidcc4ui/rest-api/pom.xml | 2 +- ext/oidcc4ui/rest-cxf/pom.xml | 2 +- ext/openfga/client-openfga/pom.xml | 2 +- ext/openfga/pom.xml | 2 +- ext/openfga/provisioning-java/pom.xml | 2 +- ext/opensearch/client-opensearch/pom.xml | 2 +- ext/opensearch/persistence/pom.xml | 2 +- ext/opensearch/pom.xml | 2 +- ext/opensearch/provisioning-java/pom.xml | 2 +- ext/pom.xml | 2 +- ext/saml2sp4ui/client-common-ui/pom.xml | 2 +- ext/saml2sp4ui/client-console/pom.xml | 2 +- ext/saml2sp4ui/client-enduser/pom.xml | 2 +- ext/saml2sp4ui/common-lib/pom.xml | 2 +- ext/saml2sp4ui/logic/pom.xml | 2 +- ext/saml2sp4ui/persistence-api/pom.xml | 2 +- ext/saml2sp4ui/persistence-jpa/pom.xml | 2 +- ext/saml2sp4ui/pom.xml | 2 +- ext/saml2sp4ui/provisioning-api/pom.xml | 2 +- ext/saml2sp4ui/provisioning-java/pom.xml | 2 +- ext/saml2sp4ui/rest-api/pom.xml | 2 +- ext/saml2sp4ui/rest-cxf/pom.xml | 2 +- ext/scimv2/client-console/pom.xml | 2 +- ext/scimv2/common-lib/pom.xml | 2 +- ext/scimv2/logic/pom.xml | 2 +- ext/scimv2/pom.xml | 2 +- ext/scimv2/rest-api/pom.xml | 2 +- ext/scimv2/rest-cxf/pom.xml | 2 +- ext/scimv2/scim-rest-api/pom.xml | 2 +- ext/scimv2/scim-rest-cxf/pom.xml | 2 +- fit/build-tools/pom.xml | 2 +- fit/console-reference/pom.xml | 2 +- fit/core-reference/pom.xml | 2 +- fit/enduser-reference/pom.xml | 2 +- fit/persistence-embedded/pom.xml | 2 +- fit/pom.xml | 2 +- fit/wa-reference/pom.xml | 2 +- pom.xml | 6 +++--- sra/pom.xml | 2 +- standalone/pom.xml | 2 +- wa/bootstrap/pom.xml | 2 +- wa/pom.xml | 2 +- wa/starter/pom.xml | 2 +- 123 files changed, 125 insertions(+), 125 deletions(-) diff --git a/archetype/pom.xml b/archetype/pom.xml index 823c663de42..b5c5607325d 100644 --- a/archetype/pom.xml +++ b/archetype/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Archetype diff --git a/client/am/console/pom.xml b/client/am/console/pom.xml index e49b624ca3f..21d7aeea979 100644 --- a/client/am/console/pom.xml +++ b/client/am/console/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.client syncope-client-am - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Client AM Console diff --git a/client/am/enduser/pom.xml b/client/am/enduser/pom.xml index 2eb52d5089a..ffc42a00e39 100644 --- a/client/am/enduser/pom.xml +++ b/client/am/enduser/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.client syncope-client-am - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Client AM Enduser diff --git a/client/am/lib/pom.xml b/client/am/lib/pom.xml index e3827702361..4d7686f4714 100644 --- a/client/am/lib/pom.xml +++ b/client/am/lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.client syncope-client-am - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Client AM Lib diff --git a/client/am/pom.xml b/client/am/pom.xml index 5fc1715969a..c93cb45713b 100644 --- a/client/am/pom.xml +++ b/client/am/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-client - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Client AM diff --git a/client/idm/console/pom.xml b/client/idm/console/pom.xml index 7f318e6f919..6d46b811712 100644 --- a/client/idm/console/pom.xml +++ b/client/idm/console/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.client syncope-client-idm - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Client IdM Console diff --git a/client/idm/lib/pom.xml b/client/idm/lib/pom.xml index 80f4a80dafe..19e0b3a1584 100644 --- a/client/idm/lib/pom.xml +++ b/client/idm/lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.client syncope-client-idm - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Client IdM Lib diff --git a/client/idm/pom.xml b/client/idm/pom.xml index fe915c75ecd..6f645f19162 100644 --- a/client/idm/pom.xml +++ b/client/idm/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-client - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Client IdM diff --git a/client/idrepo/common-ui/pom.xml b/client/idrepo/common-ui/pom.xml index 4337570a795..04d9fc2aacf 100644 --- a/client/idrepo/common-ui/pom.xml +++ b/client/idrepo/common-ui/pom.xml @@ -22,7 +22,7 @@ under the License. org.apache.syncope.client syncope-client-idrepo - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Client IdRepo Common UI diff --git a/client/idrepo/console/pom.xml b/client/idrepo/console/pom.xml index 56e7f005ec8..a15f3866a87 100644 --- a/client/idrepo/console/pom.xml +++ b/client/idrepo/console/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.client syncope-client-idrepo - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Client IdRepo Console diff --git a/client/idrepo/enduser/pom.xml b/client/idrepo/enduser/pom.xml index ec57bb935a9..17df5a143e9 100644 --- a/client/idrepo/enduser/pom.xml +++ b/client/idrepo/enduser/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.client syncope-client-idrepo - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Client IdRepo Enduser diff --git a/client/idrepo/lib/pom.xml b/client/idrepo/lib/pom.xml index a7bde1493af..575cc831590 100644 --- a/client/idrepo/lib/pom.xml +++ b/client/idrepo/lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.client syncope-client-idrepo - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Client IdRepo Lib diff --git a/client/idrepo/pom.xml b/client/idrepo/pom.xml index c36f23dbddf..d6118f297da 100644 --- a/client/idrepo/pom.xml +++ b/client/idrepo/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-client - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Client IdRepo diff --git a/client/pom.xml b/client/pom.xml index 1bd93661b80..c5327e8f43c 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Client diff --git a/common/am/lib/pom.xml b/common/am/lib/pom.xml index f60dc684161..51a1d54b449 100644 --- a/common/am/lib/pom.xml +++ b/common/am/lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common syncope-common-am - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Common AM Lib diff --git a/common/am/pom.xml b/common/am/pom.xml index 8d3a673c55e..58f3d93e8f3 100644 --- a/common/am/pom.xml +++ b/common/am/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-common - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Common AM diff --git a/common/am/rest-api/pom.xml b/common/am/rest-api/pom.xml index 95584ee09de..c834b15ec7a 100644 --- a/common/am/rest-api/pom.xml +++ b/common/am/rest-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common syncope-common-am - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Common AM REST API diff --git a/common/idm/lib/pom.xml b/common/idm/lib/pom.xml index 810d99b9ca7..2206f394053 100644 --- a/common/idm/lib/pom.xml +++ b/common/idm/lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common syncope-common-idm - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Common IdM Lib diff --git a/common/idm/pom.xml b/common/idm/pom.xml index b9d8dc93d08..d96040a4133 100644 --- a/common/idm/pom.xml +++ b/common/idm/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-common - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Common IdM diff --git a/common/idm/rest-api/pom.xml b/common/idm/rest-api/pom.xml index fa78ef1ff7f..9f01978b67b 100644 --- a/common/idm/rest-api/pom.xml +++ b/common/idm/rest-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common syncope-common-idm - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Common IdM REST API diff --git a/common/idrepo/lib/pom.xml b/common/idrepo/lib/pom.xml index b19aa766335..3fb9a5dcc4a 100644 --- a/common/idrepo/lib/pom.xml +++ b/common/idrepo/lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common syncope-common-idrepo - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Common IdRepo Lib diff --git a/common/idrepo/pom.xml b/common/idrepo/pom.xml index 25b8fde1a64..72be6586e94 100644 --- a/common/idrepo/pom.xml +++ b/common/idrepo/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-common - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Common IdRepo diff --git a/common/idrepo/rest-api/pom.xml b/common/idrepo/rest-api/pom.xml index 51434459105..be22b02879f 100644 --- a/common/idrepo/rest-api/pom.xml +++ b/common/idrepo/rest-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common syncope-common-idrepo - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Common IdRepo REST API diff --git a/common/keymaster/client-api/pom.xml b/common/keymaster/client-api/pom.xml index 46fb724e471..ff27051b975 100644 --- a/common/keymaster/client-api/pom.xml +++ b/common/keymaster/client-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common syncope-common-keymaster - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Common Keymaster Client API diff --git a/common/keymaster/client-zookeeper/pom.xml b/common/keymaster/client-zookeeper/pom.xml index 55f40ddeead..c9a418dae14 100644 --- a/common/keymaster/client-zookeeper/pom.xml +++ b/common/keymaster/client-zookeeper/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common syncope-common-keymaster - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Common Keymaster Client Zookeeper diff --git a/common/keymaster/pom.xml b/common/keymaster/pom.xml index 52cdd87f739..3daad836498 100644 --- a/common/keymaster/pom.xml +++ b/common/keymaster/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-common - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Common Keymaster diff --git a/common/keymaster/self/client-self/pom.xml b/common/keymaster/self/client-self/pom.xml index bd07a657552..2128567bf34 100644 --- a/common/keymaster/self/client-self/pom.xml +++ b/common/keymaster/self/client-self/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common.keymaster syncope-common-keymaster-self - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Common Keymaster Client Self diff --git a/common/keymaster/self/pom.xml b/common/keymaster/self/pom.xml index 42806095de1..efd07cb3c88 100644 --- a/common/keymaster/self/pom.xml +++ b/common/keymaster/self/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common syncope-common-keymaster - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Common Keymaster Self diff --git a/common/keymaster/self/rest-api/pom.xml b/common/keymaster/self/rest-api/pom.xml index bf9ab7ffb69..95a03db6c69 100644 --- a/common/keymaster/self/rest-api/pom.xml +++ b/common/keymaster/self/rest-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common.keymaster syncope-common-keymaster-self - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Common Keymaster Self REST API diff --git a/common/pom.xml b/common/pom.xml index bf3b67fa7e7..a05fb9b3c55 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Common diff --git a/core/am/logic/pom.xml b/core/am/logic/pom.xml index 6b0147d613f..b6197a17c95 100644 --- a/core/am/logic/pom.xml +++ b/core/am/logic/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.core syncope-core-am - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core AM Logic diff --git a/core/am/pom.xml b/core/am/pom.xml index 46e359672e9..5052ecdf1cf 100644 --- a/core/am/pom.xml +++ b/core/am/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core AM diff --git a/core/am/rest-cxf/pom.xml b/core/am/rest-cxf/pom.xml index 2a82237c3b6..c56325958ae 100644 --- a/core/am/rest-cxf/pom.xml +++ b/core/am/rest-cxf/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.core syncope-core-am - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core AM REST CXF diff --git a/core/idm/logic/pom.xml b/core/idm/logic/pom.xml index b78651d03d1..0082007c5ad 100644 --- a/core/idm/logic/pom.xml +++ b/core/idm/logic/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.core syncope-core-idm - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core IdM Logic diff --git a/core/idm/pom.xml b/core/idm/pom.xml index f831b58d95f..b77797186c3 100644 --- a/core/idm/pom.xml +++ b/core/idm/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core IdM diff --git a/core/idm/rest-cxf/pom.xml b/core/idm/rest-cxf/pom.xml index 79ceb8b0683..12bc9f66067 100644 --- a/core/idm/rest-cxf/pom.xml +++ b/core/idm/rest-cxf/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.core syncope-core-idm - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core IdM REST CXF diff --git a/core/idrepo/logic/pom.xml b/core/idrepo/logic/pom.xml index 630e6aec8a4..d4498d1309f 100644 --- a/core/idrepo/logic/pom.xml +++ b/core/idrepo/logic/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.core syncope-core-idrepo - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core IdRepo Logic diff --git a/core/idrepo/pom.xml b/core/idrepo/pom.xml index 32b8fe90bdd..69d4eedf968 100644 --- a/core/idrepo/pom.xml +++ b/core/idrepo/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core IdRepo diff --git a/core/idrepo/rest-cxf/pom.xml b/core/idrepo/rest-cxf/pom.xml index 898e165cf9c..edfb817e9b9 100644 --- a/core/idrepo/rest-cxf/pom.xml +++ b/core/idrepo/rest-cxf/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.core syncope-core-idrepo - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core IdRepo REST CXF diff --git a/core/persistence-api/pom.xml b/core/persistence-api/pom.xml index f222a905349..3173439ac5e 100644 --- a/core/persistence-api/pom.xml +++ b/core/persistence-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core Persistence API diff --git a/core/persistence-common/pom.xml b/core/persistence-common/pom.xml index c82278a4eef..a15b514fe16 100644 --- a/core/persistence-common/pom.xml +++ b/core/persistence-common/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core Persistence Common diff --git a/core/persistence-jpa-upgrader/pom.xml b/core/persistence-jpa-upgrader/pom.xml index f67b7556cd8..d2e7ad982ca 100644 --- a/core/persistence-jpa-upgrader/pom.xml +++ b/core/persistence-jpa-upgrader/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core Persistence JPA Upgrader diff --git a/core/persistence-jpa/pom.xml b/core/persistence-jpa/pom.xml index 98e8f914be9..1a8403b6fec 100644 --- a/core/persistence-jpa/pom.xml +++ b/core/persistence-jpa/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core Persistence JPA diff --git a/core/persistence-neo4j/pom.xml b/core/persistence-neo4j/pom.xml index efe1ebf05e1..f4c81e3d5fe 100644 --- a/core/persistence-neo4j/pom.xml +++ b/core/persistence-neo4j/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core Persistence Neo4j diff --git a/core/pom.xml b/core/pom.xml index 101dabb9e97..7a140ed86f0 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core diff --git a/core/provisioning-api/pom.xml b/core/provisioning-api/pom.xml index ef6ea8a7516..f3a687dd783 100644 --- a/core/provisioning-api/pom.xml +++ b/core/provisioning-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core Provisioning API diff --git a/core/provisioning-java/pom.xml b/core/provisioning-java/pom.xml index 4f93f4e4ed7..c2909f3f995 100644 --- a/core/provisioning-java/pom.xml +++ b/core/provisioning-java/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core Provisioning Java diff --git a/core/self-keymaster-starter/pom.xml b/core/self-keymaster-starter/pom.xml index ed2bf49116a..9cacd9f66a2 100644 --- a/core/self-keymaster-starter/pom.xml +++ b/core/self-keymaster-starter/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core Spring Boot Self Keymaster diff --git a/core/spring/pom.xml b/core/spring/pom.xml index 31f6438ff08..2e6f482c6fb 100644 --- a/core/spring/pom.xml +++ b/core/spring/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core Spring diff --git a/core/starter/pom.xml b/core/starter/pom.xml index 38f8ad7055d..fbe285f34ca 100644 --- a/core/starter/pom.xml +++ b/core/starter/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core Spring Boot Starter diff --git a/core/workflow-api/pom.xml b/core/workflow-api/pom.xml index 31c736ac40a..fe0f5ab84cf 100644 --- a/core/workflow-api/pom.xml +++ b/core/workflow-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core Workflow API diff --git a/core/workflow-java/pom.xml b/core/workflow-java/pom.xml index 43311d1f0b7..0623dbd6749 100644 --- a/core/workflow-java/pom.xml +++ b/core/workflow-java/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Core Workflow Java diff --git a/docker/console/pom.xml b/docker/console/pom.xml index 2dbf444844d..dd131f8d17a 100644 --- a/docker/console/pom.xml +++ b/docker/console/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-docker - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Docker Console diff --git a/docker/core/pom.xml b/docker/core/pom.xml index 611dbccdd23..727df16191d 100644 --- a/docker/core/pom.xml +++ b/docker/core/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-docker - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Docker Core diff --git a/docker/enduser/pom.xml b/docker/enduser/pom.xml index 0b97845ad1b..6ca2ff54676 100644 --- a/docker/enduser/pom.xml +++ b/docker/enduser/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-docker - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Docker Enduser diff --git a/docker/pom.xml b/docker/pom.xml index d0d3a40b49f..94f9832e724 100644 --- a/docker/pom.xml +++ b/docker/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Docker diff --git a/docker/sra/pom.xml b/docker/sra/pom.xml index ed134c8f2e6..15231616a4d 100644 --- a/docker/sra/pom.xml +++ b/docker/sra/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-docker - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Docker SRA diff --git a/docker/wa/pom.xml b/docker/wa/pom.xml index 8c0b762d8ae..3a9f0c15ebd 100644 --- a/docker/wa/pom.xml +++ b/docker/wa/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-docker - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Docker WA diff --git a/ext/elasticsearch/client-elasticsearch/pom.xml b/ext/elasticsearch/client-elasticsearch/pom.xml index 0c98ada2207..82ac8e5305c 100644 --- a/ext/elasticsearch/client-elasticsearch/pom.xml +++ b/ext/elasticsearch/client-elasticsearch/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-elasticsearch - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: Elasticsearch Client diff --git a/ext/elasticsearch/persistence/pom.xml b/ext/elasticsearch/persistence/pom.xml index e500ee00b29..95ab2ab534d 100644 --- a/ext/elasticsearch/persistence/pom.xml +++ b/ext/elasticsearch/persistence/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-elasticsearch - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: Elasticsearch Persistence diff --git a/ext/elasticsearch/pom.xml b/ext/elasticsearch/pom.xml index eec6a7c7279..af8703cf250 100644 --- a/ext/elasticsearch/pom.xml +++ b/ext/elasticsearch/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-ext - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: Elasticsearch diff --git a/ext/elasticsearch/provisioning-java/pom.xml b/ext/elasticsearch/provisioning-java/pom.xml index d53c0f1d346..facd72cbda2 100644 --- a/ext/elasticsearch/provisioning-java/pom.xml +++ b/ext/elasticsearch/provisioning-java/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-elasticsearch - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: Elasticsearch Provisioning Java diff --git a/ext/flowable/client-console/pom.xml b/ext/flowable/client-console/pom.xml index 2a0fe86da49..4bf40afd0bd 100644 --- a/ext/flowable/client-console/pom.xml +++ b/ext/flowable/client-console/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-flowable - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: Flowable Client Console diff --git a/ext/flowable/client-enduser/pom.xml b/ext/flowable/client-enduser/pom.xml index a2ed5b114dd..fd611e10881 100644 --- a/ext/flowable/client-enduser/pom.xml +++ b/ext/flowable/client-enduser/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-flowable - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: Flowable Client Enduser diff --git a/ext/flowable/common-lib/pom.xml b/ext/flowable/common-lib/pom.xml index cebad61a6a4..a3fe6f15a13 100644 --- a/ext/flowable/common-lib/pom.xml +++ b/ext/flowable/common-lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-flowable - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: Flowable Common Lib diff --git a/ext/flowable/flowable-bpmn/pom.xml b/ext/flowable/flowable-bpmn/pom.xml index fde73ab3071..e392cda7bcd 100644 --- a/ext/flowable/flowable-bpmn/pom.xml +++ b/ext/flowable/flowable-bpmn/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-flowable - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: Flowable BPMN diff --git a/ext/flowable/logic/pom.xml b/ext/flowable/logic/pom.xml index 90c0d5a0f87..396db1cc8dd 100644 --- a/ext/flowable/logic/pom.xml +++ b/ext/flowable/logic/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-flowable - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: Flowable Logic diff --git a/ext/flowable/pom.xml b/ext/flowable/pom.xml index dabc6cf862a..412efdfe9d4 100644 --- a/ext/flowable/pom.xml +++ b/ext/flowable/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-ext - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: Flowable diff --git a/ext/flowable/rest-api/pom.xml b/ext/flowable/rest-api/pom.xml index 5f48201521c..ee02d64979f 100644 --- a/ext/flowable/rest-api/pom.xml +++ b/ext/flowable/rest-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-flowable - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: Flowable REST API diff --git a/ext/flowable/rest-cxf/pom.xml b/ext/flowable/rest-cxf/pom.xml index f9844716670..c4a0f181f83 100644 --- a/ext/flowable/rest-cxf/pom.xml +++ b/ext/flowable/rest-cxf/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-flowable - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: Flowable REST CXF diff --git a/ext/oidcc4ui/client-common-ui/pom.xml b/ext/oidcc4ui/client-common-ui/pom.xml index 2f4fc55deec..982206130e9 100644 --- a/ext/oidcc4ui/client-common-ui/pom.xml +++ b/ext/oidcc4ui/client-common-ui/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: OIDC C4UI Common UI diff --git a/ext/oidcc4ui/client-console/pom.xml b/ext/oidcc4ui/client-console/pom.xml index 0edd628efd8..d0d1cfb8659 100644 --- a/ext/oidcc4ui/client-console/pom.xml +++ b/ext/oidcc4ui/client-console/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: OIDC C4UI Console diff --git a/ext/oidcc4ui/client-enduser/pom.xml b/ext/oidcc4ui/client-enduser/pom.xml index e9c3e040aea..48c84962515 100644 --- a/ext/oidcc4ui/client-enduser/pom.xml +++ b/ext/oidcc4ui/client-enduser/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: OIDC C4UI Enduser diff --git a/ext/oidcc4ui/common-lib/pom.xml b/ext/oidcc4ui/common-lib/pom.xml index 9ade10a3329..877d1640cd5 100644 --- a/ext/oidcc4ui/common-lib/pom.xml +++ b/ext/oidcc4ui/common-lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: OIDC C4UI Common Lib diff --git a/ext/oidcc4ui/logic/pom.xml b/ext/oidcc4ui/logic/pom.xml index bb9b3ded63e..8392104b3a6 100644 --- a/ext/oidcc4ui/logic/pom.xml +++ b/ext/oidcc4ui/logic/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: OIDC C4UI Logic diff --git a/ext/oidcc4ui/persistence-api/pom.xml b/ext/oidcc4ui/persistence-api/pom.xml index 71251338942..605464d1d89 100644 --- a/ext/oidcc4ui/persistence-api/pom.xml +++ b/ext/oidcc4ui/persistence-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: OIDC C4UI Persistence API diff --git a/ext/oidcc4ui/persistence-jpa/pom.xml b/ext/oidcc4ui/persistence-jpa/pom.xml index 8bd1e84b39c..eaf46b1bd56 100644 --- a/ext/oidcc4ui/persistence-jpa/pom.xml +++ b/ext/oidcc4ui/persistence-jpa/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: OIDC C4UI Persistence JPA diff --git a/ext/oidcc4ui/pom.xml b/ext/oidcc4ui/pom.xml index 985621c06ec..b8d1ade26e2 100644 --- a/ext/oidcc4ui/pom.xml +++ b/ext/oidcc4ui/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-ext - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: OIDC C4UI diff --git a/ext/oidcc4ui/provisioning-api/pom.xml b/ext/oidcc4ui/provisioning-api/pom.xml index 9c481f2c924..4a234ae16c2 100644 --- a/ext/oidcc4ui/provisioning-api/pom.xml +++ b/ext/oidcc4ui/provisioning-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: OIDC C4UI Provisioning API diff --git a/ext/oidcc4ui/provisioning-java/pom.xml b/ext/oidcc4ui/provisioning-java/pom.xml index 4680023d758..769e65d335b 100644 --- a/ext/oidcc4ui/provisioning-java/pom.xml +++ b/ext/oidcc4ui/provisioning-java/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: OIDC C4UI Provisioning Java diff --git a/ext/oidcc4ui/rest-api/pom.xml b/ext/oidcc4ui/rest-api/pom.xml index 9095d893aab..7ee0f3c2b57 100644 --- a/ext/oidcc4ui/rest-api/pom.xml +++ b/ext/oidcc4ui/rest-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: OIDC C4UI REST API diff --git a/ext/oidcc4ui/rest-cxf/pom.xml b/ext/oidcc4ui/rest-cxf/pom.xml index e20a6ffaca4..ebbca71b502 100644 --- a/ext/oidcc4ui/rest-cxf/pom.xml +++ b/ext/oidcc4ui/rest-cxf/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: OIDC C4UI REST CXF diff --git a/ext/openfga/client-openfga/pom.xml b/ext/openfga/client-openfga/pom.xml index 23bd555a216..0901a5d04b1 100644 --- a/ext/openfga/client-openfga/pom.xml +++ b/ext/openfga/client-openfga/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-openfga - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: OpenFGA Client diff --git a/ext/openfga/pom.xml b/ext/openfga/pom.xml index f750e08e571..db5765daf88 100644 --- a/ext/openfga/pom.xml +++ b/ext/openfga/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-ext - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: OpenFGA diff --git a/ext/openfga/provisioning-java/pom.xml b/ext/openfga/provisioning-java/pom.xml index 97dda27511f..e5300bb307c 100644 --- a/ext/openfga/provisioning-java/pom.xml +++ b/ext/openfga/provisioning-java/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-openfga - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: OpenFGA Provisioning Java diff --git a/ext/opensearch/client-opensearch/pom.xml b/ext/opensearch/client-opensearch/pom.xml index 47a89de2020..748cd60dcc2 100644 --- a/ext/opensearch/client-opensearch/pom.xml +++ b/ext/opensearch/client-opensearch/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-opensearch - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: OpenSearch Client diff --git a/ext/opensearch/persistence/pom.xml b/ext/opensearch/persistence/pom.xml index 9ae980640ff..10951f3f481 100644 --- a/ext/opensearch/persistence/pom.xml +++ b/ext/opensearch/persistence/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-opensearch - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: OpenSearch Persistence diff --git a/ext/opensearch/pom.xml b/ext/opensearch/pom.xml index af20ffe4749..686cc6a3b19 100644 --- a/ext/opensearch/pom.xml +++ b/ext/opensearch/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-ext - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: OpenSearch diff --git a/ext/opensearch/provisioning-java/pom.xml b/ext/opensearch/provisioning-java/pom.xml index 7120ebd10d6..eba02c48787 100644 --- a/ext/opensearch/provisioning-java/pom.xml +++ b/ext/opensearch/provisioning-java/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-opensearch - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: OpenSearch Provisioning Java diff --git a/ext/pom.xml b/ext/pom.xml index f32d5ac6c86..8cc67538dfb 100644 --- a/ext/pom.xml +++ b/ext/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext diff --git a/ext/saml2sp4ui/client-common-ui/pom.xml b/ext/saml2sp4ui/client-common-ui/pom.xml index 26327aa0b3b..b8b3d0e9335 100644 --- a/ext/saml2sp4ui/client-common-ui/pom.xml +++ b/ext/saml2sp4ui/client-common-ui/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SAML2 SP4UI Common UI diff --git a/ext/saml2sp4ui/client-console/pom.xml b/ext/saml2sp4ui/client-console/pom.xml index bc628a4ef03..e7fc15f290d 100644 --- a/ext/saml2sp4ui/client-console/pom.xml +++ b/ext/saml2sp4ui/client-console/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SAML2 SP4UI Client Console diff --git a/ext/saml2sp4ui/client-enduser/pom.xml b/ext/saml2sp4ui/client-enduser/pom.xml index a7c3427d55b..31cb240d7d9 100644 --- a/ext/saml2sp4ui/client-enduser/pom.xml +++ b/ext/saml2sp4ui/client-enduser/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SAML2 SP4UI Client Enduser diff --git a/ext/saml2sp4ui/common-lib/pom.xml b/ext/saml2sp4ui/common-lib/pom.xml index d103e45abd0..14a46e64bd6 100644 --- a/ext/saml2sp4ui/common-lib/pom.xml +++ b/ext/saml2sp4ui/common-lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SAML2 SP4UI Common Lib diff --git a/ext/saml2sp4ui/logic/pom.xml b/ext/saml2sp4ui/logic/pom.xml index daf8b8146e9..02e0f59c0d8 100644 --- a/ext/saml2sp4ui/logic/pom.xml +++ b/ext/saml2sp4ui/logic/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SAML2 SP4UI Logic diff --git a/ext/saml2sp4ui/persistence-api/pom.xml b/ext/saml2sp4ui/persistence-api/pom.xml index d38be815b2a..f96b0c108ab 100644 --- a/ext/saml2sp4ui/persistence-api/pom.xml +++ b/ext/saml2sp4ui/persistence-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SAML2 SP4UI Persistence API diff --git a/ext/saml2sp4ui/persistence-jpa/pom.xml b/ext/saml2sp4ui/persistence-jpa/pom.xml index 112aba9e9dc..a6ef9fd82ed 100644 --- a/ext/saml2sp4ui/persistence-jpa/pom.xml +++ b/ext/saml2sp4ui/persistence-jpa/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SAML2 SP4UI Persistence JPA diff --git a/ext/saml2sp4ui/pom.xml b/ext/saml2sp4ui/pom.xml index ba7784a423d..53c4df5d5cf 100644 --- a/ext/saml2sp4ui/pom.xml +++ b/ext/saml2sp4ui/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-ext - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SAML2 SP4UI diff --git a/ext/saml2sp4ui/provisioning-api/pom.xml b/ext/saml2sp4ui/provisioning-api/pom.xml index a31f23877e2..b1fd1f7a8b5 100644 --- a/ext/saml2sp4ui/provisioning-api/pom.xml +++ b/ext/saml2sp4ui/provisioning-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SAML2 SP4UI Provisioning API diff --git a/ext/saml2sp4ui/provisioning-java/pom.xml b/ext/saml2sp4ui/provisioning-java/pom.xml index d912a87181b..77d048c2070 100644 --- a/ext/saml2sp4ui/provisioning-java/pom.xml +++ b/ext/saml2sp4ui/provisioning-java/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SAML2 SP4UI Provisioning Java diff --git a/ext/saml2sp4ui/rest-api/pom.xml b/ext/saml2sp4ui/rest-api/pom.xml index b43e35f5db6..f2921cdbfc1 100644 --- a/ext/saml2sp4ui/rest-api/pom.xml +++ b/ext/saml2sp4ui/rest-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SAML2 SP4UI REST API diff --git a/ext/saml2sp4ui/rest-cxf/pom.xml b/ext/saml2sp4ui/rest-cxf/pom.xml index fb776ce33d8..71268c49f43 100644 --- a/ext/saml2sp4ui/rest-cxf/pom.xml +++ b/ext/saml2sp4ui/rest-cxf/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SAML2 SP4UI REST CXF diff --git a/ext/scimv2/client-console/pom.xml b/ext/scimv2/client-console/pom.xml index a7b476bc1c9..38770ed94b8 100644 --- a/ext/scimv2/client-console/pom.xml +++ b/ext/scimv2/client-console/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-scimv2 - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SCIMv2 Client Console diff --git a/ext/scimv2/common-lib/pom.xml b/ext/scimv2/common-lib/pom.xml index f6647d3e9cb..1a929742405 100644 --- a/ext/scimv2/common-lib/pom.xml +++ b/ext/scimv2/common-lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-scimv2 - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SCIMv2 Common Lib diff --git a/ext/scimv2/logic/pom.xml b/ext/scimv2/logic/pom.xml index cd2551a6c55..59e6b2156ec 100644 --- a/ext/scimv2/logic/pom.xml +++ b/ext/scimv2/logic/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-scimv2 - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SCIMv2 Logic diff --git a/ext/scimv2/pom.xml b/ext/scimv2/pom.xml index c39afca1d4e..3295657e2ae 100644 --- a/ext/scimv2/pom.xml +++ b/ext/scimv2/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-ext - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SCIMv2 diff --git a/ext/scimv2/rest-api/pom.xml b/ext/scimv2/rest-api/pom.xml index 0acc46eec21..10c576f2765 100644 --- a/ext/scimv2/rest-api/pom.xml +++ b/ext/scimv2/rest-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-scimv2 - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SCIMv2 REST API diff --git a/ext/scimv2/rest-cxf/pom.xml b/ext/scimv2/rest-cxf/pom.xml index 06de1374ffe..870fd30f23a 100644 --- a/ext/scimv2/rest-cxf/pom.xml +++ b/ext/scimv2/rest-cxf/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-scimv2 - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SCIMv2 REST CXF diff --git a/ext/scimv2/scim-rest-api/pom.xml b/ext/scimv2/scim-rest-api/pom.xml index 33d57a5c6f9..7827117155b 100644 --- a/ext/scimv2/scim-rest-api/pom.xml +++ b/ext/scimv2/scim-rest-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-scimv2 - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SCIMv2 SCIM REST API diff --git a/ext/scimv2/scim-rest-cxf/pom.xml b/ext/scimv2/scim-rest-cxf/pom.xml index ad03a2629c9..7b7a489daed 100644 --- a/ext/scimv2/scim-rest-cxf/pom.xml +++ b/ext/scimv2/scim-rest-cxf/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-scimv2 - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Ext: SCIMv2 SCIM REST CXF diff --git a/fit/build-tools/pom.xml b/fit/build-tools/pom.xml index 3fb83af68e7..c35a55dabe2 100644 --- a/fit/build-tools/pom.xml +++ b/fit/build-tools/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-fit - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope FIT Build Tools diff --git a/fit/console-reference/pom.xml b/fit/console-reference/pom.xml index e893aad8273..c2c7ffce60d 100644 --- a/fit/console-reference/pom.xml +++ b/fit/console-reference/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-fit - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope FIT Console Reference diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml index 752681a4f17..cef071a8424 100644 --- a/fit/core-reference/pom.xml +++ b/fit/core-reference/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-fit - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope FIT Core Reference diff --git a/fit/enduser-reference/pom.xml b/fit/enduser-reference/pom.xml index f262aefc05f..0f143ae65ca 100644 --- a/fit/enduser-reference/pom.xml +++ b/fit/enduser-reference/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-fit - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope FIT Enduser Reference diff --git a/fit/persistence-embedded/pom.xml b/fit/persistence-embedded/pom.xml index 5b4876e22fb..f47cfc38327 100644 --- a/fit/persistence-embedded/pom.xml +++ b/fit/persistence-embedded/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-fit - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope FIT Persistence Embedded diff --git a/fit/pom.xml b/fit/pom.xml index 7fd94f925db..e507029c374 100644 --- a/fit/pom.xml +++ b/fit/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope FIT diff --git a/fit/wa-reference/pom.xml b/fit/wa-reference/pom.xml index 32af56830a0..e9b4a420631 100644 --- a/fit/wa-reference/pom.xml +++ b/fit/wa-reference/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-fit - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope FIT WA Reference diff --git a/pom.xml b/pom.xml index 414252301a8..76e23a96f52 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ under the License. org.apache.syncope syncope - 4.0.0-SNAPSHOT + 4.0.0 pom @@ -52,7 +52,7 @@ under the License. scm:git:https://gitbox.apache.org/repos/asf/syncope.git scm:git:https://gitbox.apache.org/repos/asf/syncope.git https://gitbox.apache.org/repos/asf?p=syncope.git - HEAD + syncope-4.0.0 @@ -392,7 +392,7 @@ under the License. - 2025-03-07T13:42:57Z + 2025-05-23T08:31:05Z ${project.version} 1.6.0.1 diff --git a/sra/pom.xml b/sra/pom.xml index 1a6c773f9e1..7dc591c5ffe 100644 --- a/sra/pom.xml +++ b/sra/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope SRA diff --git a/standalone/pom.xml b/standalone/pom.xml index a6df0832c89..13e44c57299 100644 --- a/standalone/pom.xml +++ b/standalone/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope Standalone Distribution diff --git a/wa/bootstrap/pom.xml b/wa/bootstrap/pom.xml index 9d952cb8d9f..1a1ce520036 100644 --- a/wa/bootstrap/pom.xml +++ b/wa/bootstrap/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-wa - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope WA Bootstrap diff --git a/wa/pom.xml b/wa/pom.xml index d9c12d70ccc..ecaf9e19979 100644 --- a/wa/pom.xml +++ b/wa/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope WA diff --git a/wa/starter/pom.xml b/wa/starter/pom.xml index 62ab33d62f2..2398fdd2ac1 100644 --- a/wa/starter/pom.xml +++ b/wa/starter/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-wa - 4.0.0-SNAPSHOT + 4.0.0 Apache Syncope WA Spring Boot Starter From 6597d0f07300be3137c941a75f82ce12459f3451 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Fri, 23 May 2025 10:40:22 +0200 Subject: [PATCH 063/579] prepare for next development iteration --- archetype/pom.xml | 2 +- client/am/console/pom.xml | 2 +- client/am/enduser/pom.xml | 2 +- client/am/lib/pom.xml | 2 +- client/am/pom.xml | 2 +- client/idm/console/pom.xml | 2 +- client/idm/lib/pom.xml | 2 +- client/idm/pom.xml | 2 +- client/idrepo/common-ui/pom.xml | 2 +- client/idrepo/console/pom.xml | 2 +- client/idrepo/enduser/pom.xml | 2 +- client/idrepo/lib/pom.xml | 2 +- client/idrepo/pom.xml | 2 +- client/pom.xml | 2 +- common/am/lib/pom.xml | 2 +- common/am/pom.xml | 2 +- common/am/rest-api/pom.xml | 2 +- common/idm/lib/pom.xml | 2 +- common/idm/pom.xml | 2 +- common/idm/rest-api/pom.xml | 2 +- common/idrepo/lib/pom.xml | 2 +- common/idrepo/pom.xml | 2 +- common/idrepo/rest-api/pom.xml | 2 +- common/keymaster/client-api/pom.xml | 2 +- common/keymaster/client-zookeeper/pom.xml | 2 +- common/keymaster/pom.xml | 2 +- common/keymaster/self/client-self/pom.xml | 2 +- common/keymaster/self/pom.xml | 2 +- common/keymaster/self/rest-api/pom.xml | 2 +- common/pom.xml | 2 +- core/am/logic/pom.xml | 2 +- core/am/pom.xml | 2 +- core/am/rest-cxf/pom.xml | 2 +- core/idm/logic/pom.xml | 2 +- core/idm/pom.xml | 2 +- core/idm/rest-cxf/pom.xml | 2 +- core/idrepo/logic/pom.xml | 2 +- core/idrepo/pom.xml | 2 +- core/idrepo/rest-cxf/pom.xml | 2 +- core/persistence-api/pom.xml | 2 +- core/persistence-common/pom.xml | 2 +- core/persistence-jpa-upgrader/pom.xml | 2 +- core/persistence-jpa/pom.xml | 2 +- core/persistence-neo4j/pom.xml | 2 +- core/pom.xml | 2 +- core/provisioning-api/pom.xml | 2 +- core/provisioning-java/pom.xml | 2 +- core/self-keymaster-starter/pom.xml | 2 +- core/spring/pom.xml | 2 +- core/starter/pom.xml | 2 +- core/workflow-api/pom.xml | 2 +- core/workflow-java/pom.xml | 2 +- docker/console/pom.xml | 2 +- docker/core/pom.xml | 2 +- docker/enduser/pom.xml | 2 +- docker/pom.xml | 2 +- docker/sra/pom.xml | 2 +- docker/wa/pom.xml | 2 +- ext/elasticsearch/client-elasticsearch/pom.xml | 2 +- ext/elasticsearch/persistence/pom.xml | 2 +- ext/elasticsearch/pom.xml | 2 +- ext/elasticsearch/provisioning-java/pom.xml | 2 +- ext/flowable/client-console/pom.xml | 2 +- ext/flowable/client-enduser/pom.xml | 2 +- ext/flowable/common-lib/pom.xml | 2 +- ext/flowable/flowable-bpmn/pom.xml | 2 +- ext/flowable/logic/pom.xml | 2 +- ext/flowable/pom.xml | 2 +- ext/flowable/rest-api/pom.xml | 2 +- ext/flowable/rest-cxf/pom.xml | 2 +- ext/oidcc4ui/client-common-ui/pom.xml | 2 +- ext/oidcc4ui/client-console/pom.xml | 2 +- ext/oidcc4ui/client-enduser/pom.xml | 2 +- ext/oidcc4ui/common-lib/pom.xml | 2 +- ext/oidcc4ui/logic/pom.xml | 2 +- ext/oidcc4ui/persistence-api/pom.xml | 2 +- ext/oidcc4ui/persistence-jpa/pom.xml | 2 +- ext/oidcc4ui/pom.xml | 2 +- ext/oidcc4ui/provisioning-api/pom.xml | 2 +- ext/oidcc4ui/provisioning-java/pom.xml | 2 +- ext/oidcc4ui/rest-api/pom.xml | 2 +- ext/oidcc4ui/rest-cxf/pom.xml | 2 +- ext/openfga/client-openfga/pom.xml | 2 +- ext/openfga/pom.xml | 2 +- ext/openfga/provisioning-java/pom.xml | 2 +- ext/opensearch/client-opensearch/pom.xml | 2 +- ext/opensearch/persistence/pom.xml | 2 +- ext/opensearch/pom.xml | 2 +- ext/opensearch/provisioning-java/pom.xml | 2 +- ext/pom.xml | 2 +- ext/saml2sp4ui/client-common-ui/pom.xml | 2 +- ext/saml2sp4ui/client-console/pom.xml | 2 +- ext/saml2sp4ui/client-enduser/pom.xml | 2 +- ext/saml2sp4ui/common-lib/pom.xml | 2 +- ext/saml2sp4ui/logic/pom.xml | 2 +- ext/saml2sp4ui/persistence-api/pom.xml | 2 +- ext/saml2sp4ui/persistence-jpa/pom.xml | 2 +- ext/saml2sp4ui/pom.xml | 2 +- ext/saml2sp4ui/provisioning-api/pom.xml | 2 +- ext/saml2sp4ui/provisioning-java/pom.xml | 2 +- ext/saml2sp4ui/rest-api/pom.xml | 2 +- ext/saml2sp4ui/rest-cxf/pom.xml | 2 +- ext/scimv2/client-console/pom.xml | 2 +- ext/scimv2/common-lib/pom.xml | 2 +- ext/scimv2/logic/pom.xml | 2 +- ext/scimv2/pom.xml | 2 +- ext/scimv2/rest-api/pom.xml | 2 +- ext/scimv2/rest-cxf/pom.xml | 2 +- ext/scimv2/scim-rest-api/pom.xml | 2 +- ext/scimv2/scim-rest-cxf/pom.xml | 2 +- fit/build-tools/pom.xml | 2 +- fit/console-reference/pom.xml | 2 +- fit/core-reference/pom.xml | 2 +- fit/enduser-reference/pom.xml | 2 +- fit/persistence-embedded/pom.xml | 2 +- fit/pom.xml | 2 +- fit/wa-reference/pom.xml | 2 +- pom.xml | 6 +++--- sra/pom.xml | 2 +- standalone/pom.xml | 2 +- wa/bootstrap/pom.xml | 2 +- wa/pom.xml | 2 +- wa/starter/pom.xml | 2 +- 123 files changed, 125 insertions(+), 125 deletions(-) diff --git a/archetype/pom.xml b/archetype/pom.xml index b5c5607325d..f09c8cd2a85 100644 --- a/archetype/pom.xml +++ b/archetype/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Archetype diff --git a/client/am/console/pom.xml b/client/am/console/pom.xml index 21d7aeea979..36c70480abe 100644 --- a/client/am/console/pom.xml +++ b/client/am/console/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.client syncope-client-am - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Client AM Console diff --git a/client/am/enduser/pom.xml b/client/am/enduser/pom.xml index ffc42a00e39..03961c6e8b6 100644 --- a/client/am/enduser/pom.xml +++ b/client/am/enduser/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.client syncope-client-am - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Client AM Enduser diff --git a/client/am/lib/pom.xml b/client/am/lib/pom.xml index 4d7686f4714..70731860f0c 100644 --- a/client/am/lib/pom.xml +++ b/client/am/lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.client syncope-client-am - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Client AM Lib diff --git a/client/am/pom.xml b/client/am/pom.xml index c93cb45713b..c7fb6658a7a 100644 --- a/client/am/pom.xml +++ b/client/am/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-client - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Client AM diff --git a/client/idm/console/pom.xml b/client/idm/console/pom.xml index 6d46b811712..2f003ff77f7 100644 --- a/client/idm/console/pom.xml +++ b/client/idm/console/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.client syncope-client-idm - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Client IdM Console diff --git a/client/idm/lib/pom.xml b/client/idm/lib/pom.xml index 19e0b3a1584..e44375fc325 100644 --- a/client/idm/lib/pom.xml +++ b/client/idm/lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.client syncope-client-idm - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Client IdM Lib diff --git a/client/idm/pom.xml b/client/idm/pom.xml index 6f645f19162..11bb45730c1 100644 --- a/client/idm/pom.xml +++ b/client/idm/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-client - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Client IdM diff --git a/client/idrepo/common-ui/pom.xml b/client/idrepo/common-ui/pom.xml index 04d9fc2aacf..083104c7cd1 100644 --- a/client/idrepo/common-ui/pom.xml +++ b/client/idrepo/common-ui/pom.xml @@ -22,7 +22,7 @@ under the License. org.apache.syncope.client syncope-client-idrepo - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Client IdRepo Common UI diff --git a/client/idrepo/console/pom.xml b/client/idrepo/console/pom.xml index a15f3866a87..ff08f861f2b 100644 --- a/client/idrepo/console/pom.xml +++ b/client/idrepo/console/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.client syncope-client-idrepo - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Client IdRepo Console diff --git a/client/idrepo/enduser/pom.xml b/client/idrepo/enduser/pom.xml index 17df5a143e9..973f63b53f6 100644 --- a/client/idrepo/enduser/pom.xml +++ b/client/idrepo/enduser/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.client syncope-client-idrepo - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Client IdRepo Enduser diff --git a/client/idrepo/lib/pom.xml b/client/idrepo/lib/pom.xml index 575cc831590..d5137ea26ea 100644 --- a/client/idrepo/lib/pom.xml +++ b/client/idrepo/lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.client syncope-client-idrepo - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Client IdRepo Lib diff --git a/client/idrepo/pom.xml b/client/idrepo/pom.xml index d6118f297da..7dddada7672 100644 --- a/client/idrepo/pom.xml +++ b/client/idrepo/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-client - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Client IdRepo diff --git a/client/pom.xml b/client/pom.xml index c5327e8f43c..6085f803749 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Client diff --git a/common/am/lib/pom.xml b/common/am/lib/pom.xml index 51a1d54b449..a867e4c5269 100644 --- a/common/am/lib/pom.xml +++ b/common/am/lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common syncope-common-am - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Common AM Lib diff --git a/common/am/pom.xml b/common/am/pom.xml index 58f3d93e8f3..5bf120dd44c 100644 --- a/common/am/pom.xml +++ b/common/am/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-common - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Common AM diff --git a/common/am/rest-api/pom.xml b/common/am/rest-api/pom.xml index c834b15ec7a..ff9f756e22a 100644 --- a/common/am/rest-api/pom.xml +++ b/common/am/rest-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common syncope-common-am - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Common AM REST API diff --git a/common/idm/lib/pom.xml b/common/idm/lib/pom.xml index 2206f394053..e0442fb7e1d 100644 --- a/common/idm/lib/pom.xml +++ b/common/idm/lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common syncope-common-idm - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Common IdM Lib diff --git a/common/idm/pom.xml b/common/idm/pom.xml index d96040a4133..318e402d1fc 100644 --- a/common/idm/pom.xml +++ b/common/idm/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-common - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Common IdM diff --git a/common/idm/rest-api/pom.xml b/common/idm/rest-api/pom.xml index 9f01978b67b..511f4a2b58d 100644 --- a/common/idm/rest-api/pom.xml +++ b/common/idm/rest-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common syncope-common-idm - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Common IdM REST API diff --git a/common/idrepo/lib/pom.xml b/common/idrepo/lib/pom.xml index 3fb9a5dcc4a..a6b861c0618 100644 --- a/common/idrepo/lib/pom.xml +++ b/common/idrepo/lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common syncope-common-idrepo - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Common IdRepo Lib diff --git a/common/idrepo/pom.xml b/common/idrepo/pom.xml index 72be6586e94..73a8d6aa676 100644 --- a/common/idrepo/pom.xml +++ b/common/idrepo/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-common - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Common IdRepo diff --git a/common/idrepo/rest-api/pom.xml b/common/idrepo/rest-api/pom.xml index be22b02879f..94007bb640d 100644 --- a/common/idrepo/rest-api/pom.xml +++ b/common/idrepo/rest-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common syncope-common-idrepo - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Common IdRepo REST API diff --git a/common/keymaster/client-api/pom.xml b/common/keymaster/client-api/pom.xml index ff27051b975..7dd67c7aa25 100644 --- a/common/keymaster/client-api/pom.xml +++ b/common/keymaster/client-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common syncope-common-keymaster - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Common Keymaster Client API diff --git a/common/keymaster/client-zookeeper/pom.xml b/common/keymaster/client-zookeeper/pom.xml index c9a418dae14..ed3ebca32d7 100644 --- a/common/keymaster/client-zookeeper/pom.xml +++ b/common/keymaster/client-zookeeper/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common syncope-common-keymaster - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Common Keymaster Client Zookeeper diff --git a/common/keymaster/pom.xml b/common/keymaster/pom.xml index 3daad836498..b1aef0ce871 100644 --- a/common/keymaster/pom.xml +++ b/common/keymaster/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-common - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Common Keymaster diff --git a/common/keymaster/self/client-self/pom.xml b/common/keymaster/self/client-self/pom.xml index 2128567bf34..d5d9a6dc8f1 100644 --- a/common/keymaster/self/client-self/pom.xml +++ b/common/keymaster/self/client-self/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common.keymaster syncope-common-keymaster-self - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Common Keymaster Client Self diff --git a/common/keymaster/self/pom.xml b/common/keymaster/self/pom.xml index efd07cb3c88..3b56e68b18f 100644 --- a/common/keymaster/self/pom.xml +++ b/common/keymaster/self/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common syncope-common-keymaster - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Common Keymaster Self diff --git a/common/keymaster/self/rest-api/pom.xml b/common/keymaster/self/rest-api/pom.xml index 95a03db6c69..d67a7a208ee 100644 --- a/common/keymaster/self/rest-api/pom.xml +++ b/common/keymaster/self/rest-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.common.keymaster syncope-common-keymaster-self - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Common Keymaster Self REST API diff --git a/common/pom.xml b/common/pom.xml index a05fb9b3c55..9a5d7f4a014 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Common diff --git a/core/am/logic/pom.xml b/core/am/logic/pom.xml index b6197a17c95..7ce6b412692 100644 --- a/core/am/logic/pom.xml +++ b/core/am/logic/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.core syncope-core-am - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core AM Logic diff --git a/core/am/pom.xml b/core/am/pom.xml index 5052ecdf1cf..719010d7d55 100644 --- a/core/am/pom.xml +++ b/core/am/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core AM diff --git a/core/am/rest-cxf/pom.xml b/core/am/rest-cxf/pom.xml index c56325958ae..25025566be5 100644 --- a/core/am/rest-cxf/pom.xml +++ b/core/am/rest-cxf/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.core syncope-core-am - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core AM REST CXF diff --git a/core/idm/logic/pom.xml b/core/idm/logic/pom.xml index 0082007c5ad..dcb6f82f99e 100644 --- a/core/idm/logic/pom.xml +++ b/core/idm/logic/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.core syncope-core-idm - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core IdM Logic diff --git a/core/idm/pom.xml b/core/idm/pom.xml index b77797186c3..b4352441485 100644 --- a/core/idm/pom.xml +++ b/core/idm/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core IdM diff --git a/core/idm/rest-cxf/pom.xml b/core/idm/rest-cxf/pom.xml index 12bc9f66067..0fc590efdc6 100644 --- a/core/idm/rest-cxf/pom.xml +++ b/core/idm/rest-cxf/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.core syncope-core-idm - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core IdM REST CXF diff --git a/core/idrepo/logic/pom.xml b/core/idrepo/logic/pom.xml index d4498d1309f..15b43970305 100644 --- a/core/idrepo/logic/pom.xml +++ b/core/idrepo/logic/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.core syncope-core-idrepo - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core IdRepo Logic diff --git a/core/idrepo/pom.xml b/core/idrepo/pom.xml index 69d4eedf968..732da05f595 100644 --- a/core/idrepo/pom.xml +++ b/core/idrepo/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core IdRepo diff --git a/core/idrepo/rest-cxf/pom.xml b/core/idrepo/rest-cxf/pom.xml index edfb817e9b9..d6501b3493a 100644 --- a/core/idrepo/rest-cxf/pom.xml +++ b/core/idrepo/rest-cxf/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.core syncope-core-idrepo - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core IdRepo REST CXF diff --git a/core/persistence-api/pom.xml b/core/persistence-api/pom.xml index 3173439ac5e..0ec69d9fd76 100644 --- a/core/persistence-api/pom.xml +++ b/core/persistence-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core Persistence API diff --git a/core/persistence-common/pom.xml b/core/persistence-common/pom.xml index a15b514fe16..71f69ad6b09 100644 --- a/core/persistence-common/pom.xml +++ b/core/persistence-common/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core Persistence Common diff --git a/core/persistence-jpa-upgrader/pom.xml b/core/persistence-jpa-upgrader/pom.xml index d2e7ad982ca..8195ae1e040 100644 --- a/core/persistence-jpa-upgrader/pom.xml +++ b/core/persistence-jpa-upgrader/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core Persistence JPA Upgrader diff --git a/core/persistence-jpa/pom.xml b/core/persistence-jpa/pom.xml index 1a8403b6fec..f4dfd2aa03f 100644 --- a/core/persistence-jpa/pom.xml +++ b/core/persistence-jpa/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core Persistence JPA diff --git a/core/persistence-neo4j/pom.xml b/core/persistence-neo4j/pom.xml index f4c81e3d5fe..1c835557f2f 100644 --- a/core/persistence-neo4j/pom.xml +++ b/core/persistence-neo4j/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core Persistence Neo4j diff --git a/core/pom.xml b/core/pom.xml index 7a140ed86f0..a8ae4c7474e 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core diff --git a/core/provisioning-api/pom.xml b/core/provisioning-api/pom.xml index f3a687dd783..b228a439b44 100644 --- a/core/provisioning-api/pom.xml +++ b/core/provisioning-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core Provisioning API diff --git a/core/provisioning-java/pom.xml b/core/provisioning-java/pom.xml index c2909f3f995..221eb837dcf 100644 --- a/core/provisioning-java/pom.xml +++ b/core/provisioning-java/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core Provisioning Java diff --git a/core/self-keymaster-starter/pom.xml b/core/self-keymaster-starter/pom.xml index 9cacd9f66a2..3b03313b391 100644 --- a/core/self-keymaster-starter/pom.xml +++ b/core/self-keymaster-starter/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core Spring Boot Self Keymaster diff --git a/core/spring/pom.xml b/core/spring/pom.xml index 2e6f482c6fb..44a3fd1c7b2 100644 --- a/core/spring/pom.xml +++ b/core/spring/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core Spring diff --git a/core/starter/pom.xml b/core/starter/pom.xml index fbe285f34ca..ce11317295e 100644 --- a/core/starter/pom.xml +++ b/core/starter/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core Spring Boot Starter diff --git a/core/workflow-api/pom.xml b/core/workflow-api/pom.xml index fe0f5ab84cf..50da41645d7 100644 --- a/core/workflow-api/pom.xml +++ b/core/workflow-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core Workflow API diff --git a/core/workflow-java/pom.xml b/core/workflow-java/pom.xml index 0623dbd6749..c2340612538 100644 --- a/core/workflow-java/pom.xml +++ b/core/workflow-java/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-core - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Core Workflow Java diff --git a/docker/console/pom.xml b/docker/console/pom.xml index dd131f8d17a..8fd5c9afb5c 100644 --- a/docker/console/pom.xml +++ b/docker/console/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-docker - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Docker Console diff --git a/docker/core/pom.xml b/docker/core/pom.xml index 727df16191d..81e8c3fef1f 100644 --- a/docker/core/pom.xml +++ b/docker/core/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-docker - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Docker Core diff --git a/docker/enduser/pom.xml b/docker/enduser/pom.xml index 6ca2ff54676..f74e31024c1 100644 --- a/docker/enduser/pom.xml +++ b/docker/enduser/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-docker - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Docker Enduser diff --git a/docker/pom.xml b/docker/pom.xml index 94f9832e724..88d55cb7ef3 100644 --- a/docker/pom.xml +++ b/docker/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Docker diff --git a/docker/sra/pom.xml b/docker/sra/pom.xml index 15231616a4d..1349c0aec2a 100644 --- a/docker/sra/pom.xml +++ b/docker/sra/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-docker - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Docker SRA diff --git a/docker/wa/pom.xml b/docker/wa/pom.xml index 3a9f0c15ebd..5066e5519fb 100644 --- a/docker/wa/pom.xml +++ b/docker/wa/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-docker - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Docker WA diff --git a/ext/elasticsearch/client-elasticsearch/pom.xml b/ext/elasticsearch/client-elasticsearch/pom.xml index 82ac8e5305c..498ed26b909 100644 --- a/ext/elasticsearch/client-elasticsearch/pom.xml +++ b/ext/elasticsearch/client-elasticsearch/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-elasticsearch - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: Elasticsearch Client diff --git a/ext/elasticsearch/persistence/pom.xml b/ext/elasticsearch/persistence/pom.xml index 95ab2ab534d..66c53e6af09 100644 --- a/ext/elasticsearch/persistence/pom.xml +++ b/ext/elasticsearch/persistence/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-elasticsearch - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: Elasticsearch Persistence diff --git a/ext/elasticsearch/pom.xml b/ext/elasticsearch/pom.xml index af8703cf250..8f31ef09d90 100644 --- a/ext/elasticsearch/pom.xml +++ b/ext/elasticsearch/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-ext - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: Elasticsearch diff --git a/ext/elasticsearch/provisioning-java/pom.xml b/ext/elasticsearch/provisioning-java/pom.xml index facd72cbda2..c7526bc4a76 100644 --- a/ext/elasticsearch/provisioning-java/pom.xml +++ b/ext/elasticsearch/provisioning-java/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-elasticsearch - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: Elasticsearch Provisioning Java diff --git a/ext/flowable/client-console/pom.xml b/ext/flowable/client-console/pom.xml index 4bf40afd0bd..6f0e4e9da08 100644 --- a/ext/flowable/client-console/pom.xml +++ b/ext/flowable/client-console/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-flowable - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: Flowable Client Console diff --git a/ext/flowable/client-enduser/pom.xml b/ext/flowable/client-enduser/pom.xml index fd611e10881..302126e716b 100644 --- a/ext/flowable/client-enduser/pom.xml +++ b/ext/flowable/client-enduser/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-flowable - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: Flowable Client Enduser diff --git a/ext/flowable/common-lib/pom.xml b/ext/flowable/common-lib/pom.xml index a3fe6f15a13..8028886bd0b 100644 --- a/ext/flowable/common-lib/pom.xml +++ b/ext/flowable/common-lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-flowable - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: Flowable Common Lib diff --git a/ext/flowable/flowable-bpmn/pom.xml b/ext/flowable/flowable-bpmn/pom.xml index e392cda7bcd..3a1854a26ff 100644 --- a/ext/flowable/flowable-bpmn/pom.xml +++ b/ext/flowable/flowable-bpmn/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-flowable - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: Flowable BPMN diff --git a/ext/flowable/logic/pom.xml b/ext/flowable/logic/pom.xml index 396db1cc8dd..969bda57202 100644 --- a/ext/flowable/logic/pom.xml +++ b/ext/flowable/logic/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-flowable - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: Flowable Logic diff --git a/ext/flowable/pom.xml b/ext/flowable/pom.xml index 412efdfe9d4..3fec81291de 100644 --- a/ext/flowable/pom.xml +++ b/ext/flowable/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-ext - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: Flowable diff --git a/ext/flowable/rest-api/pom.xml b/ext/flowable/rest-api/pom.xml index ee02d64979f..953f1b624b0 100644 --- a/ext/flowable/rest-api/pom.xml +++ b/ext/flowable/rest-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-flowable - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: Flowable REST API diff --git a/ext/flowable/rest-cxf/pom.xml b/ext/flowable/rest-cxf/pom.xml index c4a0f181f83..eee3ff6c500 100644 --- a/ext/flowable/rest-cxf/pom.xml +++ b/ext/flowable/rest-cxf/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-flowable - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: Flowable REST CXF diff --git a/ext/oidcc4ui/client-common-ui/pom.xml b/ext/oidcc4ui/client-common-ui/pom.xml index 982206130e9..930fd43aa34 100644 --- a/ext/oidcc4ui/client-common-ui/pom.xml +++ b/ext/oidcc4ui/client-common-ui/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: OIDC C4UI Common UI diff --git a/ext/oidcc4ui/client-console/pom.xml b/ext/oidcc4ui/client-console/pom.xml index d0d1cfb8659..7f72169f3f7 100644 --- a/ext/oidcc4ui/client-console/pom.xml +++ b/ext/oidcc4ui/client-console/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: OIDC C4UI Console diff --git a/ext/oidcc4ui/client-enduser/pom.xml b/ext/oidcc4ui/client-enduser/pom.xml index 48c84962515..ed033fa05be 100644 --- a/ext/oidcc4ui/client-enduser/pom.xml +++ b/ext/oidcc4ui/client-enduser/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: OIDC C4UI Enduser diff --git a/ext/oidcc4ui/common-lib/pom.xml b/ext/oidcc4ui/common-lib/pom.xml index 877d1640cd5..85851c431d1 100644 --- a/ext/oidcc4ui/common-lib/pom.xml +++ b/ext/oidcc4ui/common-lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: OIDC C4UI Common Lib diff --git a/ext/oidcc4ui/logic/pom.xml b/ext/oidcc4ui/logic/pom.xml index 8392104b3a6..a8631a8913b 100644 --- a/ext/oidcc4ui/logic/pom.xml +++ b/ext/oidcc4ui/logic/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: OIDC C4UI Logic diff --git a/ext/oidcc4ui/persistence-api/pom.xml b/ext/oidcc4ui/persistence-api/pom.xml index 605464d1d89..8d3151b8d32 100644 --- a/ext/oidcc4ui/persistence-api/pom.xml +++ b/ext/oidcc4ui/persistence-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: OIDC C4UI Persistence API diff --git a/ext/oidcc4ui/persistence-jpa/pom.xml b/ext/oidcc4ui/persistence-jpa/pom.xml index eaf46b1bd56..99b5e3e5f10 100644 --- a/ext/oidcc4ui/persistence-jpa/pom.xml +++ b/ext/oidcc4ui/persistence-jpa/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: OIDC C4UI Persistence JPA diff --git a/ext/oidcc4ui/pom.xml b/ext/oidcc4ui/pom.xml index b8d1ade26e2..7ed3f296bec 100644 --- a/ext/oidcc4ui/pom.xml +++ b/ext/oidcc4ui/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-ext - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: OIDC C4UI diff --git a/ext/oidcc4ui/provisioning-api/pom.xml b/ext/oidcc4ui/provisioning-api/pom.xml index 4a234ae16c2..9093c64d12c 100644 --- a/ext/oidcc4ui/provisioning-api/pom.xml +++ b/ext/oidcc4ui/provisioning-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: OIDC C4UI Provisioning API diff --git a/ext/oidcc4ui/provisioning-java/pom.xml b/ext/oidcc4ui/provisioning-java/pom.xml index 769e65d335b..66013c1f40c 100644 --- a/ext/oidcc4ui/provisioning-java/pom.xml +++ b/ext/oidcc4ui/provisioning-java/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: OIDC C4UI Provisioning Java diff --git a/ext/oidcc4ui/rest-api/pom.xml b/ext/oidcc4ui/rest-api/pom.xml index 7ee0f3c2b57..14d52678c0b 100644 --- a/ext/oidcc4ui/rest-api/pom.xml +++ b/ext/oidcc4ui/rest-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: OIDC C4UI REST API diff --git a/ext/oidcc4ui/rest-cxf/pom.xml b/ext/oidcc4ui/rest-cxf/pom.xml index ebbca71b502..8b58ade09d0 100644 --- a/ext/oidcc4ui/rest-cxf/pom.xml +++ b/ext/oidcc4ui/rest-cxf/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-oidcc4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: OIDC C4UI REST CXF diff --git a/ext/openfga/client-openfga/pom.xml b/ext/openfga/client-openfga/pom.xml index 0901a5d04b1..a21d87a675c 100644 --- a/ext/openfga/client-openfga/pom.xml +++ b/ext/openfga/client-openfga/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-openfga - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: OpenFGA Client diff --git a/ext/openfga/pom.xml b/ext/openfga/pom.xml index db5765daf88..79ea88b1834 100644 --- a/ext/openfga/pom.xml +++ b/ext/openfga/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-ext - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: OpenFGA diff --git a/ext/openfga/provisioning-java/pom.xml b/ext/openfga/provisioning-java/pom.xml index e5300bb307c..d4e38c0f08d 100644 --- a/ext/openfga/provisioning-java/pom.xml +++ b/ext/openfga/provisioning-java/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-openfga - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: OpenFGA Provisioning Java diff --git a/ext/opensearch/client-opensearch/pom.xml b/ext/opensearch/client-opensearch/pom.xml index 748cd60dcc2..8956a129f3c 100644 --- a/ext/opensearch/client-opensearch/pom.xml +++ b/ext/opensearch/client-opensearch/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-opensearch - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: OpenSearch Client diff --git a/ext/opensearch/persistence/pom.xml b/ext/opensearch/persistence/pom.xml index 10951f3f481..9a00b0cc067 100644 --- a/ext/opensearch/persistence/pom.xml +++ b/ext/opensearch/persistence/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-opensearch - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: OpenSearch Persistence diff --git a/ext/opensearch/pom.xml b/ext/opensearch/pom.xml index 686cc6a3b19..860d888eb26 100644 --- a/ext/opensearch/pom.xml +++ b/ext/opensearch/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-ext - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: OpenSearch diff --git a/ext/opensearch/provisioning-java/pom.xml b/ext/opensearch/provisioning-java/pom.xml index eba02c48787..fdc6a5812ff 100644 --- a/ext/opensearch/provisioning-java/pom.xml +++ b/ext/opensearch/provisioning-java/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-opensearch - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: OpenSearch Provisioning Java diff --git a/ext/pom.xml b/ext/pom.xml index 8cc67538dfb..74e0c7c87d6 100644 --- a/ext/pom.xml +++ b/ext/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext diff --git a/ext/saml2sp4ui/client-common-ui/pom.xml b/ext/saml2sp4ui/client-common-ui/pom.xml index b8b3d0e9335..b96e6c1aef6 100644 --- a/ext/saml2sp4ui/client-common-ui/pom.xml +++ b/ext/saml2sp4ui/client-common-ui/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SAML2 SP4UI Common UI diff --git a/ext/saml2sp4ui/client-console/pom.xml b/ext/saml2sp4ui/client-console/pom.xml index e7fc15f290d..7f25d6f9234 100644 --- a/ext/saml2sp4ui/client-console/pom.xml +++ b/ext/saml2sp4ui/client-console/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SAML2 SP4UI Client Console diff --git a/ext/saml2sp4ui/client-enduser/pom.xml b/ext/saml2sp4ui/client-enduser/pom.xml index 31cb240d7d9..48b7afcb0ed 100644 --- a/ext/saml2sp4ui/client-enduser/pom.xml +++ b/ext/saml2sp4ui/client-enduser/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SAML2 SP4UI Client Enduser diff --git a/ext/saml2sp4ui/common-lib/pom.xml b/ext/saml2sp4ui/common-lib/pom.xml index 14a46e64bd6..ff95a5427b4 100644 --- a/ext/saml2sp4ui/common-lib/pom.xml +++ b/ext/saml2sp4ui/common-lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SAML2 SP4UI Common Lib diff --git a/ext/saml2sp4ui/logic/pom.xml b/ext/saml2sp4ui/logic/pom.xml index 02e0f59c0d8..0fc7655bdcb 100644 --- a/ext/saml2sp4ui/logic/pom.xml +++ b/ext/saml2sp4ui/logic/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SAML2 SP4UI Logic diff --git a/ext/saml2sp4ui/persistence-api/pom.xml b/ext/saml2sp4ui/persistence-api/pom.xml index f96b0c108ab..7e700d236ca 100644 --- a/ext/saml2sp4ui/persistence-api/pom.xml +++ b/ext/saml2sp4ui/persistence-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SAML2 SP4UI Persistence API diff --git a/ext/saml2sp4ui/persistence-jpa/pom.xml b/ext/saml2sp4ui/persistence-jpa/pom.xml index a6ef9fd82ed..ed0d53f87f9 100644 --- a/ext/saml2sp4ui/persistence-jpa/pom.xml +++ b/ext/saml2sp4ui/persistence-jpa/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SAML2 SP4UI Persistence JPA diff --git a/ext/saml2sp4ui/pom.xml b/ext/saml2sp4ui/pom.xml index 53c4df5d5cf..cb654624886 100644 --- a/ext/saml2sp4ui/pom.xml +++ b/ext/saml2sp4ui/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-ext - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SAML2 SP4UI diff --git a/ext/saml2sp4ui/provisioning-api/pom.xml b/ext/saml2sp4ui/provisioning-api/pom.xml index b1fd1f7a8b5..dfecc0f4a83 100644 --- a/ext/saml2sp4ui/provisioning-api/pom.xml +++ b/ext/saml2sp4ui/provisioning-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SAML2 SP4UI Provisioning API diff --git a/ext/saml2sp4ui/provisioning-java/pom.xml b/ext/saml2sp4ui/provisioning-java/pom.xml index 77d048c2070..a6daf7f8d80 100644 --- a/ext/saml2sp4ui/provisioning-java/pom.xml +++ b/ext/saml2sp4ui/provisioning-java/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SAML2 SP4UI Provisioning Java diff --git a/ext/saml2sp4ui/rest-api/pom.xml b/ext/saml2sp4ui/rest-api/pom.xml index f2921cdbfc1..789ce4330bf 100644 --- a/ext/saml2sp4ui/rest-api/pom.xml +++ b/ext/saml2sp4ui/rest-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SAML2 SP4UI REST API diff --git a/ext/saml2sp4ui/rest-cxf/pom.xml b/ext/saml2sp4ui/rest-cxf/pom.xml index 71268c49f43..fb96a87101c 100644 --- a/ext/saml2sp4ui/rest-cxf/pom.xml +++ b/ext/saml2sp4ui/rest-cxf/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-saml2sp4ui - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SAML2 SP4UI REST CXF diff --git a/ext/scimv2/client-console/pom.xml b/ext/scimv2/client-console/pom.xml index 38770ed94b8..ea38a4d4278 100644 --- a/ext/scimv2/client-console/pom.xml +++ b/ext/scimv2/client-console/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-scimv2 - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SCIMv2 Client Console diff --git a/ext/scimv2/common-lib/pom.xml b/ext/scimv2/common-lib/pom.xml index 1a929742405..82f25e9c3ea 100644 --- a/ext/scimv2/common-lib/pom.xml +++ b/ext/scimv2/common-lib/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-scimv2 - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SCIMv2 Common Lib diff --git a/ext/scimv2/logic/pom.xml b/ext/scimv2/logic/pom.xml index 59e6b2156ec..c3a55d6cb64 100644 --- a/ext/scimv2/logic/pom.xml +++ b/ext/scimv2/logic/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-scimv2 - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SCIMv2 Logic diff --git a/ext/scimv2/pom.xml b/ext/scimv2/pom.xml index 3295657e2ae..9c5ee008629 100644 --- a/ext/scimv2/pom.xml +++ b/ext/scimv2/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-ext - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SCIMv2 diff --git a/ext/scimv2/rest-api/pom.xml b/ext/scimv2/rest-api/pom.xml index 10c576f2765..c05ef41a26b 100644 --- a/ext/scimv2/rest-api/pom.xml +++ b/ext/scimv2/rest-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-scimv2 - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SCIMv2 REST API diff --git a/ext/scimv2/rest-cxf/pom.xml b/ext/scimv2/rest-cxf/pom.xml index 870fd30f23a..5b5df3de5ce 100644 --- a/ext/scimv2/rest-cxf/pom.xml +++ b/ext/scimv2/rest-cxf/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-scimv2 - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SCIMv2 REST CXF diff --git a/ext/scimv2/scim-rest-api/pom.xml b/ext/scimv2/scim-rest-api/pom.xml index 7827117155b..714c2f98061 100644 --- a/ext/scimv2/scim-rest-api/pom.xml +++ b/ext/scimv2/scim-rest-api/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-scimv2 - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SCIMv2 SCIM REST API diff --git a/ext/scimv2/scim-rest-cxf/pom.xml b/ext/scimv2/scim-rest-cxf/pom.xml index 7b7a489daed..2162597ed04 100644 --- a/ext/scimv2/scim-rest-cxf/pom.xml +++ b/ext/scimv2/scim-rest-cxf/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope.ext syncope-ext-scimv2 - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Ext: SCIMv2 SCIM REST CXF diff --git a/fit/build-tools/pom.xml b/fit/build-tools/pom.xml index c35a55dabe2..56d10e3b553 100644 --- a/fit/build-tools/pom.xml +++ b/fit/build-tools/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-fit - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope FIT Build Tools diff --git a/fit/console-reference/pom.xml b/fit/console-reference/pom.xml index c2c7ffce60d..86a1f26d907 100644 --- a/fit/console-reference/pom.xml +++ b/fit/console-reference/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-fit - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope FIT Console Reference diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml index cef071a8424..3cc99388f32 100644 --- a/fit/core-reference/pom.xml +++ b/fit/core-reference/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-fit - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope FIT Core Reference diff --git a/fit/enduser-reference/pom.xml b/fit/enduser-reference/pom.xml index 0f143ae65ca..d9c3e5a176a 100644 --- a/fit/enduser-reference/pom.xml +++ b/fit/enduser-reference/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-fit - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope FIT Enduser Reference diff --git a/fit/persistence-embedded/pom.xml b/fit/persistence-embedded/pom.xml index f47cfc38327..268816bad47 100644 --- a/fit/persistence-embedded/pom.xml +++ b/fit/persistence-embedded/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-fit - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope FIT Persistence Embedded diff --git a/fit/pom.xml b/fit/pom.xml index e507029c374..1f53caf77d1 100644 --- a/fit/pom.xml +++ b/fit/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope FIT diff --git a/fit/wa-reference/pom.xml b/fit/wa-reference/pom.xml index e9b4a420631..6c49563717c 100644 --- a/fit/wa-reference/pom.xml +++ b/fit/wa-reference/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-fit - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope FIT WA Reference diff --git a/pom.xml b/pom.xml index 76e23a96f52..895f605aac0 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ under the License. org.apache.syncope syncope - 4.0.0 + 4.0.1-SNAPSHOT pom @@ -52,7 +52,7 @@ under the License. scm:git:https://gitbox.apache.org/repos/asf/syncope.git scm:git:https://gitbox.apache.org/repos/asf/syncope.git https://gitbox.apache.org/repos/asf?p=syncope.git - syncope-4.0.0 + HEAD @@ -392,7 +392,7 @@ under the License. - 2025-05-23T08:31:05Z + 2025-05-23T08:39:56Z ${project.version} 1.6.0.1 diff --git a/sra/pom.xml b/sra/pom.xml index 7dc591c5ffe..8938beb956e 100644 --- a/sra/pom.xml +++ b/sra/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope SRA diff --git a/standalone/pom.xml b/standalone/pom.xml index 13e44c57299..f7f4f0e0bb7 100644 --- a/standalone/pom.xml +++ b/standalone/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope Standalone Distribution diff --git a/wa/bootstrap/pom.xml b/wa/bootstrap/pom.xml index 1a1ce520036..16bb7cab740 100644 --- a/wa/bootstrap/pom.xml +++ b/wa/bootstrap/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-wa - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope WA Bootstrap diff --git a/wa/pom.xml b/wa/pom.xml index ecaf9e19979..2f444cb7c67 100644 --- a/wa/pom.xml +++ b/wa/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope WA diff --git a/wa/starter/pom.xml b/wa/starter/pom.xml index 2398fdd2ac1..46d0970fc8a 100644 --- a/wa/starter/pom.xml +++ b/wa/starter/pom.xml @@ -24,7 +24,7 @@ under the License. org.apache.syncope syncope-wa - 4.0.0 + 4.0.1-SNAPSHOT Apache Syncope WA Spring Boot Starter From f42040c7639544b3db5e9ed372df295cefbdcb5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Fri, 23 May 2025 15:26:41 +0200 Subject: [PATCH 064/579] Only push SNAPSHOT images to DockerHub --- .github/workflows/dockerhub.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index ddc7ef6ccae..af80f96a56a 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -20,8 +20,6 @@ on: push: branches: - 4_0_X - tags: - - syncope-4.0.* jobs: push2DockerHub: From 62e5bd28bd5e5c894395b07324c33d8756c070b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Fri, 23 May 2025 16:58:10 +0200 Subject: [PATCH 065/579] Updating downloads site page for release --- src/site/xdoc/downloads.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/site/xdoc/downloads.xml b/src/site/xdoc/downloads.xml index 8d37659b00c..eb4c08b2ae9 100644 --- a/src/site/xdoc/downloads.xml +++ b/src/site/xdoc/downloads.xml @@ -90,8 +90,8 @@ under the License.
- -

Release date: March 7th 2025

+ +

Release date: May 23rd 2025

Release notes

@@ -115,20 +115,20 @@ under the License. - syncope-3.0.11-source-release.zip + syncope-3.0.12-source-release.zip - asc - sha512 + asc + sha512 - syncope-standalone-3.0.11-distribution.zip + syncope-standalone-3.0.12-distribution.zip - asc - sha512 + asc + sha512 From e0d6055b94a45a02eea1e77babe82445eca9ef8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Mon, 26 May 2025 13:02:18 +0200 Subject: [PATCH 066/579] Upgrading Payara --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 895f605aac0..d4d12f1b643 100644 --- a/pom.xml +++ b/pom.xml @@ -507,7 +507,7 @@ under the License. 10.1.41 36.0.1.Final - 6.2025.4 + 6.2025.5 4.1.3 17-alpine From 48d6b9fd6ce8231230cfc0baa7a6d21a0bb1bc61 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 May 2025 08:11:15 +0200 Subject: [PATCH 067/579] Bump io.zonky.test.postgres:embedded-postgres-binaries-bom from 17.4.0 to 17.5.0 (#1088) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d4d12f1b643..738724c9184 100644 --- a/pom.xml +++ b/pom.xml @@ -476,7 +476,7 @@ under the License. 1.21.0 2.1.0 - 17.4.0 + 17.5.0 o=isp uid=admin,ou=system From 17d83c685b062c4e404331d81182331043d15221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Wed, 28 May 2025 08:15:42 +0200 Subject: [PATCH 068/579] Upgrading Tika and git-commit-id-maven-plugin --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 738724c9184..9a6301cb022 100644 --- a/pom.xml +++ b/pom.xml @@ -909,7 +909,7 @@ under the License. org.apache.tika tika-core - 3.1.0 + 3.2.0 @@ -1539,7 +1539,7 @@ under the License. io.github.git-commit-id git-commit-id-maven-plugin - 9.0.1 + 9.0.2 From e9e8cb6cbb0cf1606cca417e351bc612ec83fcbe Mon Sep 17 00:00:00 2001 From: alberto bogi <35602311+alberto-bogi@users.noreply.github.com> Date: Wed, 28 May 2025 12:40:57 +0200 Subject: [PATCH 069/579] [SYNCOPE-1888] Change required property for specific inputs in policy configuration (#1091) --- .../console/policies/PolicyModalPanelBuilder.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyModalPanelBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyModalPanelBuilder.java index cb9f88b0ee3..708cdc2e0ed 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyModalPanelBuilder.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/policies/PolicyModalPanelBuilder.java @@ -147,11 +147,11 @@ protected List load() { switch (type) { case ACCOUNT: - fields.add(new AjaxNumberFieldPanel.Builder().min(1).build( + fields.add(new AjaxNumberFieldPanel.Builder().min(0).build( "field", "maxAuthenticationAttempts", Integer.class, - new PropertyModel<>(policyTO, "maxAuthenticationAttempts"))); + new PropertyModel<>(policyTO, "maxAuthenticationAttempts")).setRequired(true)); fields.add(new AjaxCheckBoxPanel( "field", @@ -161,11 +161,11 @@ protected List load() { break; case PASSWORD: - fields.add(new AjaxNumberFieldPanel.Builder().min(1).build( + fields.add(new AjaxNumberFieldPanel.Builder().min(0).build( "field", "historyLength", Integer.class, - new PropertyModel<>(policyTO, "historyLength"))); + new PropertyModel<>(policyTO, "historyLength")).setRequired(true)); fields.add(new AjaxCheckBoxPanel( "field", @@ -191,7 +191,7 @@ protected List load() { "field", "maxAttempts", Integer.class, - new PropertyModel<>(policyTO, "maxAttempts"))); + new PropertyModel<>(policyTO, "maxAttempts")).setRequired(true)); AjaxDropDownChoicePanel backOffStrategy = new AjaxDropDownChoicePanel<>( "field", "backOffStrategy", From 6307747c2666e096797b3787890f3a680492778c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Thu, 29 May 2025 11:19:03 +0200 Subject: [PATCH 070/579] Upgrading Spring Cloud Gateay, Postgresql JDBC driver and exec-maven-plugin --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 9a6301cb022..dd6397163ea 100644 --- a/pom.xml +++ b/pom.xml @@ -416,7 +416,7 @@ under the License. 10.3 3.4.6 - 4.2.1 + 4.2.3 4.1.1 @@ -516,7 +516,7 @@ under the License. 23-slim-faststart 5.26 - 42.7.5 + 42.7.6 9.2.0 3.5.3 23.8.0.25.04 @@ -1425,7 +1425,7 @@ under the License. org.springframework.cloud spring-cloud-contract-wiremock - ${spring-cloud-gateway.version} + 4.2.1 test @@ -1800,7 +1800,7 @@ under the License. org.codehaus.mojo exec-maven-plugin - 3.5.0 + 3.5.1 From 5a5847e568ad3d7087f1b0a3637dd88826fac74d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Thu, 29 May 2025 12:21:51 +0200 Subject: [PATCH 071/579] Fixing WA SRA integration tests after Spring Cloud Gateway upgrade --- fit/wa-reference/src/test/resources/sra-cas.properties | 4 ++++ fit/wa-reference/src/test/resources/sra-oauth2.properties | 4 ++++ fit/wa-reference/src/test/resources/sra-oidc.properties | 4 ++++ fit/wa-reference/src/test/resources/sra-saml2.properties | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/fit/wa-reference/src/test/resources/sra-cas.properties b/fit/wa-reference/src/test/resources/sra-cas.properties index d70c50cb96a..34b0b897e3f 100644 --- a/fit/wa-reference/src/test/resources/sra-cas.properties +++ b/fit/wa-reference/src/test/resources/sra-cas.properties @@ -14,6 +14,10 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +spring.cloud.gateway.forwarded.enabled=true +spring.cloud.gateway.x-forwarded.enabled=true +spring.cloud.gateway.trusted-proxies=.* + keymaster.address=https://localhost:9443/syncope/rest/keymaster keymaster.username=${anonymousUser} keymaster.password=${anonymousKey} diff --git a/fit/wa-reference/src/test/resources/sra-oauth2.properties b/fit/wa-reference/src/test/resources/sra-oauth2.properties index 4f990029d48..bc527e22106 100644 --- a/fit/wa-reference/src/test/resources/sra-oauth2.properties +++ b/fit/wa-reference/src/test/resources/sra-oauth2.properties @@ -14,6 +14,10 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +spring.cloud.gateway.forwarded.enabled=true +spring.cloud.gateway.x-forwarded.enabled=true +spring.cloud.gateway.trusted-proxies=.* + keymaster.address=https://localhost:9443/syncope/rest/keymaster keymaster.username=${anonymousUser} keymaster.password=${anonymousKey} diff --git a/fit/wa-reference/src/test/resources/sra-oidc.properties b/fit/wa-reference/src/test/resources/sra-oidc.properties index c4a60b99ba1..df2d727bb9b 100644 --- a/fit/wa-reference/src/test/resources/sra-oidc.properties +++ b/fit/wa-reference/src/test/resources/sra-oidc.properties @@ -14,6 +14,10 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +spring.cloud.gateway.forwarded.enabled=true +spring.cloud.gateway.x-forwarded.enabled=true +spring.cloud.gateway.trusted-proxies=.* + keymaster.address=https://localhost:9443/syncope/rest/keymaster keymaster.username=${anonymousUser} keymaster.password=${anonymousKey} diff --git a/fit/wa-reference/src/test/resources/sra-saml2.properties b/fit/wa-reference/src/test/resources/sra-saml2.properties index 8b70f367be3..33cd5faa295 100644 --- a/fit/wa-reference/src/test/resources/sra-saml2.properties +++ b/fit/wa-reference/src/test/resources/sra-saml2.properties @@ -14,6 +14,10 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +spring.cloud.gateway.forwarded.enabled=true +spring.cloud.gateway.x-forwarded.enabled=true +spring.cloud.gateway.trusted-proxies=.* + keymaster.address=https://localhost:9443/syncope/rest/keymaster keymaster.username=${anonymousUser} keymaster.password=${anonymousKey} From 7982f6d5873872313f60f07097ce9ffd0d76fe1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Fri, 30 May 2025 08:29:41 +0200 Subject: [PATCH 072/579] Upgrading Groovy, Elasticsearch, OpenSearch and Woodstox --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index dd6397163ea..59791fe186d 100644 --- a/pom.xml +++ b/pom.xml @@ -422,16 +422,16 @@ under the License. 1.9.3 - 5.0.0-alpha-12 + 5.0.0-beta-1 7.1.0 6.8.1 4.0.0 - 9.0.0 + 9.0.1 2.19.2 - 2.23.0 + 2.24.0 v1 @@ -661,7 +661,7 @@ under the License. com.fasterxml.woodstox woodstox-core - 7.1.0 + 7.1.1 From bfedac14ec040b3b5ae41eb3c3a792ccbbb8a899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Fri, 30 May 2025 10:57:00 +0200 Subject: [PATCH 073/579] Upgrading CAS --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 59791fe186d..1569f17c71c 100644 --- a/pom.xml +++ b/pom.xml @@ -443,7 +443,7 @@ under the License. 6.1.1 - 7.2.2 + 7.2.3 4.0.4 2.2.32 From e74194c6c363c52b4941c2aafeead592e7b6d9a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Fri, 30 May 2025 11:26:58 +0200 Subject: [PATCH 074/579] [SYNCOPE-1887] Require re-auth for sensitive features (#1097) --- .../syncope/client/console/pages/SRA.java | 2 +- .../syncope/client/console/pages/WA.java | 2 +- .../client/enduser/pages/AuthProfile.java | 59 ++++---- .../enduser/rest/AuthProfileRestClient.java | 7 +- .../console/topology/TabularTopology.java | 2 +- .../client/console/topology/Topology.java | 2 +- .../syncope/client/ui/commons/BaseLogin.java | 29 ++-- .../ui/commons}/annotations/AMPage.java | 2 +- .../ui/commons}/annotations/IdMPage.java | 2 +- .../commons/panels/BaseSSOLoginFormPanel.java | 6 + .../ClassPathScanImplementationLookup.java | 4 +- .../client/console/pages/BasePage.java | 4 +- .../syncope/client/console/pages/Login.java | 5 +- .../enduser/BookmarkablePageLinkBuilder.java | 5 +- .../client/enduser/EnduserProperties.java | 10 ++ .../client/enduser/SyncopeEnduserSession.java | 26 +++- .../client/enduser/SyncopeWebApplication.java | 5 + .../enduser/commons/EnduserConstants.java | 8 +- .../ClassPathScanImplementationLookup.java | 31 ++++ .../client/enduser/layout/SidebarLayout.java | 1 - .../enduser/pages/AbstractChangePassword.java | 4 +- .../client/enduser/pages/BaseExtPage.java | 4 - .../client/enduser/pages/BasePage.java | 24 +--- .../client/enduser/pages/BaseReauthPage.java | 51 +++++++ .../enduser/pages/EditChangePassword.java | 21 +-- .../enduser/pages/EditSecurityQuestion.java | 2 +- .../client/enduser/pages/EditUser.java | 2 +- .../syncope/client/enduser/pages/Login.java | 30 ++-- .../enduser/pages/MustChangePassword.java | 5 + .../client/enduser/pages/ReauthLogin.java | 64 +++++++++ .../client/enduser/panels/Sidebar.java | 88 ++++++++++-- .../client/enduser/panels/UserFormPanel.java | 7 +- .../enduser/rest/SyncopeRestClient.java | 9 +- .../enduser/widgets/UserProfileWidget.java | 4 - .../src/main/resources/enduser.properties | 1 + .../SyncopeEnduserApplication.properties | 4 +- ...SyncopeEnduserApplication_fr_CA.properties | 4 +- .../SyncopeEnduserApplication_it.properties | 18 +-- .../SyncopeEnduserApplication_ja.properties | 4 +- ...SyncopeEnduserApplication_pt_BR.properties | 2 +- .../SyncopeEnduserApplication_ru.properties | 4 +- .../enduser/pages/BaseReauthPage.properties | 17 +++ .../pages/BaseReauthPage_fr.properties | 17 +++ .../pages/BaseReauthPage_it.properties | 17 +++ .../pages/BaseReauthPage_ja.properties | 17 +++ .../pages/BaseReauthPage_pt_BR.properties | 17 +++ .../pages/BaseReauthPage_ru.properties | 17 +++ .../pages/EditChangePassword.properties | 2 - .../pages/EditChangePassword_fr_CA.properties | 2 - .../pages/EditChangePassword_it.properties | 2 - .../pages/EditChangePassword_ja.properties | 2 - .../pages/EditChangePassword_pt_BR.properties | 2 - .../pages/EditChangePassword_ru.properties | 3 - .../pages/EditSecurityQuestion.properties | 4 +- .../pages/EditSecurityQuestion_it.properties | 4 +- .../pages/EditSecurityQuestion_ja.properties | 4 +- .../EditSecurityQuestion_pt_BR.properties | 3 +- .../pages/EditSecurityQuestion_ru.properties | 5 +- .../client/enduser/pages/EditUser.html | 20 +-- .../client/enduser/pages/EditUser.properties | 4 - .../pages/MustChangePassword.properties | 3 - .../pages/MustChangePassword_it.properties | 4 - .../pages/MustChangePassword_ja.properties | 4 - .../pages/MustChangePassword_pt_BR.properties | 2 - .../pages/MustChangePassword_ru.properties | 5 - .../pages/SelfConfirmPasswordReset.properties | 2 - .../SelfConfirmPasswordReset_it.properties | 2 - .../SelfConfirmPasswordReset_ja.properties | 2 - .../SelfConfirmPasswordReset_pt_BR.properties | 2 - .../SelfConfirmPasswordReset_ru.properties | 2 - ...PasswordReset$SelfPwdResetPanel.properties | 2 - ...rdReset$SelfPwdResetPanel_fr_CA.properties | 2 - ...swordReset$SelfPwdResetPanel_it.properties | 2 - ...swordReset$SelfPwdResetPanel_ja.properties | 2 - ...rdReset$SelfPwdResetPanel_pt_BR.properties | 2 - ...swordReset$SelfPwdResetPanel_ru.properties | 2 - .../panels/ChangePasswordPanel.properties | 3 - .../panels/ChangePasswordPanel_it.properties | 2 - .../panels/ChangePasswordPanel_ja.properties | 2 - .../ChangePasswordPanel_pt_BR.properties | 2 - .../panels/ChangePasswordPanel_ru.properties | 3 - .../client/enduser/panels/Sidebar.html | 136 ++++++++++-------- .../enduser/panels/any/UserDetails.properties | 2 +- .../panels/any/UserDetails_it.properties | 2 +- .../panels/any/UserDetails_ja.properties | 2 +- .../panels/any/UserDetails_pt_BR.properties | 2 +- .../panels/any/UserDetails_ru.properties | 2 +- .../enduser/widgets/UserProfileWidget.html | 58 ++++---- .../test/resources/enduser-debug.properties | 4 +- .../panels/AbstractOIDCSSOLoginFormPanel.java | 10 +- .../ui/commons/panels/OIDCC4UIConstants.java | 2 + .../resources/oidcc4ui/LoginResource.java | 11 +- .../client/enduser/pages/OIDCClientLogin.java | 2 + .../syncope/core/logic/OIDCC4UILogic.java | 20 ++- .../rest/api/service/OIDCC4UIService.java | 5 +- .../rest/cxf/service/OIDCC4UIServiceImpl.java | 4 +- .../ui/commons/SAML2SP4UIConstants.java | 2 + .../panels/AbstractSAMLSSOLoginFormPanel.java | 11 +- .../resources/saml2sp4ui/LoginResource.java | 4 +- .../client/enduser/pages/SAML2SPLogin.java | 2 + .../syncope/core/logic/SAML2SP4UILogic.java | 41 +++--- .../rest/api/service/SAML2SP4UIService.java | 9 +- .../cxf/service/SAML2SP4UIServiceImpl.java | 5 +- 103 files changed, 712 insertions(+), 399 deletions(-) rename client/idrepo/{console/src/main/java/org/apache/syncope/client/console => common-ui/src/main/java/org/apache/syncope/client/ui/commons}/annotations/AMPage.java (96%) rename client/idrepo/{console/src/main/java/org/apache/syncope/client/console => common-ui/src/main/java/org/apache/syncope/client/ui/commons}/annotations/IdMPage.java (96%) create mode 100644 client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseReauthPage.java create mode 100644 client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/ReauthLogin.java create mode 100644 client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage.properties create mode 100644 client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_fr.properties create mode 100644 client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_it.properties create mode 100644 client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_ja.properties create mode 100644 client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_pt_BR.properties create mode 100644 client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_ru.properties diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/pages/SRA.java b/client/am/console/src/main/java/org/apache/syncope/client/console/pages/SRA.java index 43bf65ab19a..96bc50229f2 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/pages/SRA.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/pages/SRA.java @@ -23,13 +23,13 @@ import java.util.List; import org.apache.syncope.client.console.BookmarkablePageLinkBuilder; import org.apache.syncope.client.console.SyncopeConsoleSession; -import org.apache.syncope.client.console.annotations.AMPage; import org.apache.syncope.client.console.panels.AMSessionPanel; import org.apache.syncope.client.console.panels.SRARouteDirectoryPanel; import org.apache.syncope.client.console.panels.SRAStatisticsPanel; import org.apache.syncope.client.console.rest.SRARouteRestClient; import org.apache.syncope.client.console.rest.SRASessionRestClient; import org.apache.syncope.client.ui.commons.Constants; +import org.apache.syncope.client.ui.commons.annotations.AMPage; import org.apache.syncope.common.keymaster.client.api.ServiceOps; import org.apache.syncope.common.keymaster.client.api.model.NetworkService; import org.apache.syncope.common.lib.types.AMEntitlement; diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/pages/WA.java b/client/am/console/src/main/java/org/apache/syncope/client/console/pages/WA.java index 88dd3683105..4692d97c5a3 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/pages/WA.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/pages/WA.java @@ -32,7 +32,6 @@ import org.apache.syncope.client.console.BookmarkablePageLinkBuilder; import org.apache.syncope.client.console.SyncopeConsoleSession; import org.apache.syncope.client.console.SyncopeWebApplication; -import org.apache.syncope.client.console.annotations.AMPage; import org.apache.syncope.client.console.authprofiles.AuthProfileDirectoryPanel; import org.apache.syncope.client.console.clientapps.ClientApps; import org.apache.syncope.client.console.panels.AMSessionPanel; @@ -50,6 +49,7 @@ import org.apache.syncope.client.console.rest.WASessionRestClient; import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal; import org.apache.syncope.client.lib.WebClientBuilder; +import org.apache.syncope.client.ui.commons.annotations.AMPage; import org.apache.syncope.common.keymaster.client.api.ServiceOps; import org.apache.syncope.common.keymaster.client.api.model.NetworkService; import org.apache.syncope.common.lib.types.AMEntitlement; diff --git a/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AuthProfile.java b/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AuthProfile.java index 8a1a08a0209..50a584d4f83 100644 --- a/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AuthProfile.java +++ b/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AuthProfile.java @@ -19,11 +19,10 @@ package org.apache.syncope.client.enduser.pages; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; import org.apache.syncope.client.enduser.rest.AuthProfileRestClient; import org.apache.syncope.client.ui.commons.Constants; -import org.apache.syncope.client.ui.commons.annotations.ExtPage; +import org.apache.syncope.client.ui.commons.annotations.AMPage; import org.apache.syncope.client.ui.commons.markup.html.form.IndicatingOnConfirmAjaxLink; import org.apache.syncope.common.lib.to.AuthProfileTO; import org.apache.syncope.common.lib.wa.GoogleMfaAuthAccount; @@ -41,8 +40,8 @@ import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.spring.injection.annot.SpringBean; -@ExtPage(label = "Auth Profile", icon = "fa fa-passport", listEntitlement = "") -public class AuthProfile extends BaseExtPage { +@AMPage(label = "Auth Profile", icon = "fa fa-passport", listEntitlement = "") +public class AuthProfile extends BaseReauthPage { private static final long serialVersionUID = -3147262161518280928L; @@ -56,14 +55,14 @@ public class AuthProfile extends BaseExtPage { public AuthProfile(final PageParameters parameters) { super(parameters, AUTH_PROFILE); - Optional authProfile = restClient.read(); + AuthProfileTO authProfile = restClient.read(); WebMarkupContainer container = new WebMarkupContainer("content"); contentWrapper.add(container.setOutputMarkupId(true)); DataView impersonationAccounts = new DataView<>( "impersonationAccounts", new ListDataProvider<>( - authProfile.map(AuthProfileTO::getImpersonationAccounts).orElseGet(() -> List.of()))) { + authProfile == null ? List.of() : authProfile.getImpersonationAccounts())) { private static final long serialVersionUID = 6127875313385810666L; @@ -77,11 +76,11 @@ public void populateItem(final Item item) { @Override public void onClick(final AjaxRequestTarget target) { - authProfile.ifPresent(p -> { - p.getImpersonationAccounts().remove(item.getModelObject()); - restClient.update(p); + if (authProfile != null) { + authProfile.getImpersonationAccounts().remove(item.getModelObject()); + restClient.update(authProfile); target.add(container); - }); + } } }); } @@ -92,7 +91,7 @@ public void onClick(final AjaxRequestTarget target) { DataView googleMfaAuthTokens = new DataView<>( "googleMfaAuthTokens", new ListDataProvider<>( - authProfile.map(AuthProfileTO::getGoogleMfaAuthTokens).orElseGet(() -> List.of()))) { + authProfile == null ? List.of() : authProfile.getGoogleMfaAuthTokens())) { private static final long serialVersionUID = 6127875313385810666L; @@ -107,11 +106,11 @@ public void populateItem(final Item item) { @Override public void onClick(final AjaxRequestTarget target) { - authProfile.ifPresent(p -> { - p.getGoogleMfaAuthTokens().remove(item.getModelObject()); - restClient.update(p); + if (authProfile != null) { + authProfile.getGoogleMfaAuthTokens().remove(item.getModelObject()); + restClient.update(authProfile); target.add(container); - }); + } } }); } @@ -122,7 +121,7 @@ public void onClick(final AjaxRequestTarget target) { DataView googleMfaAuthAccounts = new DataView<>( "googleMfaAuthAccounts", new ListDataProvider<>( - authProfile.map(AuthProfileTO::getGoogleMfaAuthAccounts).orElseGet(() -> List.of()))) { + authProfile == null ? List.of() : authProfile.getGoogleMfaAuthAccounts())) { private static final long serialVersionUID = 6127875313385810666L; @@ -143,11 +142,11 @@ public void populateItem(final Item item) { @Override public void onClick(final AjaxRequestTarget target) { - authProfile.ifPresent(p -> { - p.getGoogleMfaAuthAccounts().remove(item.getModelObject()); - restClient.update(p); + if (authProfile != null) { + authProfile.getGoogleMfaAuthAccounts().remove(item.getModelObject()); + restClient.update(authProfile); target.add(container); - }); + } } }); } @@ -158,7 +157,7 @@ public void onClick(final AjaxRequestTarget target) { DataView mfaTrustedDevices = new DataView<>( "mfaTrustedDevices", new ListDataProvider<>( - authProfile.map(AuthProfileTO::getMfaTrustedDevices).orElseGet(() -> List.of()))) { + authProfile == null ? List.of() : authProfile.getMfaTrustedDevices())) { private static final long serialVersionUID = 6127875313385810666L; @@ -176,11 +175,11 @@ public void populateItem(final Item item) { @Override public void onClick(final AjaxRequestTarget target) { - authProfile.ifPresent(p -> { - p.getMfaTrustedDevices().remove(item.getModelObject()); - restClient.update(p); + if (authProfile != null) { + authProfile.getMfaTrustedDevices().remove(item.getModelObject()); + restClient.update(authProfile); target.add(container); - }); + } } }); } @@ -191,7 +190,7 @@ public void onClick(final AjaxRequestTarget target) { DataView webAuthnDeviceCredentials = new DataView<>( "webAuthnDeviceCredentials", new ListDataProvider<>( - authProfile.map(AuthProfileTO::getWebAuthnDeviceCredentials).orElseGet(() -> List.of()))) { + authProfile == null ? List.of() : authProfile.getWebAuthnDeviceCredentials())) { private static final long serialVersionUID = 6127875313385810666L; @@ -205,11 +204,11 @@ public void populateItem(final Item item) { @Override public void onClick(final AjaxRequestTarget target) { - authProfile.ifPresent(p -> { - p.getWebAuthnDeviceCredentials().remove(item.getModelObject()); - restClient.update(p); + if (authProfile != null) { + authProfile.getWebAuthnDeviceCredentials().remove(item.getModelObject()); + restClient.update(authProfile); target.add(container); - }); + } } }); } diff --git a/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/rest/AuthProfileRestClient.java b/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/rest/AuthProfileRestClient.java index 413247746fa..2714954ff59 100644 --- a/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/rest/AuthProfileRestClient.java +++ b/client/am/enduser/src/main/java/org/apache/syncope/client/enduser/rest/AuthProfileRestClient.java @@ -18,7 +18,6 @@ */ package org.apache.syncope.client.enduser.rest; -import java.util.Optional; import org.apache.syncope.common.lib.to.AuthProfileTO; import org.apache.syncope.common.rest.api.service.AuthProfileSelfService; @@ -26,12 +25,12 @@ public class AuthProfileRestClient extends BaseRestClient { private static final long serialVersionUID = 4139153766778113329L; - public Optional read() { + public AuthProfileTO read() { try { - return Optional.of(getService(AuthProfileSelfService.class).read()); + return getService(AuthProfileSelfService.class).read(); } catch (Exception e) { LOG.debug("While attempting to read the auth profile", e); - return Optional.empty(); + return null; } } diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TabularTopology.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TabularTopology.java index 02ae460c80e..58eae319b48 100644 --- a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TabularTopology.java +++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/TabularTopology.java @@ -21,11 +21,11 @@ import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel; import java.util.ArrayList; import java.util.List; -import org.apache.syncope.client.console.annotations.IdMPage; import org.apache.syncope.client.console.pages.BasePage; import org.apache.syncope.client.console.pages.Connectors; import org.apache.syncope.client.console.pages.Resources; import org.apache.syncope.client.console.panels.ConnidLocations; +import org.apache.syncope.client.ui.commons.annotations.IdMPage; import org.apache.syncope.common.lib.types.IdMEntitlement; import org.apache.wicket.extensions.markup.html.tabs.AbstractTab; import org.apache.wicket.extensions.markup.html.tabs.ITab; diff --git a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java index d22d706d51e..cbc218e1dee 100644 --- a/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java +++ b/client/idm/console/src/main/java/org/apache/syncope/client/console/topology/Topology.java @@ -36,7 +36,6 @@ import org.apache.commons.lang3.tuple.Pair; import org.apache.cxf.jaxrs.client.WebClient; import org.apache.syncope.client.console.SyncopeConsoleSession; -import org.apache.syncope.client.console.annotations.IdMPage; import org.apache.syncope.client.console.pages.BasePage; import org.apache.syncope.client.console.rest.ConnectorRestClient; import org.apache.syncope.client.console.rest.ResourceRestClient; @@ -46,6 +45,7 @@ import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel; import org.apache.syncope.client.console.wizards.resources.AbstractResourceWizardBuilder.CreateEvent; import org.apache.syncope.client.ui.commons.Constants; +import org.apache.syncope.client.ui.commons.annotations.IdMPage; import org.apache.syncope.common.lib.to.ConnInstanceTO; import org.apache.syncope.common.lib.to.ResourceTO; import org.apache.syncope.common.lib.types.IdMEntitlement; diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/BaseLogin.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/BaseLogin.java index f51e641a17d..b00a81f4b47 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/BaseLogin.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/BaseLogin.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Locale; import org.apache.commons.lang3.StringUtils; +import org.apache.syncope.client.ui.commons.panels.BaseSSOLoginFormPanel; import org.apache.syncope.client.ui.commons.panels.NotificationPanel; import org.apache.syncope.common.keymaster.client.api.DomainOps; import org.apache.syncope.common.keymaster.client.api.model.Domain; @@ -45,7 +46,6 @@ import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; -import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.LoadableDetachableModel; import org.apache.wicket.model.Model; @@ -73,6 +73,10 @@ public abstract class BaseLogin extends WebPage { protected final TextField passwordField; + protected final LocaleDropDown languageSelect; + + protected final DomainDropDown domainSelect; + protected String notificationMessage; protected String notificationLevel; @@ -97,7 +101,7 @@ public BaseLogin(final PageParameters parameters) { notificationPanel = new NotificationPanel(Constants.FEEDBACK); add(notificationPanel); - if (!parameters.get("notificationMessage").isNull()) { + if (!parameters.get(Constants.NOTIFICATION_MSG_PARAM).isNull()) { notificationMessage = parameters.get(Constants.NOTIFICATION_MSG_PARAM).toString(); notificationLevel = parameters.get(Constants.NOTIFICATION_LEVEL_PARAM).isEmpty() ? Notification.SUCCESS @@ -123,7 +127,7 @@ public BaseLogin(final PageParameters parameters) { passwordField.setMarkupId("password"); form.add(passwordField); - LocaleDropDown languageSelect = new LocaleDropDown("language"); + languageSelect = new LocaleDropDown("language"); languageSelect.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) { private static final long serialVersionUID = -1107858522700306810L; @@ -143,7 +147,7 @@ protected void onUpdate(final AjaxRequestTarget target) { }); form.add(languageSelect.setOutputMarkupId(true)); - DomainDropDown domainSelect = new DomainDropDown("domain", domains); + domainSelect = new DomainDropDown("domain", domains); domainSelect.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) { private static final long serialVersionUID = -1107858522700306810L; @@ -169,21 +173,19 @@ protected void onUpdate(final AjaxRequestTarget target) { @Override protected void onSubmit(final AjaxRequestTarget target) { - authenticate(usernameField.getRawInput(), passwordField.getRawInput(), target); + authenticate(usernameField.getValue(), passwordField.getRawInput(), target); } - }; submitButton.setDefaultFormProcessing(false); form.add(submitButton); form.setDefaultButton(submitButton); - List ssoLoginFormPanels = getSSOLoginFormPanels(); - ListView ssoLogins = new ListView<>("ssoLogins", ssoLoginFormPanels) { + ListView ssoLogins = new ListView<>("ssoLogins", getSSOLoginFormPanels()) { private static final long serialVersionUID = -9180479401817023838L; @Override - protected void populateItem(final ListItem item) { + protected void populateItem(final ListItem item) { item.add(item.getModelObject()); } }; @@ -203,16 +205,19 @@ protected Collection getDomainOnChangeComponents() { @Override public void renderHead(final IHeaderResponse response) { super.renderHead(response); + if (StringUtils.isNotBlank(notificationMessage)) { - response.render(OnLoadHeaderItem.forScript(StyledNotificationBehavior.jQueryShow(notificationMessage, + response.render(OnLoadHeaderItem.forScript(StyledNotificationBehavior.jQueryShow( + notificationMessage, String.format("jQuery('#%s').data('kendoNotification')", - notificationPanel.getNotificationMarkupId()), notificationLevel))); + notificationPanel.getNotificationMarkupId()), + notificationLevel))); } } protected abstract BaseSession getBaseSession(); - protected abstract List getSSOLoginFormPanels(); + protected abstract List getSSOLoginFormPanels(); protected abstract void sendError(String error); diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/annotations/AMPage.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/annotations/AMPage.java similarity index 96% rename from client/idrepo/console/src/main/java/org/apache/syncope/client/console/annotations/AMPage.java rename to client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/annotations/AMPage.java index 86a9c6d6b54..d4404c8483d 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/annotations/AMPage.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/annotations/AMPage.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.syncope.client.console.annotations; +package org.apache.syncope.client.ui.commons.annotations; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/annotations/IdMPage.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/annotations/IdMPage.java similarity index 96% rename from client/idrepo/console/src/main/java/org/apache/syncope/client/console/annotations/IdMPage.java rename to client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/annotations/IdMPage.java index 69436364043..239f5cefd47 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/annotations/IdMPage.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/annotations/IdMPage.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.syncope.client.console.annotations; +package org.apache.syncope.client.ui.commons.annotations; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; diff --git a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/BaseSSOLoginFormPanel.java b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/BaseSSOLoginFormPanel.java index 9675eb7bab4..4e9117387f7 100644 --- a/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/BaseSSOLoginFormPanel.java +++ b/client/idrepo/common-ui/src/main/java/org/apache/syncope/client/ui/commons/panels/BaseSSOLoginFormPanel.java @@ -24,7 +24,13 @@ public abstract class BaseSSOLoginFormPanel extends Panel { private static final long serialVersionUID = -2371733568360773586L; + protected boolean reauth; + public BaseSSOLoginFormPanel(final String id) { super(id); } + + public void setReauth(final boolean reauth) { + this.reauth = reauth; + } } diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java index e8a5b945550..a7a04597f77 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java @@ -34,15 +34,15 @@ import java.util.stream.Collectors; import org.apache.commons.lang3.ArrayUtils; import org.apache.syncope.client.console.ConsoleProperties; -import org.apache.syncope.client.console.annotations.AMPage; -import org.apache.syncope.client.console.annotations.IdMPage; import org.apache.syncope.client.console.pages.BaseExtPage; import org.apache.syncope.client.console.pages.BasePage; import org.apache.syncope.client.console.widgets.BaseExtWidget; import org.apache.syncope.client.console.widgets.ExtAlertWidget; +import org.apache.syncope.client.ui.commons.annotations.AMPage; import org.apache.syncope.client.ui.commons.annotations.BinaryPreview; import org.apache.syncope.client.ui.commons.annotations.ExtPage; import org.apache.syncope.client.ui.commons.annotations.ExtWidget; +import org.apache.syncope.client.ui.commons.annotations.IdMPage; import org.apache.syncope.client.ui.commons.markup.html.form.preview.BinaryPreviewer; import org.apache.syncope.client.ui.commons.panels.BaseSSOLoginFormPanel; import org.apache.syncope.common.lib.policy.AccountRuleConf; diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java index 8490ed6aeaf..6a1b8fe56b0 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java @@ -26,14 +26,14 @@ import org.apache.syncope.client.console.BookmarkablePageLinkBuilder; import org.apache.syncope.client.console.SyncopeConsoleSession; import org.apache.syncope.client.console.SyncopeWebApplication; -import org.apache.syncope.client.console.annotations.AMPage; -import org.apache.syncope.client.console.annotations.IdMPage; import org.apache.syncope.client.console.panels.DelegationSelectionPanel; import org.apache.syncope.client.console.rest.SyncopeRestClient; import org.apache.syncope.client.console.wicket.markup.head.MetaHeaderItem; import org.apache.syncope.client.console.widgets.ExtAlertWidget; import org.apache.syncope.client.ui.commons.Constants; +import org.apache.syncope.client.ui.commons.annotations.AMPage; import org.apache.syncope.client.ui.commons.annotations.ExtPage; +import org.apache.syncope.client.ui.commons.annotations.IdMPage; import org.apache.syncope.client.ui.commons.markup.html.form.IndicatingOnConfirmAjaxLink; import org.apache.syncope.client.ui.commons.pages.BaseWebPage; import org.apache.syncope.common.lib.SyncopeConstants; diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Login.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Login.java index 4b923e1a31a..07b33ad0588 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Login.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/pages/Login.java @@ -29,7 +29,6 @@ import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.authentication.IAuthenticationStrategy; import org.apache.wicket.authroles.authentication.AuthenticatedWebSession; -import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.request.mapper.parameter.PageParameters; public class Login extends BaseLogin { @@ -46,8 +45,8 @@ protected BaseSession getBaseSession() { } @Override - protected List getSSOLoginFormPanels() { - List ssoLoginFormPanels = new ArrayList<>(); + protected List getSSOLoginFormPanels() { + List ssoLoginFormPanels = new ArrayList<>(); SyncopeWebApplication.get().getLookup().getClasses(BaseSSOLoginFormPanel.class).forEach(ssoLoginFormPanel -> { try { ssoLoginFormPanels.add(ssoLoginFormPanel.getConstructor(String.class, BaseSession.class).newInstance( diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/BookmarkablePageLinkBuilder.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/BookmarkablePageLinkBuilder.java index 7f5c8064374..5272b5b0de4 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/BookmarkablePageLinkBuilder.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/BookmarkablePageLinkBuilder.java @@ -18,6 +18,7 @@ */ package org.apache.syncope.client.enduser; +import java.util.Optional; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.link.BookmarkablePageLink; @@ -34,9 +35,7 @@ public static BookmarkablePageLink build( @SuppressWarnings("unchecked") Class pageClass = (Class) SyncopeWebApplication.get().getPageClass(key); - return new BookmarkablePageLink<>( - id, - pageClass == null ? defaultPageClass : pageClass); + return new BookmarkablePageLink<>(id, Optional.ofNullable(pageClass).orElse(defaultPageClass)); } private BookmarkablePageLinkBuilder() { diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/EnduserProperties.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/EnduserProperties.java index 93a46de7aed..ee738252482 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/EnduserProperties.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/EnduserProperties.java @@ -36,6 +36,8 @@ public class EnduserProperties extends CommonUIProperties { private boolean captcha; + private Long reauthExpirationMinutesTimeout; + private boolean reportPropagationErrors; private boolean reportPropagationErrorDetails; @@ -66,6 +68,14 @@ public void setCaptcha(final boolean captcha) { this.captcha = captcha; } + public Long getReauthExpirationMinutesTimeout() { + return reauthExpirationMinutesTimeout; + } + + public void setReauthExpirationMinutesTimeout(final Long reauthExpirationMinutesTimeout) { + this.reauthExpirationMinutesTimeout = reauthExpirationMinutesTimeout; + } + public boolean isReportPropagationErrors() { return reportPropagationErrors; } diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java index 8f4c78fd2d6..044b3473e66 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java @@ -25,6 +25,8 @@ import jakarta.ws.rs.core.MediaType; import jakarta.xml.ws.WebServiceException; import java.text.DateFormat; +import java.time.OffsetDateTime; +import java.time.temporal.ChronoUnit; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -102,12 +104,30 @@ public static SyncopeEnduserSession get() { protected UserTO selfTO; + protected OffsetDateTime lastReauth; + public SyncopeEnduserSession(final Request request) { super(request); clientFactory = SyncopeWebApplication.get().newClientFactory(); } + public boolean isReauthExpired() { + return SyncopeWebApplication.get().getReauthExpirationMinutesTimeout(). + map(timeout -> Optional.ofNullable(lastReauth). + map(r -> ChronoUnit.MINUTES.between(r, OffsetDateTime.now()) > timeout). + orElse(true)). + orElse(false); + } + + public void setLastReauth() { + this.lastReauth = OffsetDateTime.now(); + } + + public void clearLastReauth() { + this.lastReauth = null; + } + protected String message(final SyncopeClientException sce) { Error error = null; if (sce.getType() == ClientExceptionType.InvalidSecurityAnswer) { @@ -179,7 +199,7 @@ public String getDomain() { @Override public String getJWT() { - return client == null ? null : client.getJWT(); + return Optional.ofNullable(client).map(SyncopeClient::getJWT).orElse(null); } @Override @@ -246,11 +266,11 @@ protected void refreshAuth(final String username) { } protected boolean isAuthenticated() { - return client != null && client.getJWT() != null; + return getJWT() != null; } protected boolean isMustChangePassword() { - return selfTO != null && selfTO.isMustChangePassword(); + return Optional.ofNullable(selfTO).map(UserTO::isMustChangePassword).orElse(false); } public void cleanup() { diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java index c0ce8f13938..52a5b894dec 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeWebApplication.java @@ -28,6 +28,7 @@ import java.io.InputStream; import java.util.List; import java.util.Map; +import java.util.Optional; import org.apache.syncope.client.enduser.init.ClassPathScanImplementationLookup; import org.apache.syncope.client.enduser.layout.UserFormLayoutInfo; import org.apache.syncope.client.enduser.pages.BasePage; @@ -301,6 +302,10 @@ public boolean isCaptchaEnabled() { return props.isCaptcha(); } + public Optional getReauthExpirationMinutesTimeout() { + return Optional.ofNullable(props.getReauthExpirationMinutesTimeout()); + } + public boolean isReportPropagationErrors() { return props.isReportPropagationErrors(); } diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/commons/EnduserConstants.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/commons/EnduserConstants.java index 07719f91b46..cdc5d35332b 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/commons/EnduserConstants.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/commons/EnduserConstants.java @@ -21,18 +21,12 @@ public final class EnduserConstants { public static final String STATUS = "status"; - - public static final String SUCCESS = "success"; - - public static final String FAILING_RESOURCES = "failing_resources"; public static final String LANDING_PAGE = "landingPage"; public static final String CONTENT_PANEL = "contentPanel"; - public static final String SELF_ALLOWED = "selfRegistration.allowed"; - - public static final String PAGE_TITLE = "pageTitle"; + public static final String REAUTH = "reauth"; private EnduserConstants() { // private constructor for static utility class diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/init/ClassPathScanImplementationLookup.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/init/ClassPathScanImplementationLookup.java index 042df772fca..d5c4d2b34bd 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/init/ClassPathScanImplementationLookup.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/init/ClassPathScanImplementationLookup.java @@ -22,13 +22,16 @@ import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Objects; import org.apache.commons.lang3.ArrayUtils; import org.apache.syncope.client.enduser.pages.BaseExtPage; import org.apache.syncope.client.enduser.pages.BasePage; +import org.apache.syncope.client.ui.commons.annotations.AMPage; import org.apache.syncope.client.ui.commons.annotations.BinaryPreview; import org.apache.syncope.client.ui.commons.annotations.ExtPage; +import org.apache.syncope.client.ui.commons.annotations.IdMPage; import org.apache.syncope.client.ui.commons.markup.html.form.preview.BinaryPreviewer; import org.apache.syncope.client.ui.commons.panels.BaseSSOLoginFormPanel; import org.slf4j.Logger; @@ -48,6 +51,10 @@ public class ClassPathScanImplementationLookup implements Serializable { private List> ssoLoginFormPanels; + private List> idmPages; + + private List> amPages; + private List> extPages; private List> previewers; @@ -63,6 +70,8 @@ protected static String getBasePackage() { @SuppressWarnings("unchecked") public void load() { + idmPages = new ArrayList<>(); + amPages = new ArrayList<>(); extPages = new ArrayList<>(); ssoLoginFormPanels = new ArrayList<>(); previewers = new ArrayList<>(); @@ -87,6 +96,12 @@ public void load() { LOG.error("Could not find annotation {} in {}, ignoring", ExtPage.class.getName(), clazz.getName()); } + } else if (BasePage.class.isAssignableFrom(clazz)) { + if (clazz.isAnnotationPresent(IdMPage.class)) { + idmPages.add((Class) clazz); + } else if (clazz.isAnnotationPresent(AMPage.class)) { + amPages.add((Class) clazz); + } } else if (BaseSSOLoginFormPanel.class.isAssignableFrom(clazz)) { ssoLoginFormPanels.add((Class) clazz); } else if (BinaryPreviewer.class.isAssignableFrom(clazz)) { @@ -97,13 +112,29 @@ public void load() { } } + idmPages.sort(Comparator.comparing(o -> o.getAnnotation(IdMPage.class).priority())); + idmPages = Collections.unmodifiableList(idmPages); + + amPages.sort(Comparator.comparing(o -> o.getAnnotation(AMPage.class).priority())); + amPages = Collections.unmodifiableList(amPages); + ssoLoginFormPanels = Collections.unmodifiableList(ssoLoginFormPanels); + LOG.debug("IdM pages found: {}", idmPages); + LOG.debug("AM pages found: {}", amPages); LOG.debug("Extension pages found: {}", extPages); LOG.debug("SSO Login pages found: {}", ssoLoginFormPanels); LOG.debug("Binary previewers found: {}", previewers); } + public List> getIdMPageClasses() { + return idmPages; + } + + public List> getAMPageClasses() { + return amPages; + } + public List> getSSOLoginFormPanels() { return this.ssoLoginFormPanels; } diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/layout/SidebarLayout.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/layout/SidebarLayout.java index f9840a83f00..4d23492d9ce 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/layout/SidebarLayout.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/layout/SidebarLayout.java @@ -65,5 +65,4 @@ public Map getExtensionsEnabled() { public boolean isExtensionEnabled(final String key) { return extensionsEnabled.getOrDefault(key, true); } - } diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AbstractChangePassword.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AbstractChangePassword.java index c350a1689b5..3a7d9c0eea8 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AbstractChangePassword.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/AbstractChangePassword.java @@ -29,13 +29,13 @@ import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.request.mapper.parameter.PageParameters; -public abstract class AbstractChangePassword extends BasePage { +abstract class AbstractChangePassword extends BaseReauthPage { private static final long serialVersionUID = 5889157642852559004L; private static final String CHANGE_PASSWORD = "page.changePassword"; - public AbstractChangePassword(final PageParameters parameters) { + protected AbstractChangePassword(final PageParameters parameters) { super(parameters, CHANGE_PASSWORD); WebMarkupContainer content = new WebMarkupContainer("content"); diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseExtPage.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseExtPage.java index 30238672cd5..7a477848c17 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseExtPage.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseExtPage.java @@ -24,10 +24,6 @@ public abstract class BaseExtPage extends BasePage { private static final long serialVersionUID = 4627828052717627159L; - public BaseExtPage() { - super(); - } - public BaseExtPage(final PageParameters parameters, final String name) { super(parameters, name); } diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BasePage.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BasePage.java index a0d13ea43a0..93197b6f420 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BasePage.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BasePage.java @@ -19,11 +19,8 @@ package org.apache.syncope.client.enduser.pages; import java.io.Serializable; -import java.util.List; import org.apache.syncope.client.enduser.SyncopeEnduserSession; import org.apache.syncope.client.enduser.SyncopeWebApplication; -import org.apache.syncope.client.enduser.commons.EnduserConstants; -import org.apache.syncope.client.enduser.init.ClassPathScanImplementationLookup; import org.apache.syncope.client.enduser.panels.Sidebar; import org.apache.syncope.client.enduser.wicket.markup.head.MetaHeaderItem; import org.apache.syncope.client.ui.commons.BaseSession; @@ -47,17 +44,13 @@ import org.apache.wicket.markup.html.link.BookmarkablePageLink; import org.apache.wicket.model.ResourceModel; import org.apache.wicket.request.mapper.parameter.PageParameters; -import org.apache.wicket.spring.injection.annot.SpringBean; -public class BasePage extends BaseWebPage { +public abstract class BasePage extends BaseWebPage { private static final long serialVersionUID = 1571997737305598502L; protected static final HeaderItem META_IE_EDGE = new MetaHeaderItem("X-UA-Compatible", "IE=edge"); - @SpringBean - private ClassPathScanImplementationLookup lookup; - protected final Sidebar sidebar; protected final WebMarkupContainer contentWrapper; @@ -66,10 +59,6 @@ public class BasePage extends BaseWebPage { protected final AjaxLink collapse; - public BasePage() { - this(null, null); - } - public BasePage(final PageParameters parameters, final String name) { super(parameters); @@ -80,17 +69,12 @@ public BasePage(final PageParameters parameters, final String name) { // sidebar Class clazz = SyncopeWebApplication.get().getSidebar(); - try { - sidebar = clazz.getConstructor( - String.class, - PageReference.class, - List.class). - newInstance("sidebar", getPageReference(), lookup.getExtPageClasses()); + sidebar = clazz.getConstructor(String.class, PageReference.class). + newInstance("sidebar", getPageReference()); } catch (Exception e) { throw new IllegalArgumentException("Could not instantiate " + clazz.getName(), e); } - sidebar.setOutputMarkupPlaceholderTag(true); body.add(sidebar); @@ -157,7 +141,7 @@ public void renderHead(final IHeaderResponse response) { } protected void addPageTitle(final String title) { - contentWrapper.addOrReplace(new Label(EnduserConstants.PAGE_TITLE, new ResourceModel(title, title))); + contentWrapper.addOrReplace(new Label("pageTitle", new ResourceModel(title, title))); } protected void disableSidebarAndNavbar() { diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseReauthPage.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseReauthPage.java new file mode 100644 index 00000000000..8bc66fd30a2 --- /dev/null +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/BaseReauthPage.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.enduser.pages; + +import com.googlecode.wicket.kendo.ui.widget.notification.Notification; +import org.apache.syncope.client.enduser.SyncopeEnduserSession; +import org.apache.syncope.client.ui.commons.Constants; +import org.apache.wicket.RestartResponseAtInterceptPageException; +import org.apache.wicket.request.mapper.parameter.PageParameters; + +abstract class BaseReauthPage extends BasePage { + + private static final long serialVersionUID = 417902520012512819L; + + protected BaseReauthPage(final PageParameters parameters, final String name) { + super(parameters, name); + + if (isReauthExpired()) { + LOG.debug("Re-authentication needed to proceed"); + + PageParameters notification = new PageParameters(); + notification.add(Constants.NOTIFICATION_MSG_PARAM, getString("reauth.message")); + notification.add(Constants.NOTIFICATION_LEVEL_PARAM, Notification.WARNING); + + throw new RestartResponseAtInterceptPageException(ReauthLogin.class, notification); + } else { + SyncopeEnduserSession.get().clearLastReauth(); + LOG.debug("Re-authentication cleared"); + } + } + + protected boolean isReauthExpired() { + return SyncopeEnduserSession.get().isReauthExpired(); + } +} diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditChangePassword.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditChangePassword.java index be6053bdd84..85db92c7f76 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditChangePassword.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditChangePassword.java @@ -48,17 +48,18 @@ protected void doPwdSubmit(final AjaxRequestTarget target, final AjaxPasswordFie try { UserTO userTO = getPwdLoggedUser(); // update and set page paramters according to provisioning result - ProvisioningResult provisioningResult = - userSelfRestClient.update( - userTO.getETagValue(), - new UserUR.Builder(userTO.getKey()). - password(new PasswordPatch.Builder(). - value(passwordField.getModelObject()).onSyncope(true). - resources(userTO.getResources()). - build()). - build()); + ProvisioningResult provisioningResult = userSelfRestClient.update( + userTO.getETagValue(), + new UserUR.Builder(userTO.getKey()). + password(new PasswordPatch.Builder(). + value(passwordField.getModelObject()).onSyncope(true). + resources(userTO.getResources()). + build()). + build()); setResponsePage(new SelfResult(provisioningResult, - ProvisioningUtils.managePageParams(EditChangePassword.this, "pwd.change", + ProvisioningUtils.managePageParams( + EditChangePassword.this, + "pwd.change", !SyncopeWebApplication.get().isReportPropagationErrors() || provisioningResult.getPropagationStatuses().stream(). allMatch(ps -> ExecStatus.SUCCESS == ps.getStatus())))); diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.java index 065babe8fb9..f766ce679ae 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.java @@ -52,7 +52,7 @@ import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.spring.injection.annot.SpringBean; -public class EditSecurityQuestion extends BasePage { +public class EditSecurityQuestion extends BaseReauthPage { private static final long serialVersionUID = -537205681762708502L; diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditUser.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditUser.java index c890664ef14..f0da5153383 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditUser.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/EditUser.java @@ -27,7 +27,7 @@ import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.request.mapper.parameter.PageParameters; -public class EditUser extends BasePage { +public class EditUser extends BaseReauthPage { private static final long serialVersionUID = -1100228004207271270L; diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/Login.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/Login.java index 776faabc63d..e956d28d32a 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/Login.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/Login.java @@ -28,19 +28,19 @@ import org.apache.syncope.client.enduser.SyncopeWebApplication; import org.apache.syncope.client.ui.commons.BaseLogin; import org.apache.syncope.client.ui.commons.BaseSession; +import org.apache.syncope.client.ui.commons.panels.BaseSSOLoginFormPanel; import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.html.link.BookmarkablePageLink; -import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.request.mapper.parameter.PageParameters; public class Login extends BaseLogin { private static final long serialVersionUID = 5889157642852559004L; - private final BookmarkablePageLink selfPwdReset; + protected final BookmarkablePageLink selfPwdReset; - private final BookmarkablePageLink selfRegistration; + protected final BookmarkablePageLink selfRegistration; public Login(final PageParameters parameters) { super(parameters); @@ -70,8 +70,8 @@ protected BaseSession getBaseSession() { } @Override - protected List getSSOLoginFormPanels() { - List ssoLoginFormPanels = new ArrayList<>(); + protected List getSSOLoginFormPanels() { + List ssoLoginFormPanels = new ArrayList<>(); SyncopeWebApplication.get().getLookup().getSSOLoginFormPanels().forEach(ssoLoginFormPanel -> { try { ssoLoginFormPanels.add(ssoLoginFormPanel.getConstructor(String.class, BaseSession.class).newInstance( @@ -88,6 +88,18 @@ protected void sendError(final String error) { SyncopeEnduserSession.get().error(error); } + protected void onAuthenticateSuccess(final AjaxRequestTarget target) { + // If login has been called because the user was not yet logged in, than continue to the + // original destination, otherwise to the Home page + continueToOriginalDestination(); + setResponsePage(getApplication().getHomePage()); + } + + protected void onAuthenticateFailure(final AjaxRequestTarget target) { + SyncopeEnduserSession.get().error(getString("login-error")); + notificationPanel.refresh(target); + } + @Override protected void authenticate(final String username, final String password, final AjaxRequestTarget target) throws NotAuthorizedException { @@ -99,13 +111,9 @@ protected void authenticate(final String username, final String password, final } if (SyncopeEnduserSession.get().authenticate(username, password)) { - // If login has been called because the user was not yet logged in, than continue to the - // original destination, otherwise to the Home page - continueToOriginalDestination(); - setResponsePage(getApplication().getHomePage()); + onAuthenticateSuccess(target); } else { - SyncopeEnduserSession.get().error(getString("login-error")); - notificationPanel.refresh(target); + onAuthenticateFailure(target); } } } diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/MustChangePassword.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/MustChangePassword.java index 48318cd4217..7be2655617d 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/MustChangePassword.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/MustChangePassword.java @@ -43,6 +43,11 @@ public MustChangePassword(final PageParameters parameters) { disableSidebarAndNavbar(); } + @Override + protected boolean isReauthExpired() { + return false; + } + @Override protected void doPwdSubmit(final AjaxRequestTarget target, final AjaxPasswordFieldPanel passwordField) { try { diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/ReauthLogin.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/ReauthLogin.java new file mode 100644 index 00000000000..ec5da8fc7c4 --- /dev/null +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/pages/ReauthLogin.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.enduser.pages; + +import java.util.List; +import org.apache.syncope.client.enduser.SyncopeEnduserSession; +import org.apache.syncope.client.ui.commons.panels.BaseSSOLoginFormPanel; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.request.mapper.parameter.PageParameters; + +public class ReauthLogin extends Login { + + private static final long serialVersionUID = -218346357365913190L; + + public ReauthLogin(final PageParameters parameters) { + super(parameters); + + SyncopeEnduserSession session = SyncopeEnduserSession.get(); + + usernameField.setEnabled(false); + usernameField.setModelObject(session.getSelfTO().getUsername()); + usernameField.modelChanged(); + + languageSelect.setEnabled(false); + languageSelect.setModelObject(session.getLocale()); + languageSelect.modelChanged(); + + domainSelect.setEnabled(false); + domainSelect.setModelObject(session.getDomain()); + domainSelect.modelChanged(); + + selfPwdReset.setVisible(false); + selfRegistration.setVisible(false); + } + + @Override + protected List getSSOLoginFormPanels() { + List panels = super.getSSOLoginFormPanels(); + panels.forEach(panel -> panel.setReauth(true)); + return panels; + } + + @Override + protected void onAuthenticateSuccess(final AjaxRequestTarget target) { + SyncopeEnduserSession.get().setLastReauth(); + super.onAuthenticateSuccess(target); + } +} diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/Sidebar.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/Sidebar.java index 06f9dc306f2..d0dc14ec937 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/Sidebar.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/Sidebar.java @@ -19,7 +19,6 @@ package org.apache.syncope.client.enduser.panels; import java.util.List; -import java.util.stream.Collectors; import java.util.stream.StreamSupport; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.client.enduser.BookmarkablePageLinkBuilder; @@ -31,7 +30,9 @@ import org.apache.syncope.client.enduser.pages.EditChangePassword; import org.apache.syncope.client.enduser.pages.EditSecurityQuestion; import org.apache.syncope.client.enduser.pages.EditUser; +import org.apache.syncope.client.ui.commons.annotations.AMPage; import org.apache.syncope.client.ui.commons.annotations.ExtPage; +import org.apache.syncope.client.ui.commons.annotations.IdMPage; import org.apache.wicket.AttributeModifier; import org.apache.wicket.Component; import org.apache.wicket.Page; @@ -66,11 +67,7 @@ protected static String getULContainerId(final String linkId) { protected WebMarkupContainer profileLIContainer; - public Sidebar( - final String id, - final PageReference pageRef, - final List> extPageClasses) { - + public Sidebar(final String id, final PageReference pageRef) { super(id); buildBaseSidebar(); @@ -130,10 +127,83 @@ public void onComponentTag(final Component component, final ComponentTag tag) { } } + List> idmPageClasses = SyncopeWebApplication.get().getLookup().getIdMPageClasses(); + ListView> idmPages = new ListView<>("idmPages", idmPageClasses) { + + private static final long serialVersionUID = 4949588177564901031L; + + @Override + protected void populateItem(final ListItem> item) { + WebMarkupContainer containingLI = new WebMarkupContainer("idmPageLI"); + item.add(containingLI); + + IdMPage ann = item.getModelObject().getAnnotation(IdMPage.class); + + BookmarkablePageLink link = new BookmarkablePageLink<>("idmPage", item.getModelObject()); + + link.add(new Label("idmPageLabel", ann.label())); + + if (item.getModelObject().equals(pageRef.getPage().getClass())) { + link.add(new Behavior() { + + private static final long serialVersionUID = 1469628524240283489L; + + @Override + public void onComponentTag(final Component component, final ComponentTag tag) { + tag.append("class", "active", " "); + } + }); + } + containingLI.add(link); + + Label idmPageIcon = new Label("idmPageIcon"); + idmPageIcon.add(new AttributeModifier("class", "nav-icon " + ann.icon())); + link.add(idmPageIcon); + } + }; + add(idmPages.setRenderBodyOnly(true).setOutputMarkupId(true)); + + List> amPageClasses = SyncopeWebApplication.get().getLookup().getAMPageClasses(); + ListView> amPages = new ListView<>("amPages", amPageClasses) { + + private static final long serialVersionUID = 4949588177564901031L; + + @Override + protected void populateItem(final ListItem> item) { + WebMarkupContainer containingLI = new WebMarkupContainer("amPageLI"); + item.add(containingLI); + + AMPage ann = item.getModelObject().getAnnotation(AMPage.class); + + BookmarkablePageLink link = new BookmarkablePageLink<>("amPage", item.getModelObject()); + + link.add(new Label("amPageLabel", ann.label())); + + if (item.getModelObject().equals(pageRef.getPage().getClass())) { + link.add(new Behavior() { + + private static final long serialVersionUID = 1469628524240283489L; + + @Override + public void onComponentTag(final Component component, final ComponentTag tag) { + tag.append("class", "active", " "); + } + }); + } + containingLI.add(link); + + Label amPageIcon = new Label("amPageIcon"); + amPageIcon.add(new AttributeModifier("class", "nav-icon " + ann.icon())); + link.add(amPageIcon); + } + }; + add(amPages.setRenderBodyOnly(true).setOutputMarkupId(true)); + + List> extPageClasses = SyncopeWebApplication.get().getLookup().getExtPageClasses(); ListView> extPages = new ListView<>("extPages", extPageClasses.stream(). filter(epc -> SyncopeWebApplication.get().getCustomFormLayout().getSidebarLayout(). isExtensionEnabled(StringUtils.remove(epc.getAnnotation(ExtPage.class).label(), StringUtils.SPACE))). - collect(Collectors.toList())) { + toList()) { private static final long serialVersionUID = 4949588177564901031L; @@ -172,7 +242,6 @@ public void onComponentTag(final Component component, final ComponentTag tag) { link.add(extPageIcon); } }; - add(extPages.setRenderBodyOnly(true).setOutputMarkupId(true)); } @@ -195,12 +264,11 @@ protected void buildBaseSidebar() { WebMarkupContainer liContainer = new WebMarkupContainer(getLIContainerId("edituser")); profileULContainer.add(liContainer); - liContainer.add(BookmarkablePageLinkBuilder.build("edituser", EditUser.class)). setVisible(layout.isEditUserEnabled()); + liContainer = new WebMarkupContainer(getLIContainerId("editchangepassword")); profileULContainer.add(liContainer); - liContainer.add(BookmarkablePageLinkBuilder.build("editchangepassword", EditChangePassword.class)). setVisible(layout.isPasswordManagementEnabled()); diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserFormPanel.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserFormPanel.java index 46d589638bb..c2db2294cb5 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserFormPanel.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/panels/UserFormPanel.java @@ -111,8 +111,11 @@ protected void onFormSubmit(final AjaxRequestTarget target) { ProvisioningResult provisioningResult = updateReq.isEmpty() ? new ProvisioningResult<>() : userSelfRestClient.update(getOriginalItem().getInnerObject().getETagValue(), updateReq); - setResponsePage(new SelfResult(provisioningResult, - ProvisioningUtils.managePageParams(UserFormPanel.this, "profile.change", + setResponsePage(new SelfResult( + provisioningResult, + ProvisioningUtils.managePageParams( + UserFormPanel.this, + "profile.change", !SyncopeWebApplication.get().isReportPropagationErrors() || provisioningResult.getPropagationStatuses().stream() .allMatch(ps -> ExecStatus.SUCCESS == ps.getStatus())))); diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/rest/SyncopeRestClient.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/rest/SyncopeRestClient.java index 18dbfe05a51..2ca11d8dc64 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/rest/SyncopeRestClient.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/rest/SyncopeRestClient.java @@ -19,7 +19,6 @@ package org.apache.syncope.client.enduser.rest; import java.util.List; -import org.apache.syncope.common.lib.to.TypeExtensionTO; import org.apache.syncope.common.rest.api.service.SyncopeService; public class SyncopeRestClient extends BaseRestClient { @@ -27,13 +26,11 @@ public class SyncopeRestClient extends BaseRestClient { private static final long serialVersionUID = -2211371717449597247L; public List searchUserTypeExtensions(final String groupName) { - List types = List.of(); try { - TypeExtensionTO typeExtensionTO = getService(SyncopeService.class).readUserTypeExtension(groupName); - types = typeExtensionTO == null ? types : typeExtensionTO.getAuxClasses(); + return getService(SyncopeService.class).readUserTypeExtension(groupName).getAuxClasses(); } catch (Exception e) { - LOG.error("While reading all any type classes for group [{}]", groupName, e); + LOG.debug("While reading any type classes for type extension of group {}", groupName, e); + return List.of(); } - return types; } } diff --git a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/widgets/UserProfileWidget.java b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/widgets/UserProfileWidget.java index 9f52674d142..9a4fd7dfee5 100644 --- a/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/widgets/UserProfileWidget.java +++ b/client/idrepo/enduser/src/main/java/org/apache/syncope/client/enduser/widgets/UserProfileWidget.java @@ -47,10 +47,6 @@ public UserProfileWidget(final String id) { } protected void addBaseFields(final WebMarkupContainer userProfile) { - Label username = new Label("username", userTO.getUsername()); - username.setOutputMarkupId(true); - userProfile.add(username); - Label changePwdDate = new Label("changePwdDate", userTO.getChangePwdDate()); changePwdDate.setOutputMarkupId(true); userProfile.add(changePwdDate); diff --git a/client/idrepo/enduser/src/main/resources/enduser.properties b/client/idrepo/enduser/src/main/resources/enduser.properties index dbb723008cd..eb30724e808 100644 --- a/client/idrepo/enduser/src/main/resources/enduser.properties +++ b/client/idrepo/enduser/src/main/resources/enduser.properties @@ -50,6 +50,7 @@ enduser.maxUploadFileSizeMB=5 enduser.x-forward=true enduser.captcha=true +enduser.reauth-expiration-minutes-timeout=1 enduser.reportPropagationErrors=true enduser.reportPropagationErrorDetails=true enduser.csrf=true diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication.properties index 73f7b76e6b0..160f91c717f 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication.properties @@ -85,7 +85,7 @@ tooLargeFile=File is too large, max upload file size is ${maxUploadSizeB} bytes home=Home profile=Personal Information requests=User Requests -edituser=Edit profile +edituser=Profile submit=Submit cancel=Cancel editchangepassword=Change password @@ -98,7 +98,7 @@ user_request_error=Error during user request. Please contact your administrator page.home=Home page.changePassword=Change Password page.editSecurityQuestion=Edit Security Question -page.edituser=Edit User +page.edituser=Profile page.confirmPasswordReset=Confirm Password Reset page.selfPwdReset=Password Reset page.selfRegistration=Registration diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_fr_CA.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_fr_CA.properties index 56d614e715f..b7b5740c7a7 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_fr_CA.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_fr_CA.properties @@ -84,7 +84,7 @@ tooLargeFile=Le fichier est trop grand, la taille du fichier de t\u00e9l\u00e9ch home=Aper\u00e7u profile=Information personnelle requests=Demandes des utilisateurs -edituser=Editer le profil +edituser=Profil submit=Soumettre cancel=Annuler editchangepassword=Changer mot de passe @@ -97,7 +97,7 @@ user_request_error=Erreur lors de la demande de l'utilisateur. Veuillez contacte page.home=Aper\u00e7u page.changePassword=Changer mot de passe page.editSecurityQuestion=Modifier la question de s\u00e9curit\u00e9 -page.edituser=Modifier l'utilisateur +page.edituser=Profil page.confirmPasswordReset=Confirm Password Reset page.selfPwdReset=Password Reset page.selfRegistration=Enregistrement diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_it.properties index dd048076309..dc325d6f8c7 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_it.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_it.properties @@ -81,16 +81,16 @@ invalid.security.answer=Risposta di sicurezza non valida tooLargeFile=File troppo grande, la dimensione massima ammessa \\u00e8 ${maxUploadSizeB} bytes (${maxUploadSizeMB} MB). home=Home profile=Informazioni personali -requests=User Requests -edituser=Modifica profilo -submit=Submit -cancel=Cancel +requests=Richieste utente +edituser=Profilo +submit=Invia +cancel=Annulla editchangepassword=Gestione password -attributes.derived=Derived Attributes -attributes.plain=Plain Attributes +attributes.derived=Attributi Derivati +attributes.plain=Attributi captcha=Captcha -details=Details -user-requests-link=User Requests +details=Dettagli +user-requests-link=Richieste utente self-pwd-reset-link=Self Password Reset self-registration-link=Self Registration user_request_error=Errore durante la richiesta. Si prega di contattare l'amministratore di sistema. @@ -98,7 +98,7 @@ user_request_error=Errore durante la richiesta. Si prega di contattare l'amminis page.home=Home page.changePassword=Cambio Password page.editSecurityQuestion=Modifica domanda segreta -page.edituser=Modifica profilo +page.edituser=Profilo page.confirmPasswordReset=Conferma Reset Password page.selfPwdReset=Password Reset page.selfRegistration=Self Registration diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ja.properties index 4b9640769ed..4b48338b43b 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ja.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ja.properties @@ -80,7 +80,7 @@ tooLargeFile=File is too large, max upload file size is ${maxUploadSizeB} bytes home=Home profile=Personal Information requests=User Requests -edituser=\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u7de8\u96c6 +edituser=Profile submit=Submit cancel=Cancel editchangepassword=Change password @@ -96,7 +96,7 @@ user_request_error=\u30e6\u30fc\u30b6\u30fc\u30ea\u30af\u30a8\u30b9\u30c8\u4e2d\ page.home=Home page.changePassword=Change Password page.editSecurityQuestion=Edit Security Question -page.edituser=Edit User +page.edituser=Profile page.confirmPasswordReset=Confirm Password Reset page.selfPwdReset=Password Reset page.selfRegistration=Registration diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_pt_BR.properties index 45fc6c0abe2..cd544991713 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_pt_BR.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_pt_BR.properties @@ -98,7 +98,7 @@ user_request_error=Erro durante a solicita\u00e7\u00e3o do usu\u00e1rio. Por fav page.home=Home page.changePassword=Change Password page.editSecurityQuestion=Edit Security Question -page.edituser=Edit User +page.edituser=Profile page.confirmPasswordReset=Confirm Password Reset page.selfPwdReset=Password Reset page.selfRegistration=Registration diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ru.properties index 4e79d544b0e..5f0346504cd 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ru.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/SyncopeEnduserApplication_ru.properties @@ -81,7 +81,7 @@ tooLargeFile=File is too large, max upload file size is ${maxUploadSizeB} bytes home=Home profile=Personal Information requests=User Requests -edituser=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0444\u0438\u043b\u044c +edituser=Profile submit=Submit cancel=Cancel editchangepassword=Change password @@ -97,7 +97,7 @@ user_request_error=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043 page.home=Home page.changePassword=Change Password page.editSecurityQuestion=Edit Security Question -page.edituser=Edit User +page.edituser=Profile page.confirmPasswordReset=Confirm Password Reset page.selfPwdReset=Password Reset page.selfRegistration=Registration diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage.properties new file mode 100644 index 00000000000..1754bfabae6 --- /dev/null +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage.properties @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +reauth.message=Please authenticate again to proceed diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_fr.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_fr.properties new file mode 100644 index 00000000000..1754bfabae6 --- /dev/null +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_fr.properties @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +reauth.message=Please authenticate again to proceed diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_it.properties new file mode 100644 index 00000000000..ef988d7b2d9 --- /dev/null +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_it.properties @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +reauth.message=Si prega di autenticarsi per procedere diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_ja.properties new file mode 100644 index 00000000000..1754bfabae6 --- /dev/null +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_ja.properties @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +reauth.message=Please authenticate again to proceed diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_pt_BR.properties new file mode 100644 index 00000000000..1754bfabae6 --- /dev/null +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_pt_BR.properties @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +reauth.message=Please authenticate again to proceed diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_ru.properties new file mode 100644 index 00000000000..1754bfabae6 --- /dev/null +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/BaseReauthPage_ru.properties @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +reauth.message=Please authenticate again to proceed diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword.properties index 451aab80712..8149cbc7b32 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword.properties @@ -15,8 +15,6 @@ # specific language governing permissions and limitations # under the License. password=Password -submit=Change -cancel=Cancel confirmPassword=Password (confirm) passwordNeedsToBeUpdated=Password needs to be updated self.pwd.change.success.msg=Password successfully changed diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_fr_CA.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_fr_CA.properties index eb20e467e1a..ba9c4c8c5cb 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_fr_CA.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_fr_CA.properties @@ -14,8 +14,6 @@ # limitations under the License. # password=Mot de passe -submit=Modifier -cancel=Annuler confirmPassword=Confirmer le mot de passe passwordNeedsToBeUpdated=Le mot de passe doit \u00eatre mis \u00e0 jour self.pwd.change.success.msg=Mot de passe chang\u00e9 avec succ\u00e8s diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_it.properties index 0b6cc617780..e95f5f65f40 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_it.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_it.properties @@ -15,8 +15,6 @@ # specific language governing permissions and limitations # under the License. password=Password -submit=Cambia -cancel=Annulla confirmPassword=Password (conferma) passwordNeedsToBeUpdated=La password deve essere aggiornata self.pwd.change.success.msg=Password aggiornata con successo diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_ja.properties index 9361a166695..ca3081b38b9 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_ja.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_ja.properties @@ -15,8 +15,6 @@ # specific language governing permissions and limitations # under the License. password=\u30d1\u30b9\u30ef\u30fc\u30c9 -submit=\u5909\u66f4 -cancel=\u30ad\u30e3\u30f3\u30bb\u30eb confirmPassword=\u30d1\u30b9\u30ef\u30fc\u30c9 (\u78ba\u8a8d) passwordNeedsToBeUpdated=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u66f4\u65b0\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059 self.pwd.change.success.msg=\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u6b63\u5e38\u306b\u5909\u66f4\u3055\u308c\u307e\u3057\u305f diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_pt_BR.properties index a54d21540a4..834af24b0f0 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_pt_BR.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_pt_BR.properties @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. password=Senha -submit=Alterar confirmPassword=Senha (confirmar) passwordNeedsToBeUpdated=Senha precisa ser atualizado self.pwd.change.success.msg=Senha mudada com sucesso @@ -23,4 +22,3 @@ self.pwd.change.success.msg=Senha mudada com sucesso self.pwd.change.error=Incapaz de completar a mudan\u00e7a de senha self.pwd.change.error.msg=Incapaz de completar a mudan\u00e7a de senha self.pwd.change.success=Alterado com sucesso -cancel=Cancelar diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_ru.properties index dc396f8f991..c9c50992511 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_ru.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditChangePassword_ru.properties @@ -15,9 +15,6 @@ # specific language governing permissions and limitations # under the License. password=\u041f\u0430\u0440\u043e\u043b\u044c -# submit=\u00d0\u0098\u00d0\u00b7\u00d0\u00bc\u00d0\u00b5\u00d0\u00bd\u00d0\u00b8\u00d1\u0082\u00d1\u008c -submit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c -cancel=\u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c #confirmPassword=\u00d0\u009f\u00d0\u00b0\u00d1\u0080\u00d0\u00be\u00d0\u00bb\u00d1\u008c (\u00d0\u00bf\u00d0\u00be\u00d0\u00b4\u00d1\u0082\u00d0\u00b2\u00d0\u00b5\u00d1\u0080\u00d0\u00b6\u00d0\u00b4\u00d0\u00b5\u00d0\u00bd\u00d0\u00b8\u00d0\u00b5) confirmPassword=\u041f\u0430\u0440\u043e\u043b\u044c (\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435) # passwordNeedsToBeUpdated=\u00d0\u009f\u00d0\u00b0\u00d1\u0080\u00d0\u00be\u00d0\u00bb\u00d1\u008c \u00d0\u00b4\u00d0\u00be\u00d0\u00bb\u00d0\u00b6\u00d0\u00b5\u00d0\u00bd \u00d0\u00b1\u00d1\u008b\u00d1\u0082\u00d1\u008c \u00d0\u00b8\u00d0\u00b7\u00d0\u00bc\u00d0\u00b5\u00d0\u00bd\u00d1\u0091\u00d0\u00bd diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.properties index 2a001b7ad08..f8a85d71798 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion.properties @@ -15,9 +15,9 @@ # specific language governing permissions and limitations # under the License. password=Password -submit=Change -cancel=Cancel self.securityquestion.change.success=Successfully changed self.securityquestion.change.error=Unable to change the security question self.securityquestion.change.error.msg=Please contact an administrator self.securityquestion.change.success.msg=Security question changed successfully +securityQuestion=Security Question +securityAnswer=Security Answer diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_it.properties index 6920aca5de3..dd175f97ded 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_it.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_it.properties @@ -15,9 +15,9 @@ # specific language governing permissions and limitations # under the License. password=Password -submit=Cambia -cancel=Annulla self.securityquestion.change.success=Aggiornamento avvenuto con successo self.securityquestion.change.error=Errore durante il cambio della domanda di sicurezza self.securityquestion.change.error.msg=Errore durante la richiesta. Si prega di contattare l'amministratore di sistema. self.securityquestion.change.success.msg=Aggiornamento della domanda di sicurezza avvenuto con successo +securityQuestion=Domanda di sicurezza +securityAnswer=Risposta di sicurezza diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_ja.properties index a5a6bcbbf97..fff0798c65a 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_ja.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_ja.properties @@ -15,9 +15,9 @@ # specific language governing permissions and limitations # under the License. password=\u30d1\u30b9\u30ef\u30fc\u30c9 -submit=\u5909\u66f4 -cancel=\u30ad\u30e3\u30f3\u30bb\u30eb self.securityquestion.change.success=\u6b63\u5e38\u306b\u5909\u66f4\u3055\u308c\u307e\u3057\u305f self.securityquestion.change.error=\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u5909\u66f4\u3092\u5b8c\u4e86\u3067\u304d\u307e\u305b\u3093 self.securityquestion.change.error.msg=\u30d1\u30b9\u30ef\u30fc\u30c9\u30ea\u30bb\u30c3\u30c8\u306e\u78ba\u8a8d\u3092\u5b8c\u4e86\u3067\u304d\u307e\u305b\u3093 self.securityquestion.change.success.msg=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u306e\u8cea\u554f\u304c\u6b63\u5e38\u306b\u5909\u66f4\u3055\u308c\u307e\u3057\u305f +securityQuestion=Security Question +securityAnswer=Security Answer diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_pt_BR.properties index 7ded2ebfb10..f3429a1ef7d 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_pt_BR.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_pt_BR.properties @@ -15,9 +15,10 @@ # specific language governing permissions and limitations # under the License. password=Senha -submit=Alterar self.securityquestion.change.success=Alterado com sucesso self.securityquestion.change.error=Incapaz de completar a mudan\u00e7a de senha self.securityquestion.change.error.msg=Incapaz de completar a mudan\u00e7a de senha self.securityquestion.change.success.msg=Pergunta de seguran\u00e7a alterada com sucesso +securityQuestion=Security Question +securityAnswer=Security Answer diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_ru.properties index 616ccfa4253..972a36f9cac 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_ru.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditSecurityQuestion_ru.properties @@ -15,10 +15,9 @@ # specific language governing permissions and limitations # under the License. password=\u041f\u0430\u0440\u043e\u043b\u044c -# submit=\u00d0\u0098\u00d0\u00b7\u00d0\u00bc\u00d0\u00b5\u00d0\u00bd\u00d0\u00b8\u00d1\u0082\u00d1\u008c -submit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c -cancel=\u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c self.securityquestion.change.success=\u0423\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043e self.securityquestion.change.error=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u0441\u043c\u0435\u043d\u0443 \u043f\u0430\u0440\u043e\u043b\u044f self.securityquestion.change.error.msg=\u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0441\u0432\u044f\u0436\u0438\u0442\u0435\u0441\u044c \u0441 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u043c self.securityquestion.change.success.msg=\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d +securityQuestion=Security Question +securityAnswer=Security Answer diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.html b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.html index c1b74ac6279..60371878490 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.html +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.html @@ -18,18 +18,18 @@ under the License. --> - +
-
-
- -
-
- -
-
+
+
+ +
+
+
+
+
-
+
diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties index 633e2c50335..b9100c3071a 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/EditUser.properties @@ -17,7 +17,3 @@ overview=Overview control=Control accessTokens=Access Tokens -palette.available=Available -palette.selected=Selected -submit=Change -cancel=Cancel diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword.properties index 899a97cd2b8..9f8e9830487 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword.properties @@ -16,11 +16,8 @@ # under the License. username=Username password=Password -submit=Change -cancel=Cancel confirmPassword=Password (confirm) passwordNeedsToBeUpdated=Password needs to be updated self.pwd.change.success=Password successfully changed -Cancel=Cancel self.pwd.change.error=Unable to complete the change password self.pwd.change.error.msg=Please contact an administrator diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_it.properties index bfc68736031..bf7394e52fa 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_it.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_it.properties @@ -16,12 +16,8 @@ # under the License. username=Username password=Password -submit=Cambia -cancel=Annulla confirmPassword=Password (conferma) passwordNeedsToBeUpdated=La password deve essere aggiornata self.pwd.change.success=Password aggiornata con successo - -Cancel=Annulla self.pwd.change.error=Errore durante il cambio password self.pwd.change.error.msg=Errore durante la richiesta. Si prega di contattare l'amministratore di sistema. diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_ja.properties index ea0d5bf94fd..d6a98bbc761 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_ja.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_ja.properties @@ -16,12 +16,8 @@ # under the License. username=\u30e6\u30fc\u30b6\u30fc\u540d password=\u30d1\u30b9\u30ef\u30fc\u30c9 -submit=\u5909\u66f4 -cancel=\u30ad\u30e3\u30f3\u30bb\u30eb confirmPassword=\u30d1\u30b9\u30ef\u30fc\u30c9 (\u78ba\u8a8d) passwordNeedsToBeUpdated=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u66f4\u65b0\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059 self.pwd.change.success=\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u6b63\u5e38\u306b\u5909\u66f4\u3055\u308c\u307e\u3057\u305f - -Cancel=\u30ad\u30e3\u30f3\u30bb\u30eb self.pwd.change.error=\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u5909\u66f4\u3092\u5b8c\u4e86\u3067\u304d\u307e\u305b\u3093 self.pwd.change.error.msg=\u30d1\u30b9\u30ef\u30fc\u30c9\u30ea\u30bb\u30c3\u30c8\u306e\u78ba\u8a8d\u3092\u5b8c\u4e86\u3067\u304d\u307e\u305b\u3093 diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_pt_BR.properties index f5e4aba8087..640a826ee12 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_pt_BR.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_pt_BR.properties @@ -16,8 +16,6 @@ # under the License. username=Usu\u00e1rio password=Senha -submit=Alterar -Cancel=Cancelar confirmPassword=Senha (confirmar) passwordNeedsToBeUpdated=Senha precisa ser atualizado self.pwd.change.success=Senha mudada com sucesso diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_ru.properties index 1d7af162acf..ce36ebe4f1a 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_ru.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/MustChangePassword_ru.properties @@ -17,15 +17,10 @@ username=\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f # password=\u00d0\u009f\u00d0\u00b0\u00d1\u0080\u00d0\u00be\u00d0\u00bb\u00d1\u008c password=\u041f\u0430\u0440\u043e\u043b\u044c -# submit=\u00d0\u0098\u00d0\u00b7\u00d0\u00bc\u00d0\u00b5\u00d0\u00bd\u00d0\u00b8\u00d1\u0082\u00d1\u008c -submit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c -cancel=\u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c #confirmPassword=\u00d0\u009f\u00d0\u00b0\u00d1\u0080\u00d0\u00be\u00d0\u00bb\u00d1\u008c (\u00d0\u00bf\u00d0\u00be\u00d0\u00b4\u00d1\u0082\u00d0\u00b2\u00d0\u00b5\u00d1\u0080\u00d0\u00b6\u00d0\u00b4\u00d0\u00b5\u00d0\u00bd\u00d0\u00b8\u00d0\u00b5) confirmPassword=\u041f\u0430\u0440\u043e\u043b\u044c (\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435) # passwordNeedsToBeUpdated=\u00d0\u009f\u00d0\u00b0\u00d1\u0080\u00d0\u00be\u00d0\u00bb\u00d1\u008c \u00d0\u00b4\u00d0\u00be\u00d0\u00bb\u00d0\u00b6\u00d0\u00b5\u00d0\u00bd \u00d0\u00b1\u00d1\u008b\u00d1\u0082\u00d1\u008c \u00d0\u00b8\u00d0\u00b7\u00d0\u00bc\u00d0\u00b5\u00d0\u00bd\u00d1\u0091\u00d0\u00bd passwordNeedsToBeUpdated=\u041f\u0430\u0440\u043e\u043b\u044c \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0451\u043d self.pwd.change.success=\u041f\u0430\u0440\u043e\u043b\u044c \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d - -Cancel=\u041e\u0442\u043c\u0435\u043d\u0430 self.pwd.change.error=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u0441\u043c\u0435\u043d\u0443 \u043f\u0430\u0440\u043e\u043b\u044f self.pwd.change.error.msg=\u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0441\u0432\u044f\u0436\u0438\u0442\u0435\u0441\u044c \u0441 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u043c diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.properties index c5da696e653..59b2080e7d8 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset.properties @@ -18,8 +18,6 @@ confirm-reset=Confirm password reset password=Password confirm-password=Confirm password password-strength=Password strength: -cancel=Cancel -submit=Submit self.confirm.pwd.reset.success=Password Changed! self.confirm.pwd.reset.success.msg=Password successfully changed self.confirm.pwd.reset.error.empty=No token was specified in the url, cannot access to the requested page diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_it.properties index 9500f0c356e..13baa1f0abb 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_it.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_it.properties @@ -18,8 +18,6 @@ confirm-reset=Conferma reset della password password=Password confirm-password=Conferma password password-strength=Sicurezza della password: -cancel=Annulla -submit=Invia self.confirm.pwd.reset.success=Password \u00e8 stata modificata self.confirm.pwd.reset.success.msg=Cambio password eseguito con successo self.confirm.pwd.reset.error.empty=Nessun token \u00e8 specificato nell'url, non \u00e8 possibile accedere alla pagina richiesta diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ja.properties index 7703a333205..a957cc1aa92 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ja.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ja.properties @@ -18,8 +18,6 @@ confirm-reset=\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u518d\u8a2d\u5b9a\u3092\u78ba password=\u30d1\u30b9\u30ef\u30fc\u30c9 confirm-password=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u8a8d\u8a3c\u3059\u308b password-strength=\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u5f37\u5ea6\uff1a -cancel=\u30ad\u30e3\u30f3\u30bb\u30eb -submit=\u63d0\u51fa\u3059\u308b self.confirm.pwd.reset.success=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u30ea\u30bb\u30c3\u30c8\u3057\u307e\u3057\u305f self.confirm.pwd.reset.error.empty=URL\u306b\u30c8\u30fc\u30af\u30f3\u304c\u6307\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u8981\u6c42\u3055\u308c\u305f\u30da\u30fc\u30b8\u306b\u30a2\u30af\u30bb\u30b9\u3067\u304d\u307e\u305b\u3093 self.confirm.pwd.reset.success.msg=Password Changed! diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_pt_BR.properties index 88202f91187..e219188cda0 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_pt_BR.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_pt_BR.properties @@ -18,8 +18,6 @@ confirm-reset=Confirme a redefini\u00e7\u00e3o da senha password=Senha confirm-password=Confirme a Senha password-strength=For\u00e7a da senha: -cancel=Cancelar -submit=Enviar self.confirm.pwd.reset.success=Senha redefinida com sucesso self.confirm.pwd.reset.success.msg=Senha redefinida com sucesso self.confirm.pwd.reset.error.empty=Nenhum token foi especificado na URL, n\u00e3o pode acessar a p\u00e1gina solicitada diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ru.properties index a1445b84fa9..03f1807d88d 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ru.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfConfirmPasswordReset_ru.properties @@ -18,8 +18,6 @@ confirm-reset=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 password=\u043f\u0430\u0440\u043e\u043b\u044c confirm-password=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u041f\u0430\u0440\u043e\u043b\u044c password-strength=\u041d\u0430\u0434\u0435\u0436\u043d\u043e\u0441\u0442\u044c \u041f\u0430\u0440\u043e\u043b\u044f: -cancel=\u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c -submit=\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c self.confirm.pwd.reset.success=\u041f\u0430\u0440\u043e\u043b\u044c \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0431\u0440\u043e\u0448\u0435\u043d self.confirm.pwd.reset.success.msg=\u041f\u0430\u0440\u043e\u043b\u044c \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0431\u0440\u043e\u0448\u0435\u043d self.confirm.pwd.reset.error.empty=\u0412 URL \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d \u0442\u043e\u043a\u0435\u043d, \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel.properties index 73ca456a860..5999bc1df17 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel.properties @@ -19,5 +19,3 @@ securityQuestion=Security Question securityAnswer=Security Answer reload=Reload not.loading=Not loading? -submit=Submit -cancel=Cancel diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_fr_CA.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_fr_CA.properties index 73ca456a860..5999bc1df17 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_fr_CA.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_fr_CA.properties @@ -19,5 +19,3 @@ securityQuestion=Security Question securityAnswer=Security Answer reload=Reload not.loading=Not loading? -submit=Submit -cancel=Cancel diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_it.properties index 5cc8c264360..d5e4542c3dc 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_it.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_it.properties @@ -19,5 +19,3 @@ securityQuestion=Domanda di sicurezza securityAnswer=Risposta di sicurezza reload=Ricarica not.loading=Non carica? -submit=Salva -cancel=Annulla diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_ja.properties index 54ca2b3dc00..8adddfa5397 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_ja.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_ja.properties @@ -19,5 +19,3 @@ securityQuestion=\u79d8\u5bc6\u306e\u8cea\u554f securityAnswer=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u56de\u7b54 reload=\u30ea\u30ed\u30fc\u30c9 not.loading=\u30ed\u30fc\u30c9\u3057\u3066\u3044\u307e\u305b\u3093\u304b\uff1f -submit=\u63d0\u51fa\u3059\u308b -cancel=\u30ad\u30e3\u30f3\u30bb\u30eb diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_pt_BR.properties index 0a1b647b44a..18507c777be 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_pt_BR.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_pt_BR.properties @@ -19,5 +19,3 @@ securityQuestion=Pergunta de Seguran\u00e7a securityAnswer=Resposta de seguran\u00e7a reload=recarregar not.loading=N\u00e3o est\u00e1 carregando? -submit=Enviar -cancel=Cancelar diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_ru.properties index 9287f4907a1..8615e445359 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_ru.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/SelfPasswordReset$SelfPwdResetPanel_ru.properties @@ -19,5 +19,3 @@ securityQuestion=\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u044b\u0 securityAnswer=\u041e\u0442\u0432\u0435\u0442 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 reload=\u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c not.loading=\u041d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f? -submit=\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c -cancel=\u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel.properties index f2447ea8211..8d767e27a2e 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel.properties @@ -16,9 +16,6 @@ # under the License. username=Username password=Password -submit=Change -cancel=Cancel confirmPassword=Password (confirm) passwordNeedsToBeUpdated=Password needs to be updated self.pwd.change.success=Password successfully changed -editchangepassword=Change password diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_it.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_it.properties index 0d65dc419c8..dd7759803f5 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_it.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_it.properties @@ -16,8 +16,6 @@ # under the License. username=Username password=Password -submit=Cambia -cancel=Annulla confirmPassword=Password (conferma) passwordNeedsToBeUpdated=La password deve essere aggiornata self.pwd.change.success=Password aggiornata con successo diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_ja.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_ja.properties index 34bb07ced31..6d3d9d66f4a 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_ja.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_ja.properties @@ -16,8 +16,6 @@ # under the License. username=\u30e6\u30fc\u30b6\u30fc\u540d password=\u30d1\u30b9\u30ef\u30fc\u30c9 -submit=\u5909\u66f4 -cancel=\u30ad\u30e3\u30f3\u30bb\u30eb confirmPassword=\u30d1\u30b9\u30ef\u30fc\u30c9 (\u78ba\u8a8d) passwordNeedsToBeUpdated=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u66f4\u65b0\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059 self.pwd.change.success=\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u6b63\u5e38\u306b\u5909\u66f4\u3055\u308c\u307e\u3057\u305f diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_pt_BR.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_pt_BR.properties index 3390349529a..7e48492d1e6 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_pt_BR.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_pt_BR.properties @@ -16,8 +16,6 @@ # under the License. username=Usu\u00e1rio password=Senha -submit=Alterar -Cancel=Cancelar confirmPassword=Senha (confirmar) passwordNeedsToBeUpdated=Senha precisa ser atualizado self.pwd.change.success=Senha mudada com sucesso diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_ru.properties b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_ru.properties index 6f199c603df..e3062e56a90 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_ru.properties +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/ChangePasswordPanel_ru.properties @@ -17,9 +17,6 @@ username=\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f # password=\u00d0\u009f\u00d0\u00b0\u00d1\u0080\u00d0\u00be\u00d0\u00bb\u00d1\u008c password=\u041f\u0430\u0440\u043e\u043b\u044c -# submit=\u00d0\u0098\u00d0\u00b7\u00d0\u00bc\u00d0\u00b5\u00d0\u00bd\u00d0\u00b8\u00d1\u0082\u00d1\u008c -submit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c -cancel=\u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c #confirmPassword=\u00d0\u009f\u00d0\u00b0\u00d1\u0080\u00d0\u00be\u00d0\u00bb\u00d1\u008c (\u00d0\u00bf\u00d0\u00be\u00d0\u00b4\u00d1\u0082\u00d0\u00b2\u00d0\u00b5\u00d1\u0080\u00d0\u00b6\u00d0\u00b4\u00d0\u00b5\u00d0\u00bd\u00d0\u00b8\u00d0\u00b5) confirmPassword=\u041f\u0430\u0440\u043e\u043b\u044c (\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435) # passwordNeedsToBeUpdated=\u00d0\u009f\u00d0\u00b0\u00d1\u0080\u00d0\u00be\u00d0\u00bb\u00d1\u008c \u00d0\u00b4\u00d0\u00be\u00d0\u00bb\u00d0\u00b6\u00d0\u00b5\u00d0\u00bd \u00d0\u00b1\u00d1\u008b\u00d1\u0082\u00d1\u008c \u00d0\u00b8\u00d0\u00b7\u00d0\u00bc\u00d0\u00b5\u00d0\u00bd\u00d1\u0091\u00d0\u00bd diff --git a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/Sidebar.html b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/Sidebar.html index 5aaf7de9654..aafa6fc1037 100644 --- a/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/Sidebar.html +++ b/client/idrepo/enduser/src/main/resources/org/apache/syncope/client/enduser/panels/Sidebar.html @@ -27,72 +27,82 @@ -