diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 2addc10811d..fbc74d27374 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -18,12 +18,10 @@ name: "CodeQL" on: push: - branches: [master,pr-*] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: analyze: @@ -45,26 +43,19 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v4.37.6 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -89,4 +80,4 @@ jobs: mvn -U -T 1C -PskipTests,all - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v4.37.6 diff --git a/.github/workflows/crosschecks.yml b/.github/workflows/crosschecks.yml index d382b4fbd5a..75f327687c1 100644 --- a/.github/workflows/crosschecks.yml +++ b/.github/workflows/crosschecks.yml @@ -18,12 +18,10 @@ name: "Cross Checks" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: crosschecks: @@ -33,27 +31,21 @@ jobs: fail-fast: false matrix: language: ['java'] - java: [ '21', '25-ea' ] + java: [ '21', '27-ea' ] os: [ubuntu-latest, windows-latest, macos-latest] steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: ${{ matrix.java }} - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: Validate @@ -64,7 +56,7 @@ jobs: - name: Start PostgreSQL on Windows if: runner.os == 'Windows' run: | - sc.exe config postgresql-x64-14 start=auto - sc.exe start postgresql-x64-14 + sc.exe config postgresql-x64-17 start=auto + sc.exe start postgresql-x64-17 - name: Verify run: mvn -f fit/core-reference/pom.xml verify '-Dit.test=RESTITCase' '-Dinvoker.streamLogs=true' '-Dmodernizer.skip=true' '-Drat.skip=true' '-Dcheckstyle.skip=true' '-Djacoco.skip=true' diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 5a10de05be0..18728688ce3 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -19,9 +19,7 @@ name: "Push to DockerHub" on: push: branches: - - master - tags: - - syncope-4.0.* + - 4_0_X jobs: push2DockerHub: @@ -55,22 +53,16 @@ jobs: - name: Disk space after run: df . -h - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all,docker' - name: 'Push to DockerHub' diff --git a/.github/workflows/fit_Elasticsearch.yml b/.github/workflows/fit_Elasticsearch.yml index b2f24b4e4e5..a05421eae00 100644 --- a/.github/workflows/fit_Elasticsearch.yml +++ b/.github/workflows/fit_Elasticsearch.yml @@ -18,12 +18,10 @@ name: "FIT Elasticsearch" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: fit_Elasticsearch: @@ -31,22 +29,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'Elasticsearch / PostgreSQL / JSON' diff --git a/.github/workflows/fit_OpenSearch.yml b/.github/workflows/fit_OpenSearch.yml index 25d5851d46e..4e0eec36620 100644 --- a/.github/workflows/fit_OpenSearch.yml +++ b/.github/workflows/fit_OpenSearch.yml @@ -18,12 +18,10 @@ name: "FIT OpenSearch" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: fit_OpenSearch: @@ -31,22 +29,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'zulu' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'OpenSearch / PostgreSQL / JSON' diff --git a/.github/workflows/fit_Payara.yml b/.github/workflows/fit_Payara.yml index 7b2d697106b..e61ceb1ed68 100644 --- a/.github/workflows/fit_Payara.yml +++ b/.github/workflows/fit_Payara.yml @@ -18,12 +18,10 @@ name: "FIT Payara" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: fit_Payara: @@ -31,22 +29,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'Payara / PostgreSQL / JSON' diff --git a/.github/workflows/fit_Tomcat_LiveSync.yml b/.github/workflows/fit_Tomcat_LiveSync.yml index 7481cae0ddc..3e1d6f61359 100644 --- a/.github/workflows/fit_Tomcat_LiveSync.yml +++ b/.github/workflows/fit_Tomcat_LiveSync.yml @@ -18,12 +18,10 @@ name: "FIT Tomcat LiveSync" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: fit_Tomcat_LiveSync: @@ -31,22 +29,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'Tomcat / PostgreSQL / Debezium' diff --git a/.github/workflows/fit_Tomcat_PostgreSQL_JSON.yml b/.github/workflows/fit_Tomcat_PostgreSQL_JSON.yml index 2d9a5b8bcbd..ed2f4aed112 100644 --- a/.github/workflows/fit_Tomcat_PostgreSQL_JSON.yml +++ b/.github/workflows/fit_Tomcat_PostgreSQL_JSON.yml @@ -18,12 +18,10 @@ name: "FIT Tomcat PostgreSQL JSON" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: fit_Tomcat_PostgreSQL_JSON: @@ -31,22 +29,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'Tomcat / PostgreSQL / JSON' diff --git a/.github/workflows/fit_Tomcat_PostgreSQL_XML.yml b/.github/workflows/fit_Tomcat_PostgreSQL_XML.yml index b3153d898c4..bf9cc65f255 100644 --- a/.github/workflows/fit_Tomcat_PostgreSQL_XML.yml +++ b/.github/workflows/fit_Tomcat_PostgreSQL_XML.yml @@ -18,12 +18,10 @@ name: "FIT Tomcat PostgreSQL XML" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: fit_Tomcat_PostgreSQL_XML: @@ -31,9 +29,9 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.0 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 @@ -41,12 +39,6 @@ jobs: uses: stCarolas/setup-maven@v5 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'Tomcat / PostgreSQL / XML' diff --git a/.github/workflows/fit_Tomcat_PostgreSQL_YAML.yml b/.github/workflows/fit_Tomcat_PostgreSQL_YAML.yml index ba19bdd2d0c..f77bc07fc4b 100644 --- a/.github/workflows/fit_Tomcat_PostgreSQL_YAML.yml +++ b/.github/workflows/fit_Tomcat_PostgreSQL_YAML.yml @@ -18,12 +18,10 @@ name: "FIT Tomcat PostgreSQL YAML" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: fit_Tomcat_PostgreSQL_YAML: @@ -31,9 +29,9 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.0 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 @@ -41,12 +39,6 @@ jobs: uses: stCarolas/setup-maven@v5 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'Tomcat / PostgreSQL / YAML' diff --git a/.github/workflows/fit_WA_OIDCC4UI.yml b/.github/workflows/fit_WA_OIDCC4UI.yml index fc045e60f44..f284bb596fe 100644 --- a/.github/workflows/fit_WA_OIDCC4UI.yml +++ b/.github/workflows/fit_WA_OIDCC4UI.yml @@ -18,12 +18,10 @@ name: "FIT WA OIDCC4UI" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: fit_WA_OIDCC4UI: @@ -31,22 +29,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'WA / OIDCC4UI' diff --git a/.github/workflows/fit_WA_OpenFGA.yml b/.github/workflows/fit_WA_OpenFGA.yml index 56680e70c06..a4d8c254288 100644 --- a/.github/workflows/fit_WA_OpenFGA.yml +++ b/.github/workflows/fit_WA_OpenFGA.yml @@ -18,12 +18,10 @@ name: "FIT WA OpenFGA" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: fit_WA_OpenFGA: @@ -31,22 +29,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'Unit Tests: OpenFGA' diff --git a/.github/workflows/fit_WA_SAML2SP4UI.yml b/.github/workflows/fit_WA_SAML2SP4UI.yml index 93881c49d34..ed5367aa755 100644 --- a/.github/workflows/fit_WA_SAML2SP4UI.yml +++ b/.github/workflows/fit_WA_SAML2SP4UI.yml @@ -18,12 +18,10 @@ name: "FIT WA SAML2SP4UI" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: fit_WA_SAML2SP4UI: @@ -31,22 +29,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'WA / SAML2SP4UI' diff --git a/.github/workflows/fit_WA_SRA_CASClient.yml b/.github/workflows/fit_WA_SRA_CASClient.yml index f32f124ff1d..7956c8f88c1 100644 --- a/.github/workflows/fit_WA_SRA_CASClient.yml +++ b/.github/workflows/fit_WA_SRA_CASClient.yml @@ -18,12 +18,10 @@ name: "FIT WA SRA CASClient" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: fit_WA_SRA_CASClient: @@ -31,22 +29,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'WA / SRA / CAS Client' diff --git a/.github/workflows/fit_WA_SRA_OAuth2.yml b/.github/workflows/fit_WA_SRA_OAuth2.yml index e016731bf4b..56cde3c5ee0 100644 --- a/.github/workflows/fit_WA_SRA_OAuth2.yml +++ b/.github/workflows/fit_WA_SRA_OAuth2.yml @@ -18,12 +18,10 @@ name: "FIT WA SRA OAuth2" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: fit_WA_SRA_OAuth2: @@ -31,22 +29,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'WA / SRA / OAuth 2.0' diff --git a/.github/workflows/fit_WA_SRA_OIDC.yml b/.github/workflows/fit_WA_SRA_OIDC.yml index 0360b68d726..367aa133109 100644 --- a/.github/workflows/fit_WA_SRA_OIDC.yml +++ b/.github/workflows/fit_WA_SRA_OIDC.yml @@ -18,12 +18,10 @@ name: "FIT WA SRA OIDC" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: fit_WA_SRA_OIDC: @@ -31,22 +29,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'WA / SRA / OpenID Connect 1.0' diff --git a/.github/workflows/fit_WA_SRA_SAML2.yml b/.github/workflows/fit_WA_SRA_SAML2.yml index b60f464740f..97e6db5d11f 100644 --- a/.github/workflows/fit_WA_SRA_SAML2.yml +++ b/.github/workflows/fit_WA_SRA_SAML2.yml @@ -18,12 +18,10 @@ name: "FIT WA SRA SAML2" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: fit_WA_SRA_SAML2: @@ -31,22 +29,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'WA / SRA / SAML 2.0' diff --git a/.github/workflows/fit_Wildfly.yml b/.github/workflows/fit_Wildfly.yml index 5e165174730..af2ed68f645 100644 --- a/.github/workflows/fit_Wildfly.yml +++ b/.github/workflows/fit_Wildfly.yml @@ -18,12 +18,10 @@ name: "FIT Wildfly" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: fit_Wildfly: @@ -31,22 +29,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'Wildfly / PostgreSQL / JSON' diff --git a/.github/workflows/fit_Zookeeper.yml b/.github/workflows/fit_Zookeeper.yml index c2ff40d05e9..f0ee747871f 100644 --- a/.github/workflows/fit_Zookeeper.yml +++ b/.github/workflows/fit_Zookeeper.yml @@ -18,12 +18,10 @@ name: "FIT Zookeeper" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: fit_Zookeeper: @@ -31,22 +29,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'Zookeeper / PostgreSQL / JSON' diff --git a/.github/workflows/mariadb.yml b/.github/workflows/mariadb.yml index 8c2e2b7b1ea..2047e3bfbc0 100644 --- a/.github/workflows/mariadb.yml +++ b/.github/workflows/mariadb.yml @@ -18,12 +18,10 @@ name: "MariaDB" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: mariadb: @@ -31,22 +29,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'Unit Tests: MariaDB' diff --git a/.github/workflows/mysql.yml b/.github/workflows/mysql.yml index 30997151f9b..b241f1de1ca 100644 --- a/.github/workflows/mysql.yml +++ b/.github/workflows/mysql.yml @@ -18,12 +18,10 @@ name: "MySQL" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: mysql: @@ -31,22 +29,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'Unit Tests: MySQL' diff --git a/.github/workflows/neo4j.yml b/.github/workflows/neo4j.yml index d698236c3fc..e07afe9cd91 100644 --- a/.github/workflows/neo4j.yml +++ b/.github/workflows/neo4j.yml @@ -18,12 +18,10 @@ name: "Neo4j" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: neo4j: @@ -31,22 +29,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'Unit Tests: Neo4j' diff --git a/.github/workflows/oracle.yml b/.github/workflows/oracle.yml index 128a47b4d51..ffeb2ff5d09 100644 --- a/.github/workflows/oracle.yml +++ b/.github/workflows/oracle.yml @@ -18,35 +18,29 @@ name: "Oracle" on: push: - branches: ['master', 'pr-*'] + branches: [4_0_X] pull_request: # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' + branches: [4_0_X] jobs: oracle: runs-on: ubuntu-latest steps: + - name: Free disk space + run: curl -fsSL https://raw.githubusercontent.com/kou/arrow/e49d8ae15583ceff03237571569099a6ad62be32/ci/scripts/util_free_space.sh | bash - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7.0.1 - name: Setup Java JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: 21 - name: Setup Maven - uses: stCarolas/setup-maven@v5 + uses: stCarolas/setup-maven@v5.1 with: maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - name: 'Unit Tests: Oracle' diff --git a/.mvn/extensions.xml b/.mvn/extensions.xml index 135a6d56a22..01a31424521 100644 --- a/.mvn/extensions.xml +++ b/.mvn/extensions.xml @@ -21,6 +21,6 @@ under the License. org.apache.maven.extensions maven-build-cache-extension - 1.2.0 + 1.2.3 diff --git a/CHANGES b/CHANGES index a7087493681..6bb9b3613c7 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,168 @@ Apache Syncope - CHANGES Licensed under Apache License 2.0 - http://www.apache.org/licenses/LICENSE-2.0 -------------------------------------------------------------------------------- +Release Notes - Syncope - Version 4.0.7 +================================================================================ + +** Bug + * [SYNCOPE-1970] - Scheduled task Groovy implementation not updated when running in cluster + * [SYNCOPE-1977] - Error after Macro compose + +** Improvement + * [SYNCOPE-1978] - Search in auditevent based on username + * [SYNCOPE-1981] - Search audit events by who (the principal that performed the operation) + * [SYNCOPE-1982] - Slow query on OraclePlainSchemaRepoExtImpl + * [SYNCOPE-1983] - Make approval required for user self-operations + +Release Notes - Syncope - Version 4.0.6 +================================================================================ + +** Bug + * [SYNCOPE-1744] - Empty value in template when notification is sent on DELETE event + * [SYNCOPE-1921] - LDAPMembershipPropagationActions deletes memberships of groups not managed by Syncope + * [SYNCOPE-1960] - Cannot remove aux class from user, group or any object + +** Improvement + * [SYNCOPE-1958] - Fail early on invalid password + +Release Notes - Syncope - Version 4.0.5 +================================================================================ + +** Bug + * [SYNCOPE-1945] - Tasks result not visible until the refresh is triggered + * [SYNCOPE-1956] - Dropdown multivalue PlainAttr not updated via Console + * [SYNCOPE-1957] - Wrong validation triggered while updating users, groups or any objects after auxiliary class change + +** Improvement + * [SYNCOPE-1949] - Allow to search AuthProfile owners + * [SYNCOPE-1950] - Allow configuration of OIDC Token Expiration Policy in WA + * [SYNCOPE-1951] - Searching Realms by attributes + * [SYNCOPE-1953] - Improve job stopping + +** Task + * [SYNCOPE-1947] - Job actuator + +Release Notes - Syncope - Version 4.0.4 +================================================================================ + +** Bug + * [SYNCOPE-1933] - Console: only first dynamic group is shown + * [SYNCOPE-1936] - WA: only SIGNATURE and CURRENT keys generated for OIDC + * [SYNCOPE-1937] - User password history length is not correctly trimmed + * [SYNCOPE-1942] - Menu localization doesn't work properly on admin console + * [SYNCOPE-1943] - French Canadian GUI failed with Groups contextual menu + * [SYNCOPE-1944] - Membership derived attributes are not computed from membership plain attributes + +** Improvement + * [SYNCOPE-1934] - Allow to select multiple AnyTypeClasses for Realm + +** Task + * [SYNCOPE-1946] - Console: access audit history for Realms + +Release Notes - Syncope - Version 4.0.3 +================================================================================ + +** Bug + * [SYNCOPE-1922] - Disallow searches by encrypted attribute + * [SYNCOPE-1924] - Bug in retainAll, removeAll, and removeIf methods of PropagationByResource + * [SYNCOPE-1925] - Contextual menu stays open after modal window is closed + * [SYNCOPE-1928] - Session timeout not working for Console + +** Improvement + * [SYNCOPE-1926] - Reduce number of update on Syncope after a SCIM PATCH + * [SYNCOPE-1927] - Macro Tasks: simplify binary form property binding + * [SYNCOPE-1929] - Console: allow to extend session duration + * [SYNCOPE-1930] - Exploit MariaDB with JSON + * [SYNCOPE-1931] - Allow for JEXL custom functions + * [SYNCOPE-1932] - Improve AES management + +** Task + * [SYNCOPE-1923] - Virtual Threads and JDK versions + +Release Notes - Syncope - Version 4.0.2 +================================================================================ + +** Bug + * [SYNCOPE-1905] - Error while pulling a specific group (single pull) from resource + * [SYNCOPE-1906] - Wrong result order if sorting by plain attribute + * [SYNCOPE-1910] - Tasks and Reports executed nevertheless inactive + * [SYNCOPE-1911] - Case sensisitve search failing with Elasticsearch or OpenSearch + * [SYNCOPE-1912] - Linked account password is not propagated on update + * [SYNCOPE-1913] - Missing dependency to resolve inline Groovy in Syncope WA + * [SYNCOPE-1915] - Failure when running the Persistence Storage Upgrader against Oracle DBMS + * [SYNCOPE-1919] - Notification Job occasionally stuck + * [SYNCOPE-1920] - Error in search panel while trying to add a condition after an attribute of type Long + +** New Feature + * [SYNCOPE-1916] - Metrics + +** Improvement + * [SYNCOPE-1907] - Run Groovy code in a sandbox + * [SYNCOPE-1908] - Improve Relationship management + * [SYNCOPE-1909] - Docker containers as unprivileged user + * [SYNCOPE-1914] - WA SAML 2.0: support IdP customization per Client Application + * [SYNCOPE-1917] - Manage bypassTrustedDeviceEnabled on Syncope WA + * [SYNCOPE-1918] - Push task with assign unmatching rule remove dynamic memberships + +Release Notes - Syncope - Version 4.0.1 +================================================================================ + +** Bug + * [SYNCOPE-1888] - Console: change required property for specific inputs in policy configuration + * [SYNCOPE-1890] - Configure max retry attempts for login with Syncope authentication module on WA + * [SYNCOPE-1891] - Missing mapped attribute setting for SAML2IdPAuthModuleConf + * [SYNCOPE-1894] - Mapping parsing error while schema contains a dot + * [SYNCOPE-1895] - Console CSV export does not consider search filter + * [SYNCOPE-1896] - Audit: not serializable exception for ConnectorObject and Any instances + * [SYNCOPE-1899] - Console: code editor does not persist changes + * [SYNCOPE-1902] - Can't set Unauthorized Redirect URL in access policy via Console + * [SYNCOPE-1904] - Console: cannot edit authentication.attributes under Keymaster > Parameters + +** Improvement + * [SYNCOPE-1886] - Elasticsearch and Opensearch query performance improvements + * [SYNCOPE-1887] - Enduser: require re-authentication for sensitive features + * [SYNCOPE-1889] - Improve group search using SCIM extension + * [SYNCOPE-1892] - Further Macro improvements + * [SYNCOPE-1893] - SCIM extension improvement + * [SYNCOPE-1897] - WA: mapping Google MFA crypto settings + * [SYNCOPE-1898] - Reset password with WA if mustChangePassword is true + * [SYNCOPE-1900] - Implement OIDC Back-Channel Logout for Console and Enduser + * [SYNCOPE-1903] - Add endpoint to verify the security answer during password reset in CAS + +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 ================================================================================ diff --git a/NOTICE b/NOTICE index 956e233e6e7..b3a136c86ef 100644 --- a/NOTICE +++ b/NOTICE @@ -1,5 +1,5 @@ Apache Syncope -Copyright 2012-2025 The Apache Software Foundation +Copyright 2012-2026 The Apache Software Foundation This product includes software developed by: The Apache Software Foundation (http://www.apache.org/). diff --git a/archetype/pom.xml b/archetype/pom.xml index 5ff22d221fa..dc42391e646 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.8-SNAPSHOT Apache Syncope Archetype @@ -34,7 +34,7 @@ under the License. maven-archetype - 3.3.1 + 3.4.1 ${basedir}/.. 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/fit/pom.xml b/archetype/src/main/resources/archetype-resources/fit/pom.xml index 42191e79e62..8c244ccf7a8 100644 --- a/archetype/src/main/resources/archetype-resources/fit/pom.xml +++ b/archetype/src/main/resources/archetype-resources/fit/pom.xml @@ -437,6 +437,13 @@ under the License. postgres + -Dfile.encoding=UTF-8 -server -Xms1536m -Xmx1536m + -XX:NewSize=256m -XX:MaxNewSize=256m -XX:+DisableExplicitGC + -Dsyncope.conf.dir=/opt/syncope/conf + -Dsyncope.connid.location=file:/opt/syncope/bundles + -Djava.security.egd=file:/dev/./urandom + -Djavax.net.ssl.trustStore=/opt/syncope/conf/keystore.p12 + -Djavax.net.ssl.trustStorePassword=password docker,postgresql,all jdbc:postgresql://postgres:5432/syncope?stringtype=unspecified syncope @@ -456,6 +463,7 @@ under the License. ${basedir}/../core/target/classes/domains/MasterContent.xml:/opt/syncope/conf/domains/MasterContent.xml:ro ${settings.localRepository}/${groupIdDocker}/syncope-core/${project.version}/syncope-core-${project.version}-classes.jar:/opt/syncope/lib/syncope-core-classes.jar:ro ${settings.localRepository}/${groupIdDocker}/syncope-common/${project.version}/syncope-common-${project.version}.jar:/opt/syncope/lib/syncope-common.jar:ro + ${basedir}/src/test/resources/keystore.p12:/opt/syncope/conf/keystore.p12:ro @@ -474,11 +482,6 @@ under the License. syncope - -Dfile.encoding=UTF-8 -server -Xms1536m -Xmx1536m - -XX:NewSize=256m -XX:MaxNewSize=256m -XX:+DisableExplicitGC - -Djava.security.egd=file:/dev/./urandom - -Djavax.net.ssl.trustStore=/opt/syncope/conf/keystore.p12 - -Djavax.net.ssl.trustStorePassword=password docker,all http://syncope-console:8080/syncope-console/ http://syncope:8080/syncope/rest/keymaster @@ -489,7 +492,6 @@ under the License. - ${basedir}/src/test/resources/keystore.p12:/opt/syncope/conf/keystore.p12:ro ${settings.localRepository}/${groupIdDocker}/syncope-console/${project.version}/syncope-console-${project.version}-classes.jar:/opt/syncope/lib/syncope-console-classes.jar:ro ${settings.localRepository}/${groupIdDocker}/syncope-common/${project.version}/syncope-common-${project.version}.jar:/opt/syncope/lib/syncope-common.jar:ro 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/archetype/src/main/resources/archetype-resources/wa/pom.xml b/archetype/src/main/resources/archetype-resources/wa/pom.xml index c2619707b5b..399525e8c38 100644 --- a/archetype/src/main/resources/archetype-resources/wa/pom.xml +++ b/archetype/src/main/resources/archetype-resources/wa/pom.xml @@ -38,6 +38,13 @@ under the License. + + org.springframework + spring-framework-bom + ${spring-framework.version} + pom + import + org.springframework.boot spring-boot-dependencies diff --git a/client/am/console/pom.xml b/client/am/console/pom.xml index e49b624ca3f..64369a6fc0b 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.8-SNAPSHOT Apache Syncope Client AM Console 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/authprofiles/AuthProfileDirectoryPanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfileDirectoryPanel.java index f6e02fe5802..be7597329ef 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,16 +19,18 @@ 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; import java.util.List; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Strings; import org.apache.syncope.client.console.SyncopeConsoleSession; import org.apache.syncope.client.console.authprofiles.AuthProfileDirectoryPanel.AuthProfileProvider; import org.apache.syncope.client.console.commons.AMConstants; import org.apache.syncope.client.console.commons.DirectoryDataProvider; +import org.apache.syncope.client.console.commons.KeywordSearchEvent; import org.apache.syncope.client.console.panels.DirectoryPanel; import org.apache.syncope.client.console.panels.ModalDirectoryPanel; import org.apache.syncope.client.console.rest.AuthProfileRestClient; @@ -39,7 +41,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 +51,13 @@ 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.event.IEvent; 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; @@ -67,6 +66,8 @@ public class AuthProfileDirectoryPanel private static final long serialVersionUID = 2018518567549153364L; + private String keyword; + private final BaseModal authProfileModal; public AuthProfileDirectoryPanel( @@ -85,15 +86,9 @@ protected void onConfigure() { } }; authProfileModal.size(Modal.Size.Large); - authProfileModal.setWindowClosedCallback(target -> { - updateResultTable(target); - authProfileModal.show(false); - }); + setWindowClosedReloadCallback(authProfileModal, true); addOuterObject(authProfileModal); - addNewItemPanelBuilder(new CreateAuthProfileWizardBuilder(pageRef), true); - MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, AMEntitlement.AUTH_PROFILE_CREATE); - disableCheckBoxes(); initResultTable(); } @@ -442,6 +437,25 @@ public void onClick(final AjaxRequestTarget target, final AuthProfileTO ignore) return panel; } + @Override + public void onEvent(final IEvent> event) { + if (event.getPayload() instanceof KeywordSearchEvent payload) { + keyword = payload.getKeyword(); + if (StringUtils.isNotBlank(keyword)) { + if (!Strings.CS.startsWith(keyword, "*")) { + keyword = "*" + keyword; + } + if (!Strings.CS.endsWith(keyword, "*")) { + keyword += "*"; + } + } + + updateResultTable(payload.getTarget()); + } else { + super.onEvent(event); + } + } + protected final class AuthProfileProvider extends DirectoryDataProvider { private static final long serialVersionUID = -185944053385660794L; @@ -454,12 +468,12 @@ private AuthProfileProvider(final int paginatorRows) { @Override public Iterator iterator(final long first, final long count) { int page = ((int) first / paginatorRows); - return restClient.list((page < 0 ? 0 : page) + 1, paginatorRows).iterator(); + return restClient.search(keyword, (page < 0 ? 0 : page) + 1, paginatorRows).iterator(); } @Override public long size() { - return restClient.count(); + return restClient.count(keyword); } @Override @@ -467,39 +481,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/AuthProfilePanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfilePanel.java new file mode 100644 index 00000000000..9c40fec62be --- /dev/null +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/authprofiles/AuthProfilePanel.java @@ -0,0 +1,69 @@ +/* + * 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.authprofiles; + +import org.apache.commons.lang3.StringUtils; +import org.apache.syncope.client.console.commons.KeywordSearchEvent; +import org.apache.syncope.client.console.rest.AuthProfileRestClient; +import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel; +import org.apache.wicket.PageReference; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.form.AjaxButton; +import org.apache.wicket.event.Broadcast; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.model.Model; + +public class AuthProfilePanel extends Panel { + + private static final long serialVersionUID = -4716856239434102405L; + + public AuthProfilePanel(final String id, + final AuthProfileRestClient authProfileRestClient, + final PageReference pageRef) { + super(id); + + Model keywordModel = new Model<>(StringUtils.EMPTY); + + WebMarkupContainer searchBoxContainer = new WebMarkupContainer("searchBox"); + add(searchBoxContainer); + + Form> form = new Form<>("form"); + searchBoxContainer.add(form); + + AjaxTextFieldPanel filter = new AjaxTextFieldPanel("filter", "filter", keywordModel, true); + form.add(filter.hideLabel().setOutputMarkupId(true).setRenderBodyOnly(true)); + + AjaxButton search = new AjaxButton("search") { + + private static final long serialVersionUID = 8390605330558248736L; + + @Override + protected void onSubmit(final AjaxRequestTarget target) { + send(AuthProfilePanel.this, Broadcast.DEPTH, new KeywordSearchEvent(target, keywordModel.getObject())); + } + }; + search.setOutputMarkupId(true); + form.add(search); + form.setDefaultButton(search); + + add(new AuthProfileDirectoryPanel("authProfiles", authProfileRestClient, pageRef).setOutputMarkupId(true)); + } +} 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/clientapps/ClientAppDirectoryPanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel.java index 87014925985..105b26fd4a8 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel.java @@ -97,10 +97,7 @@ public ClientAppDirectoryPanel( modal.addSubmitButton(); modal.size(Modal.Size.Large); - modal.setWindowClosedCallback(target -> { - updateResultTable(target); - modal.show(false); - }); + setWindowClosedReloadCallback(modal, true); setFooterVisibility(true); propertiesModal = new BaseModal<>(Constants.OUTER) { @@ -114,7 +111,7 @@ protected void onConfigure() { } }; propertiesModal.size(Modal.Size.Large); - propertiesModal.setWindowClosedCallback(target -> propertiesModal.show(false)); + setWindowClosedReloadCallback(propertiesModal); addOuterObject(propertiesModal); disableCheckBoxes(); @@ -231,8 +228,8 @@ protected void restore(final String json, final AjaxRequestTarget target) { historyModal.show(true); } - }, ActionLink.ActionType.VIEW_AUDIT_HISTORY, String.format("%s,%s", AMEntitlement.CLIENTAPP_READ, - IdRepoEntitlement.AUDIT_LIST)); + }, ActionLink.ActionType.VIEW_AUDIT_HISTORY, + "%s,%s".formatted(AMEntitlement.CLIENTAPP_READ, IdRepoEntitlement.AUDIT_LIST)); panel.add(new ActionLink<>() { 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..10044edcd27 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 @@ -27,6 +27,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.commons.lang3.RandomStringUtils; @@ -40,8 +41,6 @@ import org.apache.syncope.client.console.rest.RealmRestClient; import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal; import org.apache.syncope.client.console.wicket.markup.html.form.AjaxSearchFieldPanel; -import org.apache.syncope.client.console.wicket.markup.html.form.BinaryFieldPanel; -import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel; import org.apache.syncope.client.console.wicket.markup.html.form.PolicyRenderer; import org.apache.syncope.client.ui.commons.Constants; import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior; @@ -50,6 +49,8 @@ import org.apache.syncope.client.ui.commons.markup.html.form.AjaxNumberFieldPanel; 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.BinaryFieldPanel; +import org.apache.syncope.client.ui.commons.markup.html.form.MultiFieldPanel; import org.apache.syncope.client.ui.commons.pages.BaseWebPage; import org.apache.syncope.client.ui.commons.panels.WizardModalPanel; import org.apache.syncope.client.ui.commons.wizards.AbstractModalPanelBuilder; @@ -59,6 +60,7 @@ import org.apache.syncope.common.lib.to.ClientAppTO; import org.apache.syncope.common.lib.to.OIDCRPClientAppTO; import org.apache.syncope.common.lib.to.RealmTO; +import org.apache.syncope.common.lib.to.SAML2SPClientAppTO; import org.apache.syncope.common.lib.types.ClientAppType; import org.apache.syncope.common.lib.types.LogoutType; import org.apache.syncope.common.lib.types.OIDCApplicationType; @@ -72,6 +74,7 @@ import org.apache.syncope.common.lib.types.PolicyType; import org.apache.syncope.common.lib.types.SAML2SPNameId; import org.apache.syncope.common.lib.types.XmlSecAlgorithm; +import org.apache.syncope.common.rest.api.service.SAML2IdPEntityService; import org.apache.wicket.Component; import org.apache.wicket.PageReference; import org.apache.wicket.ajax.AjaxRequestTarget; @@ -193,7 +196,7 @@ private class Profile extends AbstractModalPanel { protected Iterator getChoices(final String input) { return realmRestClient.search(fullRealmsTree ? RealmsUtils.buildBaseQuery() - : RealmsUtils.buildKeywordQuery(input)).getResult().stream(). + : RealmsUtils.buildNameQuery(input)).getResult().stream(). map(RealmTO::getFullPath).iterator(); } }; @@ -301,7 +304,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); @@ -462,6 +465,38 @@ public void setObject(final String object) { false); tokenEndpointAuthenticationMethod.setChoices(List.of(OIDCClientAuthenticationMethod.values())); fields.add(tokenEndpointAuthenticationMethod); + + AjaxTextFieldPanel accessTokenMaxTimeToLive = new AjaxTextFieldPanel( + "field", "accessTokenMaxTimeToLive", + new PropertyModel<>(clientAppTO, "accessTokenMaxTimeToLive"), false); + fields.add(accessTokenMaxTimeToLive); + + AjaxTextFieldPanel accessTokenTimeToKill = new AjaxTextFieldPanel( + "field", "accessTokenTimeToKill", new PropertyModel<>(clientAppTO, "accessTokenTimeToKill"), + false); + fields.add(accessTokenTimeToKill); + + AjaxNumberFieldPanel accessTokenMaxActiveTokens = new AjaxNumberFieldPanel.Builder() + .enableOnChange() + .build("field", "accessTokenMaxActiveTokens", Long.class, + new PropertyModel<>(clientAppTO, "accessTokenMaxActiveTokens")); + fields.add(accessTokenMaxActiveTokens); + + AjaxTextFieldPanel refreshTokenTimeToKill = new AjaxTextFieldPanel( + "field", "refreshTokenTimeToKill", + new PropertyModel<>(clientAppTO, "refreshTokenTimeToKill"), false); + fields.add(refreshTokenTimeToKill); + + AjaxNumberFieldPanel refreshTokenMaxActiveTokens = new AjaxNumberFieldPanel.Builder() + .enableOnChange() + .build("field", "refreshTokenMaxActiveTokens", Long.class, + new PropertyModel<>(clientAppTO, "refreshTokenMaxActiveTokens")); + fields.add(refreshTokenMaxActiveTokens); + + AjaxTextFieldPanel deviceTokenTimeToKill = new AjaxTextFieldPanel( + "field", "deviceTokenTimeToKill", new PropertyModel<>(clientAppTO, "deviceTokenTimeToKill"), + false); + fields.add(deviceTokenTimeToKill); break; case SAML2SP: @@ -469,6 +504,17 @@ public void setObject(final String object) { "field", "entityId", new PropertyModel<>(clientAppTO, "entityId"), false); fields.add(entityId.setRequired(true)); + fields.add(new AjaxTextFieldPanel("field", "idp", new PropertyModel<>(clientAppTO, "idp") { + + private static final long serialVersionUID = -1476737401674143862L; + + @Override + public String getObject() { + return Optional.ofNullable(((SAML2SPClientAppTO) clientAppTO).getIdp()). + orElse(SAML2IdPEntityService.DEFAULT_OWNER); + } + }, false)); + fields.add(new AjaxTextFieldPanel("field", "metadataLocation", new PropertyModel<>(clientAppTO, "metadataLocation"), false).setRequired(true)); 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/SRA.java b/client/am/console/src/main/java/org/apache/syncope/client/console/pages/SRA.java index 43bf65ab19a..3904aff8f78 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; @@ -82,12 +82,9 @@ public void onClick(final AjaxRequestTarget target) { body.add(push); WebMarkupContainer content = new WebMarkupContainer("content"); - content.setOutputMarkupId(true); - AjaxBootstrapTabbedPanel tabbedPanel = - new AjaxBootstrapTabbedPanel<>("tabbedPanel", buildTabList(instances)); - content.add(tabbedPanel); + body.add(content.setOutputMarkupId(true)); - body.add(content); + content.add(new AjaxBootstrapTabbedPanel<>("tabbedPanel", buildTabList(instances))); } private List buildTabList(final List instances) { 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..9f7f0e4fb67 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 @@ -29,26 +29,29 @@ import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Strings; 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.authprofiles.AuthProfilePanel; import org.apache.syncope.client.console.clientapps.ClientApps; import org.apache.syncope.client.console.panels.AMSessionPanel; 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.ClientAppRestClient; +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; 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; @@ -82,6 +85,12 @@ public class WA extends BasePage { @SpringBean protected AttrRepoRestClient attrRepoRestClient; + @SpringBean + protected SAML2IdPEntityRestClient saml2IdPEntityRestClient; + + @SpringBean + protected ClientAppRestClient clientAppRestClient; + @SpringBean protected ServiceOps serviceOps; @@ -118,16 +127,13 @@ public void onClick(final AjaxRequestTarget target) { body.add(push); WebMarkupContainer content = new WebMarkupContainer("content"); - content.setOutputMarkupId(true); - AjaxBootstrapTabbedPanel tabbedPanel = - new AjaxBootstrapTabbedPanel<>("tabbedPanel", buildTabList(instances)); - content.add(tabbedPanel); + body.add(content.setOutputMarkupId(true)); - body.add(content); + content.add(new AjaxBootstrapTabbedPanel<>("tabbedPanel", buildTabList(instances))); if (!instances.isEmpty()) { - String actuatorEndpoint = StringUtils.appendIfMissing( - instances.getFirst().getAddress(), "/") + "actuator/env"; + String actuatorEndpoint = Strings.CS.appendIfMissing( + instances.getFirst().getAddress(), "/") + "actuator/env"; try { Response response = WebClientBuilder.build(actuatorEndpoint, SyncopeWebApplication.get().getAnonymousUser(), @@ -142,7 +148,7 @@ public void onClick(final AjaxRequestTarget target) { if (properties.has("cas.server.prefix")) { JsonNode prefix = properties.get("cas.server.prefix"); if (prefix.has("value")) { - waPrefix = StringUtils.removeEnd(prefix.get("value").asText(), "/"); + waPrefix = Strings.CS.removeEnd(prefix.get("value").asText(), "/"); } } } @@ -154,7 +160,7 @@ public void onClick(final AjaxRequestTarget target) { } if (StringUtils.isBlank(waPrefix)) { - waPrefix = StringUtils.removeEnd(instances.getFirst().getAddress(), "/"); + waPrefix = Strings.CS.removeEnd(instances.getFirst().getAddress(), "/"); } } } @@ -204,7 +210,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, clientAppRestClient, waPrefix, getPageReference()); } }); @@ -237,7 +244,7 @@ public Panel getPanel(final String panelId) { @Override public Panel getPanel(final String panelId) { - return new AuthProfileDirectoryPanel(panelId, authProfileRestClient, getPageReference()); + return new AuthProfilePanel(panelId, authProfileRestClient, getPageReference()); } }); } diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/panels/AMSessionDirectoryPanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/AMSessionDirectoryPanel.java index 9db0f0b7136..88d118df6a8 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/panels/AMSessionDirectoryPanel.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/AMSessionDirectoryPanel.java @@ -92,7 +92,7 @@ protected void onConfigure() { } }; viewModal.size(Modal.Size.Extra_large); - viewModal.setWindowClosedCallback(target -> viewModal.show(false)); + setWindowClosedReloadCallback(viewModal); addOuterObject(viewModal); initResultTable(); @@ -123,7 +123,7 @@ protected ActionsPanel getActions(final IModel model) { public void onClick(final AjaxRequestTarget target, final AMSession ignore) { viewModal.header(new ResourceModel("details")); target.add(viewModal.setContent( - new JsonEditorPanel(viewModal, Model.of(model.getObject().getJson()), true, pageRef))); + new JsonEditorPanel(viewModal, Model.of(model.getObject().getJson()), true, pageRef))); viewModal.show(true); } }, ActionLink.ActionType.VIEW, listEntitlement); @@ -167,8 +167,7 @@ protected String paginatorRowsKey() { @Override public void onEvent(final IEvent> event) { - if (event.getPayload() instanceof AMSessionSearchEvent) { - AMSessionSearchEvent payload = AMSessionSearchEvent.class.cast(event.getPayload()); + if (event.getPayload() instanceof AMSessionSearchEvent payload) { keyword = payload.getKeyword(); updateResultTable(payload.getTarget()); diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/panels/AttrRepoDirectoryPanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/AttrRepoDirectoryPanel.java index 63bd50d47ea..a251eb8383a 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/panels/AttrRepoDirectoryPanel.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/AttrRepoDirectoryPanel.java @@ -183,8 +183,8 @@ protected void restore(final String json, final AjaxRequestTarget target) { historyModal.show(true); } - }, ActionLink.ActionType.VIEW_AUDIT_HISTORY, String.format("%s,%s", AMEntitlement.ATTR_REPO_READ, - IdRepoEntitlement.AUDIT_LIST)); + }, ActionLink.ActionType.VIEW_AUDIT_HISTORY, + "%s,%s".formatted(AMEntitlement.ATTR_REPO_READ, IdRepoEntitlement.AUDIT_LIST)); panel.add(new ActionLink<>() { diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/panels/AuthModuleDirectoryPanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/AuthModuleDirectoryPanel.java index 70d25d0b95b..e6934448879 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/panels/AuthModuleDirectoryPanel.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/AuthModuleDirectoryPanel.java @@ -187,8 +187,8 @@ protected void restore(final String json, final AjaxRequestTarget target) { historyModal.show(true); } - }, ActionLink.ActionType.VIEW_AUDIT_HISTORY, String.format("%s,%s", AMEntitlement.AUTH_MODULE_READ, - IdRepoEntitlement.AUDIT_LIST)); + }, ActionLink.ActionType.VIEW_AUDIT_HISTORY, + "%s,%s".formatted(AMEntitlement.AUTH_MODULE_READ, IdRepoEntitlement.AUDIT_LIST)); panel.add(new ActionLink<>() { 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..b71c26bf7a5 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,9 +21,11 @@ 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.rest.WAConfigRestClient; import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal; import org.apache.syncope.client.console.wicket.markup.html.form.JsonEditorPanel; import org.apache.syncope.client.ui.commons.Constants; @@ -54,6 +56,11 @@ public class OIDC extends Panel { @SpringBean protected OIDCJWKSRestClient oidcJWKSRestClient; + @SpringBean + protected WAConfigRestClient waConfigRestClient; + + protected final BaseModal generateModal = new BaseModal<>("generateModal"); + protected final BaseModal viewModal = new BaseModal<>("viewModal") { private static final long serialVersionUID = 389935548143327858L; @@ -75,14 +82,14 @@ public OIDC(final String id, final String waPrefix, final PageReference pageRef) super(id); setOutputMarkupId(true); - add(viewModal); - viewModal.size(Modal.Size.Extra_large); - viewModal.setWindowClosedCallback(target -> viewModal.show(false)); - WebMarkupContainer container = new WebMarkupContainer("container"); add(container.setOutputMarkupId(true)); - AtomicReference oidcjwksto = oidcJWKSRestClient.get(); + Mutable oidcjwksto = oidcJWKSRestClient.get(); + + add(viewModal); + viewModal.size(Modal.Size.Extra_large); + viewModal.setWindowClosedCallback(target -> viewModal.show(false)); view = new AjaxLink<>("view") { @@ -96,7 +103,7 @@ public void onClick(final AjaxRequestTarget target) { writeValueAsString(MAPPER.readTree(oidcjwksto.get().getJson())); } catch (IOException e) { LOG.error("Could not pretty-print", e); - pretty = oidcjwksto.get().getJson(); + pretty = Optional.ofNullable(oidcjwksto.get()).map(OIDCJWKSTO::getJson).orElse(null); } viewModal.header(Model.of("JSON Web Key Sets")); @@ -123,18 +130,10 @@ protected void onComponentTag(final ComponentTag tag) { @Override public void onClick(final AjaxRequestTarget target) { - try { - oidcjwksto.set(oidcJWKSRestClient.generate()); - generate.setEnabled(false); - view.setEnabled(true); - - SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED)); - target.add(container); - } catch (Exception e) { - LOG.error("While generating OIDC JWKS", e); - SyncopeConsoleSession.get().onException(e); - } - ((BaseWebPage) pageRef.getPage()).getNotificationPanel().refresh(target); + generateModal.header(Model.of("Generate JSON Web Key Sets")); + target.add(generateModal.setContent(new OIDCJWKSGenerationPanel( + oidcJWKSRestClient, waConfigRestClient, generateModal, pageRef))); + generateModal.show(true); } @Override @@ -158,7 +157,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); @@ -184,6 +183,17 @@ protected void onComponentTag(final ComponentTag tag) { container.add(delete.setOutputMarkupId(true)); MetaDataRoleAuthorizationStrategy.authorize(delete, ENABLE, AMEntitlement.OIDC_JWKS_DELETE); + generateModal.addSubmitButton(); + add(generateModal); + generateModal.setWindowClosedCallback(target -> { + oidcjwksto.setValue(oidcJWKSRestClient.get().get()); + view.setEnabled(oidcjwksto.get() != null); + delete.setEnabled(oidcjwksto.get() != null); + + target.add(container); + generateModal.show(false); + }); + String wellKnownURI = waPrefix + "/oidc/.well-known/openid-configuration"; container.add(new ExternalLink("wellKnownURI", wellKnownURI, wellKnownURI)); } diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/panels/OIDCJWKSGenerationPanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/OIDCJWKSGenerationPanel.java new file mode 100644 index 00000000000..d5d18f96eb2 --- /dev/null +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/OIDCJWKSGenerationPanel.java @@ -0,0 +1,117 @@ +/* + * 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.List; +import org.apache.syncope.client.console.SyncopeConsoleSession; +import org.apache.syncope.client.console.rest.OIDCJWKSRestClient; +import org.apache.syncope.client.console.rest.WAConfigRestClient; +import org.apache.syncope.client.console.wicket.ajax.form.IndicatorAjaxEventBehavior; +import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal; +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.AjaxNumberFieldPanel; +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.SyncopeClientException; +import org.apache.syncope.common.lib.to.OIDCJWKSTO; +import org.apache.wicket.PageReference; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.model.Model; + +public class OIDCJWKSGenerationPanel extends AbstractModalPanel { + + private static final long serialVersionUID = -3372006007594607067L; + + protected final OIDCJWKSRestClient oidcJWKSRestClient; + + protected final Model jwksKeyIdM; + + protected final Model jwksTypeM; + + protected final Model jwksKeySizeM; + + public OIDCJWKSGenerationPanel( + final OIDCJWKSRestClient oidcJWKSRestClient, + final WAConfigRestClient waConfigRestClient, + final BaseModal modal, + final PageReference pageRef) { + + super(modal, pageRef); + this.oidcJWKSRestClient = oidcJWKSRestClient; + + jwksKeyIdM = Model.of("syncope"); + try { + jwksKeyIdM.setObject(waConfigRestClient.get("cas.authn.oidc.jwks.core.jwks-key-id").getValues().getFirst()); + } catch (SyncopeClientException e) { + LOG.error("While reading cas.authn.oidc.jwks.core.jwks-key-id", e); + } + add(new AjaxTextFieldPanel("jwksKeyId", "jwksKeyId", jwksKeyIdM).setRequired(true)); + + jwksTypeM = Model.of("rsa"); + try { + jwksTypeM.setObject(waConfigRestClient.get("cas.authn.oidc.jwks.core.jwks-type").getValues().getFirst()); + } catch (SyncopeClientException e) { + LOG.error("While reading cas.authn.oidc.jwks.core.jwks-type", e); + } + AjaxDropDownChoicePanel jwksType = new AjaxDropDownChoicePanel<>("jwksType", "jwksType", jwksTypeM). + setChoices(List.of("rsa", "ec")); + add(jwksType.setRequired(true)); + + jwksKeySizeM = Model.of(2048); + try { + jwksKeySizeM.setObject(Integer.valueOf( + waConfigRestClient.get("cas.authn.oidc.jwks.core.jwks-key-size").getValues().getFirst())); + } catch (SyncopeClientException e) { + LOG.error("While reading cas.authn.oidc.jwks.core.jwks-key-size", e); + } + AjaxNumberFieldPanel jwksKeySize = new AjaxNumberFieldPanel.Builder().step(128). + build("jwksKeySize", "jwksKeySize", Integer.class, jwksKeySizeM); + add(jwksKeySize.setRequired(true)); + + jwksType.add(new IndicatorAjaxEventBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -4255753643957306394L; + + @Override + protected void onEvent(final AjaxRequestTarget target) { + if ("ec".equals(jwksTypeM.getObject())) { + jwksKeySizeM.setObject(256); + } else { + jwksKeySizeM.setObject(2048); + } + target.add(jwksKeySize); + } + }); + } + + @Override + public void onSubmit(final AjaxRequestTarget target) { + try { + oidcJWKSRestClient.generate(jwksKeyIdM.getObject(), jwksTypeM.getObject(), jwksKeySizeM.getObject()); + + SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED)); + modal.close(target); + } catch (Exception e) { + LOG.error("While generating OIDC JWKS", e); + SyncopeConsoleSession.get().onException(e); + } + ((BaseWebPage) pageRef.getPage()).getNotificationPanel().refresh(target); + } +} 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/SAML2IdPEntityDirectoryPanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPEntityDirectoryPanel.java index 2ec1e9ea21c..279fa58bb04 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPEntityDirectoryPanel.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPEntityDirectoryPanel.java @@ -23,18 +23,25 @@ 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.pages.BasePage; import org.apache.syncope.client.console.panels.SAML2IdPEntityDirectoryPanel.SAML2IdPEntityProvider; +import org.apache.syncope.client.console.rest.ClientAppRestClient; import org.apache.syncope.client.console.rest.SAML2IdPEntityRestClient; 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.SAML2IdPEntityWizardBuilder; import org.apache.syncope.client.ui.commons.Constants; import org.apache.syncope.client.ui.commons.wizards.AjaxWizard; +import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.to.SAML2IdPEntityTO; +import org.apache.syncope.common.lib.to.SAML2SPClientAppTO; import org.apache.syncope.common.lib.types.AMEntitlement; +import org.apache.syncope.common.lib.types.ClientAppType; +import org.apache.syncope.common.rest.api.service.SAML2IdPEntityService; import org.apache.wicket.PageReference; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.event.Broadcast; @@ -43,10 +50,12 @@ 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.basic.Label; 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.LoadableDetachableModel; import org.apache.wicket.model.Model; import org.apache.wicket.model.StringResourceModel; @@ -55,26 +64,54 @@ public class SAML2IdPEntityDirectoryPanel extends DirectoryPanel< private static final long serialVersionUID = -6535332920023200166L; + private static ExternalLink metadataLink(final String componentId, final String url) { + return new ExternalLink(componentId, Model.of(url), Model.of(url)) { + + private static final long serialVersionUID = -1919646533527005367L; + + @Override + protected void onComponentTag(final ComponentTag tag) { + super.onComponentTag(tag); + + tag.setName("a"); + if (url.startsWith("http")) { + tag.put("href", getDefaultModelObject().toString()); + tag.put("target", "_blank"); + } + } + }; + } + + private final LoadableDetachableModel> clientApps; + private final String metadataURL; public SAML2IdPEntityDirectoryPanel( final String id, final SAML2IdPEntityRestClient restClient, + final ClientAppRestClient clientAppRestClient, final String waPrefix, final PageReference pageRef) { super(id, restClient, pageRef); + + clientApps = new LoadableDetachableModel<>() { + + private static final long serialVersionUID = 7172461137064525667L; + + @Override + protected List load() { + return clientAppRestClient.list(ClientAppType.SAML2SP); + } + }; + this.metadataURL = waPrefix + "/idp/metadata"; disableCheckBoxes(); modal.size(Modal.Size.Large); modal.addSubmitButton(); - - modal.setWindowClosedCallback(target -> { - updateResultTable(target); - modal.show(false); - }); + setWindowClosedReloadCallback(modal, true); addNewItemPanelBuilder(new SAML2IdPEntityWizardBuilder(new SAML2IdPEntityTO(), restClient, pageRef), false); @@ -98,24 +135,16 @@ public void populateItem( final String componentId, final IModel rowModel) { - 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"); - } - } - }); + if (SAML2IdPEntityService.DEFAULT_OWNER.equals(rowModel.getObject().getKey())) { + cellItem.add(metadataLink(componentId, metadataURL)); + } else { + clientApps.getObject().stream(). + filter(app -> rowModel.getObject().getKey().equals(app.getIdp())). + findFirst().ifPresentOrElse( + app -> cellItem.add(metadataLink( + componentId, metadataURL + "?service=" + app.getClientAppId())), + () -> cellItem.add(new Label(componentId, Model.of()))); + } } }); @@ -138,6 +167,26 @@ public void onClick(final AjaxRequestTarget target, final SAML2IdPEntityTO ignor } }, ActionLink.ActionType.EDIT, AMEntitlement.SAML2_IDP_ENTITY_SET); + if (!SAML2IdPEntityService.DEFAULT_OWNER.equals(model.getObject().getKey())) { + panel.add(new ActionLink<>() { + + private static final long serialVersionUID = -3722207913631435501L; + + @Override + public void onClick(final AjaxRequestTarget target, final SAML2IdPEntityTO ignore) { + try { + restClient.delete(model.getObject().getKey()); + SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED)); + target.add(container); + } catch (SyncopeClientException e) { + LOG.error("While deleting IdP {}", model.getObject().getKey(), e); + SyncopeConsoleSession.get().onException(e); + } + ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target); + } + }, ActionLink.ActionType.DELETE, AMEntitlement.SAML2_IDP_ENTITY_DELETE, true); + } + return panel; } 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 extends SAML2SPEntityTO> 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/panels/SRARouteDirectoryPanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/SRARouteDirectoryPanel.java index a116ccf53fc..280026d2e8f 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/panels/SRARouteDirectoryPanel.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/SRARouteDirectoryPanel.java @@ -61,13 +61,10 @@ public SRARouteDirectoryPanel(final String id, final SRARouteRestClient restClie modal.size(Modal.Size.Large); modal.addSubmitButton(); - - modal.setWindowClosedCallback(target -> { - updateResultTable(target); - modal.show(false); - }); + setWindowClosedReloadCallback(modal, true); addNewItemPanelBuilder(new SRARouteWizardBuilder(new SRARouteTO(), restClient, pageRef), true); + initResultTable(); } diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/panels/WAConfigDirectoryPanel.java b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/WAConfigDirectoryPanel.java index 36c160f67b5..bd008fdf79a 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/panels/WAConfigDirectoryPanel.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/panels/WAConfigDirectoryPanel.java @@ -78,7 +78,11 @@ public ActionsPanel getActions(final IModel model) { public void onClick(final AjaxRequestTarget target, final Attr ignore) { target.add(modal); modal.header(new StringResourceModel("any.edit")); - modal.setContent(new WAConfigModalPanel(modal, model.getObject(), AjaxWizard.Mode.EDIT, pageRef)); + modal.setContent(new WAConfigModalPanel( + modal, + ((WAConfigRestClient) restClient).get(model.getObject().getSchema()), + AjaxWizard.Mode.EDIT, + pageRef)); modal.show(true); } }, ActionLink.ActionType.EDIT, AMEntitlement.WA_CONFIG_SET); 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..ca413343d8f 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 @@ -26,7 +26,6 @@ import org.apache.syncope.client.console.rest.AttrRepoRestClient; import org.apache.syncope.client.console.rest.PolicyRestClient; import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal; -import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel; import org.apache.syncope.client.ui.commons.Constants; import org.apache.syncope.client.ui.commons.markup.html.form.AjaxCheckBoxPanel; import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel; @@ -34,6 +33,7 @@ import org.apache.syncope.client.ui.commons.markup.html.form.AjaxNumberFieldPanel; 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.MultiFieldPanel; import org.apache.syncope.client.ui.commons.pages.BaseWebPage; import org.apache.syncope.common.lib.policy.AttrReleasePolicyTO; import org.apache.syncope.common.lib.policy.DefaultAttrReleasePolicyConf.PrincipalAttrRepoMergingStrategy; @@ -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/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..e4edc93d09e 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", @@ -98,6 +104,12 @@ public AuthPolicyModalPanel( "bypassPrincipalAttributeValue", new PropertyModel<>(model.getObject().getConf(), "bypassPrincipalAttributeValue"), false)); + + add(new AjaxCheckBoxPanel( + "bypassTrustedDeviceEnabled", + "bypassTrustedDeviceEnabled", + new PropertyModel<>(model.getObject().getConf(), "bypassTrustedDeviceEnabled"), + false)); } @Override 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..99f8cb18ce8 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 @@ -20,28 +20,29 @@ import java.util.List; import org.apache.syncope.common.lib.to.AuthProfileTO; +import org.apache.syncope.common.rest.api.beans.AuthProfileQuery; import org.apache.syncope.common.rest.api.service.AuthProfileService; public class AuthProfileRestClient extends BaseRestClient { private static final long serialVersionUID = -7379778542101161274L; - public long count() { - return getService(AuthProfileService.class).list(1, 1).getTotalCount(); + public long count(final String keyword) { + return getService(AuthProfileService.class). + search(new AuthProfileQuery.Builder().page(1).size(0).keyword(keyword).build()). + getTotalCount(); } - public List list(final int page, final int size) { - return getService(AuthProfileService.class).list(page, size).getResult(); + public List search(final String keyword, final int page, final int size) { + return getService(AuthProfileService.class). + search(new AuthProfileQuery.Builder().page(page).size(size).keyword(keyword).build()). + getResult(); } 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/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..70a94e40309 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,18 +28,18 @@ 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); } return result; } - public OIDCJWKSTO generate() { - Response response = getService(OIDCJWKSService.class).generate("syncope", "RSA", 2048); + public OIDCJWKSTO generate(final String jwksKeyId, final String jwksType, final int jwksKeySize) { + Response response = getService(OIDCJWKSService.class).generate(jwksKeyId, jwksType, jwksKeySize); return response.readEntity(OIDCJWKSTO.class); } diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/rest/SAML2IdPEntityRestClient.java b/client/am/console/src/main/java/org/apache/syncope/client/console/rest/SAML2IdPEntityRestClient.java index 9c66b1e7844..26b7a13c364 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/rest/SAML2IdPEntityRestClient.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/rest/SAML2IdPEntityRestClient.java @@ -38,4 +38,8 @@ public SAML2IdPEntityTO get(final String key) { public void set(final SAML2IdPEntityTO entityTO) { getService(SAML2IdPEntityService.class).set(entityTO); } + + public void delete(final String key) { + getService(SAML2IdPEntityService.class).delete(key); + } } 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/rest/SRAStatisticsRestClient.java b/client/am/console/src/main/java/org/apache/syncope/client/console/rest/SRAStatisticsRestClient.java index e313d0c022f..3aeabe26818 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/rest/SRAStatisticsRestClient.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/rest/SRAStatisticsRestClient.java @@ -50,7 +50,7 @@ public SRAStatistics get(final List instances, final List s.getKey() + ":" + s.getValue()).toArray()); + client.query("tag", selected.stream().map(s -> s.getLeft() + ":" + s.getRight()).toArray()); } Response response = client.get(); diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/rest/WAConfigRestClient.java b/client/am/console/src/main/java/org/apache/syncope/client/console/rest/WAConfigRestClient.java index c803821bfce..4dce2e8b33e 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/rest/WAConfigRestClient.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/rest/WAConfigRestClient.java @@ -30,6 +30,10 @@ public List list() { return getService(WAConfigService.class).list(); } + public Attr get(final String schema) { + return getService(WAConfigService.class).get(schema); + } + public void set(final Attr value) { getService(WAConfigService.class).set(value); } 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..92677033f03 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,12 +19,15 @@ 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; 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.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; @@ -32,10 +35,12 @@ import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel; 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.markup.html.form.BinaryFieldPanel; import org.apache.syncope.client.ui.commons.wizards.AjaxWizard; 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 +97,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 +176,69 @@ 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 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 + 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/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails.html b/client/am/console/src/main/resources/org/apache/syncope/client/console/authprofiles/AuthProfilePanel.html similarity index 63% rename from client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails.html rename to client/am/console/src/main/resources/org/apache/syncope/client/console/authprofiles/AuthProfilePanel.html index b5d83e86fef..8d2a5af99eb 100644 --- a/client/idm/console/src/main/resources/org/apache/syncope/client/console/panels/VirSchemaDetails.html +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/authprofiles/AuthProfilePanel.html @@ -18,22 +18,19 @@ --> - - - [name] - - - [readonly] - - - [resource] - - - [anyType] - - - [extAttrName] - + + + + [FILTER] + + + + + + + + + diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel.properties index 229c25a2629..e3ba1847eb2 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel.properties @@ -81,3 +81,4 @@ userInfoSigningAlg=UserInfo Signing Algorithm userInfoEncryptedResponseAlg=UserInfo Encrypted Response Algorithm userInfoEncryptedResponseEncoding=UserInfo Encrypted Response Encoding evaluationOrder=Evaluation Order +idp=Identity Provider diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_fr_CA.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_fr_CA.properties index b8f5fc87984..2bb0a441b38 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_fr_CA.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_fr_CA.properties @@ -81,3 +81,4 @@ userInfoSigningAlg=UserInfo Signing Algorithm userInfoEncryptedResponseAlg=UserInfo Encrypted Response Algorithm userInfoEncryptedResponseEncoding=UserInfo Encrypted Response Encoding evaluationOrder=Evaluation Order +idp=Identity Provider diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_it.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_it.properties index 90bfaf968a8..2ad1b0f69bd 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_it.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_it.properties @@ -81,3 +81,4 @@ userInfoSigningAlg=Algoritmo di firma UserInfo userInfoEncryptedResponseAlg=Algoritmo di cifratura risposta UserInfo userInfoEncryptedResponseEncoding=Codifica di cifratura risposta UserInfo evaluationOrder=Ordine di valutazione +idp=Identity Provider diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_ja.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_ja.properties index 428c4dce872..d0868ef9f22 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_ja.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_ja.properties @@ -81,3 +81,4 @@ userInfoSigningAlg=UserInfo Signing Algorithm userInfoEncryptedResponseAlg=UserInfo Encrypted Response Algorithm userInfoEncryptedResponseEncoding=UserInfo Encrypted Response Encoding evaluationOrder=Evaluation Order +idp=Identity Provider diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_pt_BR.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_pt_BR.properties index 54383631234..1bd4e93e86b 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_pt_BR.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_pt_BR.properties @@ -81,3 +81,4 @@ userInfoSigningAlg=UserInfo Signing Algorithm userInfoEncryptedResponseAlg=UserInfo Encrypted Response Algorithm userInfoEncryptedResponseEncoding=UserInfo Encrypted Response Encoding evaluationOrder=Evaluation Order +idp=Identity Provider diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_ru.properties b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_ru.properties index 09307c88255..bc0ab53d9db 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_ru.properties +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/clientapps/ClientAppDirectoryPanel_ru.properties @@ -82,3 +82,4 @@ userInfoSigningAlg=UserInfo Signing Algorithm userInfoEncryptedResponseAlg=UserInfo Encrypted Response Algorithm userInfoEncryptedResponseEncoding=UserInfo Encrypted Response Encoding evaluationOrder=Evaluation Order +idp=Identity Provider diff --git a/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/OIDC.html b/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/OIDC.html index 8a4de0f0453..f67ee751dcf 100644 --- a/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/OIDC.html +++ b/client/am/console/src/main/resources/org/apache/syncope/client/console/panels/OIDC.html @@ -49,6 +49,7 @@ Well-Known URI +