From f1511ef652354f4b4b435c6243b939ae528820dd Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Mon, 16 Sep 2024 20:13:14 +0200 Subject: [PATCH 01/12] Revise build (#999) * chore(deps): bump golang.org/x/net Bumps the go_modules group with 1 update in the / directory: [golang.org/x/net](https://github.com/golang/net). Updates `golang.org/x/net` from 0.17.0 to 0.23.0 - [Commits](https://github.com/golang/net/compare/v0.17.0...v0.23.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production dependency-group: go_modules ... Signed-off-by: dependabot[bot] * Updated CodeQL and GoReleaser versions * chore(deps): bump github.com/hashicorp/go-retryablehttp Bumps the go_modules group with 1 update in the / directory: [github.com/hashicorp/go-retryablehttp](https://github.com/hashicorp/go-retryablehttp). Updates `github.com/hashicorp/go-retryablehttp` from 0.7.1 to 0.7.7 - [Changelog](https://github.com/hashicorp/go-retryablehttp/blob/main/CHANGELOG.md) - [Commits](https://github.com/hashicorp/go-retryablehttp/compare/v0.7.1...v0.7.7) --- updated-dependencies: - dependency-name: github.com/hashicorp/go-retryablehttp dependency-type: direct:production dependency-group: go_modules ... Signed-off-by: dependabot[bot] * chore(deps): bump google.golang.org/protobuf Bumps the go_modules group with 1 update in the / directory: google.golang.org/protobuf. Updates `google.golang.org/protobuf` from 1.30.0 to 1.33.0 --- updated-dependencies: - dependency-name: google.golang.org/protobuf dependency-type: indirect dependency-group: go_modules ... Signed-off-by: dependabot[bot] * chore(deps): bump tj-actions/changed-files Bumps the github_actions group with 1 update in the /.github/workflows directory: [tj-actions/changed-files](https://github.com/tj-actions/changed-files). Updates `tj-actions/changed-files` from 1.1.3 to 41.0.0 - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/v1.1.3...v41.0.0) --- updated-dependencies: - dependency-name: tj-actions/changed-files dependency-type: direct:production dependency-group: github_actions ... Signed-off-by: dependabot[bot] * Fixed gradle build to work again - Shortened build.gradle - Run docker container manually - Fix gradle build for example-extension - Fixed failing java keystore tests, version updates, removed custom image build * Set Terraform version to 1.9.5 for tests * Fix KC19 build * Skip using custom-user-federation-example in CI --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Laureat Grepi --- .github/workflows/build-test-image.yml | 43 ---------------- .github/workflows/codeql-analysis.yml | 6 +-- .github/workflows/test.yml | 32 +++++++----- .goreleaser.yml | 4 +- custom-user-federation-example/build.gradle | 48 ++++-------------- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../keycloak/CustomEventListenerProvider.kt | 22 ++++++++ .../CustomEventListenerProviderFactory.kt | 30 +++++++++++ .../keycloak/CustomUserStorageProvider.kt | 24 ++++----- .../META-INF/jboss-deployment-structure.xml | 16 ------ ...ycloak.events.EventListenerProviderFactory | 1 + docker-compose.yml | 10 ++-- go.mod | 18 +++---- go.sum | 39 +++++++------- provider/misc/java-keystore.jks | Bin 2579 -> 0 bytes provider/misc/keystore.jks | Bin 0 -> 2724 bytes ...cloak_realm_keystore_java_kyestore_test.go | 17 ++++--- test/Dockerfile | 8 --- 18 files changed, 146 insertions(+), 174 deletions(-) delete mode 100644 .github/workflows/build-test-image.yml create mode 100644 custom-user-federation-example/src/main/kotlin/com/github/mrparkers/keycloak/CustomEventListenerProvider.kt create mode 100644 custom-user-federation-example/src/main/kotlin/com/github/mrparkers/keycloak/CustomEventListenerProviderFactory.kt delete mode 100644 custom-user-federation-example/src/main/resources/META-INF/jboss-deployment-structure.xml create mode 100644 custom-user-federation-example/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory delete mode 100644 provider/misc/java-keystore.jks create mode 100644 provider/misc/keystore.jks delete mode 100644 test/Dockerfile diff --git a/.github/workflows/build-test-image.yml b/.github/workflows/build-test-image.yml deleted file mode 100644 index a7593b33f..000000000 --- a/.github/workflows/build-test-image.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Build Test Image -on: - push: - branches: - - master - paths: - - ".github/workflows/build-test-image.yml" - - "test/Dockerfile" - -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - keycloak-version: - - '21.0.1' - - '20.0.5' - - '19.0.2' - fail-fast: false - concurrency: - group: docker-build-${{ matrix.keycloak-version }} - cancel-in-progress: true - steps: - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Login to Docker Hub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push - uses: docker/build-push-action@v4 - with: - push: true - tags: mrparkers/keycloak-dev:${{ matrix.keycloak-version }} - file: test/Dockerfile - build-args: | - KEYCLOAK_VERSION=${{ matrix.keycloak-version }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index d353c4f10..70853fca2 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -48,7 +48,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -59,7 +59,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v2 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -73,4 +73,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e4fce6bfc..b66f6877e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: # we only want to run tests if any code changes (not for README or docs changes) - name: Check Changed Files id: files - uses: tj-actions/changed-files@v1.1.3 + uses: tj-actions/changed-files@v41.0.0 with: files: | .github @@ -67,18 +67,6 @@ jobs: concurrency: group: ${{ github.head_ref || github.run_id }}-${{ matrix.keycloak-version }} cancel-in-progress: true - services: - keycloak: - # we have to use a custom docker image for these tests, since it's not possible to provide command-line args - # to a service container. see https://github.com/actions/runner/issues/2139 - image: mrparkers/keycloak-dev:${{ matrix.keycloak-version }} - ports: - - 8080:8080 - env: - KC_DB: dev-mem - KC_LOG_LEVEL: INFO - KEYCLOAK_ADMIN: keycloak - KEYCLOAK_ADMIN_PASSWORD: password steps: - name: Checkout Code uses: actions/checkout@v3 @@ -93,7 +81,19 @@ jobs: uses: hashicorp/setup-terraform@v1 with: terraform_wrapper: false - terraform_version: 1.4.1 + terraform_version: 1.9.5 + + - name: Start Keycloak Container + run: | + docker run -d --name keycloak \ + -p 8080:8080 \ + -e KC_DB=dev-mem \ + -e KC_LOG_LEVEL=INFO \ + -e KEYCLOAK_ADMIN=keycloak \ + -e KEYCLOAK_ADMIN_PASSWORD=password \ + -e KC_FEATURES=preview \ + -v $PWD/provider/misc:/opt/keycloak/misc:z \ + quay.io/keycloak/keycloak:${{ matrix.keycloak-version }} start-dev - name: Initialize Keycloak run: ./scripts/wait-for-local-keycloak.sh && ./scripts/create-terraform-client.sh @@ -119,3 +119,7 @@ jobs: KEYCLOAK_TEST_PASSWORD_GRANT: "true" KEYCLOAK_VERSION: ${{ steps.keycloak-version.outputs.result }} timeout-minutes: 60 + - name: Clean up + run: | + docker stop keycloak + docker rm keycloak diff --git a/.goreleaser.yml b/.goreleaser.yml index d1c1d733c..8402b84dd 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,5 +1,7 @@ # Visit https://goreleaser.com for documentation on how to customize this # behavior. +version: 2 + before: hooks: # this is just an example and not a requirement for provider building/publishing @@ -57,4 +59,4 @@ release: # If you want to manually examine the release before its live, uncomment this line: # draft: true changelog: - skip: true + disable: true diff --git a/custom-user-federation-example/build.gradle b/custom-user-federation-example/build.gradle index 140e7f547..4c32d943b 100644 --- a/custom-user-federation-example/build.gradle +++ b/custom-user-federation-example/build.gradle @@ -1,50 +1,22 @@ -buildscript { - ext.kotlinVersion = '1.3.31' - ext.keycloakVersion = '19.0.2' - ext.shadowJarVersion = '4.0.2' - - repositories { - mavenCentral() - jcenter() - } - - dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}" - classpath "com.github.jengelman.gradle.plugins:shadow:${shadowJarVersion}" - } -} - -apply { - plugin 'java' - plugin 'kotlin' - plugin 'com.github.johnrengelman.shadow' +plugins { + id 'org.jetbrains.kotlin.jvm' version '2.0.20' + id 'com.gradleup.shadow' version '8.3.0' + id 'java-library' } -shadowJar { - classifier = null +ext { + keycloakVersion = '21.0.1' } dependencies { - compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinVersion}" - compile "org.keycloak:keycloak-core:${keycloakVersion}" - compile "org.keycloak:keycloak-services:${keycloakVersion}" - compile "org.keycloak:keycloak-server-spi:${keycloakVersion}" - compile "org.keycloak:keycloak-server-spi-private:${keycloakVersion}" - compile "org.keycloak:keycloak-model-legacy:${keycloakVersion}" + compileOnly "org.keycloak:keycloak-services:${keycloakVersion}" + compileOnly "org.keycloak:keycloak-model-legacy:${keycloakVersion}" } repositories { mavenCentral() } -compileKotlin { - kotlinOptions { - jvmTarget = "1.8" - } -} - -compileTestKotlin { - kotlinOptions { - jvmTarget = "1.8" - } +kotlin { + jvmToolchain(11) } diff --git a/custom-user-federation-example/gradle/wrapper/gradle-wrapper.properties b/custom-user-federation-example/gradle/wrapper/gradle-wrapper.properties index 9ec837b2b..6cb8454ca 100644 --- a/custom-user-federation-example/gradle/wrapper/gradle-wrapper.properties +++ b/custom-user-federation-example/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-all.zip diff --git a/custom-user-federation-example/src/main/kotlin/com/github/mrparkers/keycloak/CustomEventListenerProvider.kt b/custom-user-federation-example/src/main/kotlin/com/github/mrparkers/keycloak/CustomEventListenerProvider.kt new file mode 100644 index 000000000..75a712e65 --- /dev/null +++ b/custom-user-federation-example/src/main/kotlin/com/github/mrparkers/keycloak/CustomEventListenerProvider.kt @@ -0,0 +1,22 @@ +package com.github.mrparkers.keycloak + +import org.keycloak.events.Event +import org.keycloak.events.EventListenerProvider +import org.keycloak.events.admin.AdminEvent +import org.keycloak.models.KeycloakSession + +class CustomEventListenerProvider(session: KeycloakSession) : EventListenerProvider { + + override fun onEvent(event: Event) { + // + } + + override fun onEvent(adminEvent: AdminEvent, includeRep: Boolean) { + // + } + + override fun close() { + // NOOP + } + +} diff --git a/custom-user-federation-example/src/main/kotlin/com/github/mrparkers/keycloak/CustomEventListenerProviderFactory.kt b/custom-user-federation-example/src/main/kotlin/com/github/mrparkers/keycloak/CustomEventListenerProviderFactory.kt new file mode 100644 index 000000000..3c70018fd --- /dev/null +++ b/custom-user-federation-example/src/main/kotlin/com/github/mrparkers/keycloak/CustomEventListenerProviderFactory.kt @@ -0,0 +1,30 @@ +package com.github.mrparkers.keycloak + +import org.keycloak.Config +import org.keycloak.events.EventListenerProvider +import org.keycloak.events.EventListenerProviderFactory +import org.keycloak.models.KeycloakSession +import org.keycloak.models.KeycloakSessionFactory + +class CustomEventListenerProviderFactory : EventListenerProviderFactory { + + override fun create(session: KeycloakSession): EventListenerProvider { + return CustomEventListenerProvider(session); + } + + override fun init(config: Config.Scope) { + // NOOP + } + + override fun postInit(sessionFactory: KeycloakSessionFactory) { + // NOOP + } + + override fun close() { + // NOOP + } + + override fun getId(): String { + return "example-listener"; + } +} diff --git a/custom-user-federation-example/src/main/kotlin/com/github/mrparkers/keycloak/CustomUserStorageProvider.kt b/custom-user-federation-example/src/main/kotlin/com/github/mrparkers/keycloak/CustomUserStorageProvider.kt index 700ddb03f..ea71c7e67 100644 --- a/custom-user-federation-example/src/main/kotlin/com/github/mrparkers/keycloak/CustomUserStorageProvider.kt +++ b/custom-user-federation-example/src/main/kotlin/com/github/mrparkers/keycloak/CustomUserStorageProvider.kt @@ -4,15 +4,17 @@ import org.keycloak.component.ComponentModel import org.keycloak.credential.CredentialInput import org.keycloak.credential.CredentialInputUpdater import org.keycloak.credential.CredentialInputValidator -import org.keycloak.credential.CredentialModel +import org.keycloak.models.credential.PasswordCredentialModel import org.keycloak.credential.LegacyUserCredentialManager import org.keycloak.models.* +import org.keycloak.models.credential.* import org.keycloak.storage.ReadOnlyException import org.keycloak.storage.StorageId import org.keycloak.storage.UserStorageProvider import org.keycloak.storage.adapter.AbstractUserAdapter import org.keycloak.storage.user.UserLookupProvider import java.util.* +import java.util.stream.Stream class CustomUserStorageProvider(private val session: KeycloakSession, private val model: ComponentModel) : UserStorageProvider, UserLookupProvider, CredentialInputValidator, CredentialInputUpdater { @@ -30,11 +32,11 @@ class CustomUserStorageProvider(private val session: KeycloakSession, private va // UserLookupProvider - override fun getUserByEmail(email: String, realm: RealmModel): UserModel? { + override fun getUserByEmail(realm: RealmModel, email: String): UserModel? { return null } - override fun getUserByUsername(username: String, realm: RealmModel): UserModel? { + override fun getUserByUsername(realm: RealmModel, username: String): UserModel? { val user = loadedUsers[username] if (user != null) { @@ -60,11 +62,11 @@ class CustomUserStorageProvider(private val session: KeycloakSession, private va return null } - override fun getUserById(id: String, realm: RealmModel): UserModel? { + override fun getUserById(realm: RealmModel, id: String): UserModel? { val storageId = StorageId(id) val username = storageId.externalId - return getUserByUsername(username, realm) + return getUserByUsername(realm, username) } // CredentialInputValidator @@ -74,7 +76,7 @@ class CustomUserStorageProvider(private val session: KeycloakSession, private va } override fun supportsCredentialType(credentialType: String?): Boolean { - return credentialType.equals(CredentialModel.PASSWORD) + return credentialType.equals(PasswordCredentialModel.TYPE) } override fun isValid(realm: RealmModel, user: UserModel, input: CredentialInput): Boolean { @@ -87,14 +89,12 @@ class CustomUserStorageProvider(private val session: KeycloakSession, private va return password == input.value } - // CredentialInputUpdater - - override fun getDisableableCredentialTypes(realm: RealmModel, user: UserModel): MutableSet { - return Collections.EMPTY_SET as MutableSet - } + override fun getDisableableCredentialTypesStream(realm: RealmModel, user: UserModel): Stream { + return Stream.empty() + } override fun updateCredential(realm: RealmModel, user: UserModel, input: CredentialInput): Boolean { - if (input.type == CredentialModel.PASSWORD) { + if (input.type == PasswordCredentialModel.TYPE) { throw ReadOnlyException("Custom provider does not support password updating") } diff --git a/custom-user-federation-example/src/main/resources/META-INF/jboss-deployment-structure.xml b/custom-user-federation-example/src/main/resources/META-INF/jboss-deployment-structure.xml deleted file mode 100644 index 63a4ac777..000000000 --- a/custom-user-federation-example/src/main/resources/META-INF/jboss-deployment-structure.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/custom-user-federation-example/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory b/custom-user-federation-example/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory new file mode 100644 index 000000000..47ca129f5 --- /dev/null +++ b/custom-user-federation-example/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory @@ -0,0 +1 @@ +com.github.mrparkers.keycloak.CustomEventListenerProviderFactory diff --git a/docker-compose.yml b/docker-compose.yml index d05dfe5c2..d36730cfa 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,3 @@ -version: "3" volumes: postgres: services: @@ -7,18 +6,18 @@ services: - POSTGRES_DB=keycloak - POSTGRES_USER=keycloak - POSTGRES_PASSWORD=password - image: postgres:12 + image: postgres:16 ports: - 5432:5432 volumes: - postgres:/var/lib/postgresql openldap: - image: osixia/openldap:1.3.0 + image: bitnami/openldap:2.6 ports: - 8389:389 keycloak: image: quay.io/keycloak/keycloak:21.0.1 - command: start-dev --features=preview + command: --verbose start-dev --features=preview depends_on: - postgres - openldap @@ -40,4 +39,5 @@ services: # - 8787:8787 volumes: # Make the custom-user-federation-example extension available to Keycloak. The :z option is required and tells Docker that the volume content will be shared between containers. - - ./custom-user-federation-example/build/libs/custom-user-federation-example.jar:/opt/jboss/keycloak/standalone/deployments/custom-user-federation-example.jar:z + - ./custom-user-federation-example/build/libs/custom-user-federation-example-all.jar:/opt/keycloak/providers/custom-user-federation-example-all.jar:z + - ./provider/misc:/opt/keycloak/misc:z diff --git a/go.mod b/go.mod index aaf5fae2e..89c597a4d 100644 --- a/go.mod +++ b/go.mod @@ -3,23 +3,23 @@ module github.com/mrparkers/terraform-provider-keycloak require ( github.com/hashicorp/errwrap v1.0.0 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 - github.com/hashicorp/go-retryablehttp v0.7.1 + github.com/hashicorp/go-retryablehttp v0.7.7 github.com/hashicorp/go-version v1.6.0 github.com/hashicorp/terraform-plugin-log v0.9.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1 github.com/imdario/mergo v0.3.13 - golang.org/x/net v0.17.0 + golang.org/x/net v0.23.0 ) require ( github.com/agext/levenshtein v1.2.2 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect - github.com/fatih/color v1.13.0 // indirect + github.com/fatih/color v1.16.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-plugin v1.4.8 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect @@ -32,8 +32,8 @@ require ( github.com/hashicorp/terraform-registry-address v0.1.0 // indirect github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 // indirect github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect - github.com/mattn/go-colorable v0.1.12 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.0 // indirect @@ -44,14 +44,14 @@ require ( github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect github.com/vmihailenco/tagparser v0.1.1 // indirect github.com/zclconf/go-cty v1.13.1 // indirect - golang.org/x/crypto v0.17.0 // indirect + golang.org/x/crypto v0.21.0 // indirect golang.org/x/mod v0.8.0 // indirect - golang.org/x/sys v0.15.0 // indirect + golang.org/x/sys v0.20.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect google.golang.org/grpc v1.56.3 // indirect - google.golang.org/protobuf v1.30.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect ) go 1.19 diff --git a/go.sum b/go.sum index e72123337..f86853061 100644 --- a/go.sum +++ b/go.sum @@ -26,8 +26,9 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= @@ -63,16 +64,15 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= -github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-plugin v1.4.8 h1:CHGwpxYDOttQOY7HOWgETU9dyVjOXzniXDqJcYJE1zM= github.com/hashicorp/go-plugin v1.4.8/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= -github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1aJLQ4LJJbTQ= -github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -126,12 +126,15 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= @@ -190,8 +193,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= @@ -209,8 +212,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -234,13 +237,15 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -264,8 +269,8 @@ google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/provider/misc/java-keystore.jks b/provider/misc/java-keystore.jks deleted file mode 100644 index d0d3afc69ef99d4a603351d8f590861c4cfa2795..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2579 zcmY+EX*3j!8pn-UVki=lq9`$z8pfVuSB)iEvV&@VU!#Dv2j(EsD(=jTEE z)H<;aY0DrV$dp5E`Sf1J%v`xSJCLpSE(imn`Jl}qyA&B44Z)EZPanMS-t^j-G5Lq5z$uIrx z1>e>*!o3gb0_G6bDm}dYVZu)#E^CjGH^Nsh$c>zRK z+W?&Q+9aY3RLDJg+QpmdGC%JLRx;*M%VX)a-|PI+X);4xSrl}d?}>DM>&(ajCab{= z@;@R8upXTR3d9!Xh@_FFb2;)~-w>$QsP9FPo^VP%&!Mk|p5FctuyM}4>^z47r_&^M zp>k^WhJVYjn(o2EMX;8j7k6Kj;OM?**7o6V-9A0rvmMYCl2&X(RGNKlhyn><*2R85 zLiUr7pPOp&TL%6Cz`C{W_T;&aj-iGnl;BePH6FHZqg>T3Nx9Xr;Dv@~iw;5vVz>6F zgwwzyuJ^kJ*xqp*-yyV?KQk8xX*SKCG@$b+d*I4KjE<|)eJckwkQiJgt0aOK)+UAvd1-$bG$r*xAyPyVVRr1cJ1EEcaOph}V++tqk~ zTa5?heAW4~qmf%dfIYTkR^`RfubEv7df=tEO6#>Fpj1kLn7^8Mt<5X#ZaynxbuuxYIg`F*XcKzXn@xq9s;#v=#7(JSCoioaGdbN-9V7r z6V0VlyV05aZyx*Rb_CQ*6)PY$eVYtqys~LpJIa1L^!%blLf15c@buW)55Rm5w@mYHLx?Pf2M#!rwBa~H?6jcS z=>+81rAo(0o*lq;yrln50RONn?V|Fvrz2KbdE z>pXMYT}vh#Nr!&7^PIAk@%nALv?KetfI)d5MrN)$xq@@=t!0-Y3P3Nh>_^I3!)La{x~TJ*r>B`ukBajrE5L1KXJQB7p%_@ zDBRb^Pfq5tvZg;UT`c9aG74v22X+`LvL%)z-y2_3SY4jY>!rOT6I>!&{5s#9SUQy{ zQ}#Rx8RQ1nQ}=UXa^g{;fmO;Oxe+1pCW#}hiz&9JmX6TE3DACf%BP*whClM2qzA@D z2h>)R2a4t^7qlkrh?xW1+w!s03bC|D{1OuWfsJU}Jr?jqeBEyK$t#Yuw!G%hO#nDK zaWUQZCx<%!&SbJ!XIF}Aik$yiV5VX~ZtRVTT}m{mPB$@VZ3I>Sv*To#rO9eVfqKlC zwZp7!3-qT7ocFP2x!{b@H;Es-csuMC-{|P`**&$Mf%E~?F7q&^B`IOCmg1>%^}^DL zK8KXE_w2MnOm%M!qrdB58Ek`*gOb8(RY7N~RO3EwYMfCE%<($%IJwaCX%(*(qLY)+ zcEoa;8wp>HVb(NY2g~siNKUFeDP7=cw_8SX{4U3H9%`O{7;Jjz`oUVs&H_8{FWnkI ztZ(@BjaKKrB?3bD%BRs6q)MWli13S;PtTa*woL>5pPscp#F?IgHZO$trz-en(Xq>N za`i4_9feyMU>3rdbxTIqZI@gccG6Q-o4kckc}X`%b15%<^UHQMJMvUzwjlo)VzDpl zu+}4aJ6*v%gE8AI_a1xN)B?(q{B;7{!27P%-HENua;PXmJ@-O6oH(wgi4v>zRib{x z_m>Ok#o>Q6u;_PIS|(n>$f|OQ=`kM+a0rp@e_h$4%=>Q-Yh_&7b8@dP5z?IaRg!gq zPB&hgvq=aucH?xp{#jK(RwIO|lJm-^wymw0$UiWMeBd1G06c%@Xf@NmX4q_+;}!_Z z6Ec?fyPlEuqes&F{9QUabr|@hxskwlRqLB~>F|tow`q&6h2gY!={XUj_@)h7z1-H( zIb{J3KSa7fvPOn~M%PpUEp1K7^^&%DY~{oJM?+YcDK6^810@-6UqRRT1PR2rqDqYP znfE1B^v<_vJ#`p`L3={5?@=R=G4u(l)r!<<0;xZWwTLt>RTIC8-Mt6ZU)giMxsN)$ zn%5?0WMBPu!7T34dM6mJ2^WKNLclVofb7CxHW0tz(r;pQxn64Z#H1M4zK%_`wb4Bg ezh8IvZ%4gt(JFn98LI(hpT49&(Ck0}uIS&6wcj5A diff --git a/provider/misc/keystore.jks b/provider/misc/keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..94e04f3d48f8b46093155e7a168a561610f4bb0a GIT binary patch literal 2724 zcma);X*d)N_r}eb8D@qo4JAgF>`P-CV|%15lT3`pmKJH4hp}W!gcvmEA;3b^n;Bya|Z0#5ynAN;OF2>jnJJ{SO)O#z?y4GmH5e;iT0U-wXzsc6)CeDS)`~K?Lic2941VjOW3W7j@6p9bR`~Me#P%sw?34yv$ zu>d!25I`9u*i-l;mn=Cqmz9`C!9$tjAPT65r`gj6>x@4nSWt&YR(4A^RiTrU$u0Rg zC`+lSxo8zTOS}b{`QeDZS2!6-FOGVldg~^1Q@xp)c@uD1T4w2qBmJvNMq0wHoQV;H ziqH~s;E=-VM2e=>7tJN7c?krz{*%J{lQs><2+3hDEy)d%rd+>C)x zGWPxpZ}_NAer8_0{+5JY*1}9v#~`Q7ip#pBVXR0XNh*eTX2=DqT{uug#=$cS{WPD& z1m_EXnag;(E1(wSLXHn5(7IU8&f5a+wc&lTSDQ&U2-gr$^Vt*kEWsEqup;qr`V zu-jW1!Dg{kTaT%As;NGFH4obh(z06^0|525L;b6QOuMWM#13T(#!|i{xpj0`gKvr7 zX>%_1MjKYk>NQproh+s9_uM<-0Bt5ePLb8H&(emd${I-%T<>+TjQ3xb#ja1PaOw^! zKF73e#Jo8+T+9XsQ5J1ai?Xd*X(?w|wLieuAV4=k6@D$Vg!J4kg4FPtEgHExGA#+S zAFGzAjhGkRQN3}#c67BPeRGn$E7ynkfKNpBqFtl!VsYdgm&t7mIkjwhnsmKWw%bYg z;+&`d`a&R*=co9E?^;_*3yC8N@xg8_mGuv9HSoRYI{ItC@27Y+&e#LCf1m%w_Udj9 zy7r(E*brT%nm-lbbjkjO;OE0Oa@?S@-C^R9S#LIc*3(I==%fmDg9Ao@1PUz94rXs&P_T4?CTXx^~6`$j*&^XYJFF{HqI zQkK}d#Hr_OJq(Ol50`AZKjm>6WQuH1O5eJKFe;_(@#?AwNg z@8OZ^{hy2DFTQJOm;Vs9d=9rcer&VUw+G-=f&X|gu|a(iYk+X*{Ooht=}aiQGk{$1 zs2uK#DJ=Gk+y?5USd90bf=nd^hWB3%%EJg|>6UQbn;gDh8f-2{Qp#=b+|OR~3E;jg zt?Js>e_)eW05x*a#azB;ixeH(Q4nNwU5K$AkGP)WPLr^y2}!R|jI=j)pDK!a0{EC~ zJv!|jexY2$5OwHJTtX2VFiBpnKrT0~0Iook^gn`#1_C5Z@bGq%($Lk^!C>^z8hU87 z28sfT`m@9X$)TSSkf{fsPZlC{;V))4JoAIIFA)jIUQL^RVJ zvi7|Id_1I&(Ak&Bc@#X8C!|LlFW6 zpDi@BiyA?OmR&-)BX2>%y5{qF?8<(x9CJ|@?Fj9#g08W}(7Zs0p*@jDcf{3IJY3P{ zME<#VyAqjq>UO424@9*aM^#RCM*DjB?H&ni*>WpiEHus)?E(r;5>aa*5k7^H9^BnB zXmyI@yEYL@QTba7yRp7r4l10@ZmW+|W`Trve0e<&M5V|3O=NU9nW))W*s_HW{Fkkhfu)VDP>g3+x|Qlma3Qvu4ZXBizX*3}JEKi>cwYepmfoED+gTLV3&XSo<^+WeWQSVWXb> z4HH^CVoi(^dc~_~uM^ek^-!9G?AYXSHv7_iy@ueDofLdaC)Q|i@D+rX?2$GBm{aQTWDo@7mF%(5Vx~daKsi4~$6soD~S}EqXCnqRa zAbGm}iz;^l@+65gQ?C0Yq_KrxOXJ8dMIImL+Bno{+Y_#Jl6eUR{$;__J&E-6a9WS! zx$kxKZ=AN7B2oms9@YkU4Q+Y0aSIn*x?LxKC5nX|_g#=>KnwbFyy&xYl$0paem zmBnedokw2%uoOWJvBnOT@(hs9-mTsTGPVHAC6ljBW#|@5f2&&NS#y|LIR272S`lj^8bWL|X;zqzmSri}vHO*BSyeDU z%YvMH=KA=RI4SnZ&r*GFl{r)| z1__QLHa_wByy7`EBd&N8D9j;>5Zcuv@%vS`atWb#E=IoOMd45yDE>d68xR2I0!b;| z2=c1d%v}Hbn_2ZonKT~iBc^WWn@z<5)7yD>PRXr-5W}iL@ Date: Mon, 2 Sep 2024 18:12:03 +0200 Subject: [PATCH 02/12] Enable configuring required action from terraform Signed-off-by: Laureat Grepi --- provider/resource_keycloak_required_action.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/provider/resource_keycloak_required_action.go b/provider/resource_keycloak_required_action.go index c6c751496..3b67ca585 100644 --- a/provider/resource_keycloak_required_action.go +++ b/provider/resource_keycloak_required_action.go @@ -4,10 +4,11 @@ import ( "context" "errors" "fmt" + "strings" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/mrparkers/terraform-provider-keycloak/keycloak" - "strings" ) func resourceKeycloakRequiredAction() *schema.Resource { @@ -47,6 +48,10 @@ func resourceKeycloakRequiredAction() *schema.Resource { Optional: true, Computed: true, }, + "config": { + Type: schema.TypeMap, + Optional: true, + }, }, } } @@ -60,7 +65,7 @@ func getRequiredActionFromData(data *schema.ResourceData) (*keycloak.RequiredAct Enabled: data.Get("enabled").(bool), DefaultAction: data.Get("default_action").(bool), Priority: data.Get("priority").(int), - Config: make(map[string][]string), + Config: data.Get("config").(map[string][]string), } return action, nil @@ -74,6 +79,7 @@ func setRequiredActionData(data *schema.ResourceData, action *keycloak.RequiredA data.Set("enabled", action.Enabled) data.Set("default_action", action.DefaultAction) data.Set("priority", action.Priority) + data.Set("config", action.Config) } func resourceKeycloakRequiredActionsCreate(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { From d49c6127ccaf69bd0fbb20f606e5abc720def5aa Mon Sep 17 00:00:00 2001 From: Laureat Grepi Date: Tue, 3 Sep 2024 12:28:55 +0200 Subject: [PATCH 03/12] Allow required action config values to be passed from terraform Signed-off-by: Laureat Grepi --- keycloak/required_action.go | 23 +++++----- provider/resource_keycloak_required_action.go | 8 +++- .../resource_keycloak_required_action_test.go | 43 +++++++++++++++++++ 3 files changed, 61 insertions(+), 13 deletions(-) diff --git a/keycloak/required_action.go b/keycloak/required_action.go index d46c3db94..5893f556b 100644 --- a/keycloak/required_action.go +++ b/keycloak/required_action.go @@ -6,31 +6,30 @@ import ( ) type RequiredAction struct { - Id string `json:"-"` - RealmId string `json:"-"` - Alias string `json:"alias"` - Name string `json:"name"` - ProviderId string `json:"providerId"` - Enabled bool `json:"enabled"` - DefaultAction bool `json:"defaultAction"` - Priority int `json:"priority"` - Config map[string][]string `json:"config"` + Id string `json:"-"` + RealmId string `json:"-"` + Alias string `json:"alias"` + Name string `json:"name"` + ProviderId string `json:"providerId"` + Enabled bool `json:"enabled"` + DefaultAction bool `json:"defaultAction"` + Priority int `json:"priority"` + Config map[string]string `json:"config"` } func (requiredActions *RequiredAction) getConfig(val string) string { if len(requiredActions.Config[val]) == 0 { return "" } - return requiredActions.Config[val][0] + return requiredActions.Config[val] } func (requiredActions *RequiredAction) getConfigOk(val string) (string, bool) { if v, ok := requiredActions.Config[val]; ok { - return v[0], true + return v, true } return "", false } - func (keycloakClient *KeycloakClient) GetRequiredActions(ctx context.Context, realmId string) ([]*RequiredAction, error) { var requiredActions []*RequiredAction diff --git a/provider/resource_keycloak_required_action.go b/provider/resource_keycloak_required_action.go index 3b67ca585..7d4cc0ad9 100644 --- a/provider/resource_keycloak_required_action.go +++ b/provider/resource_keycloak_required_action.go @@ -50,6 +50,7 @@ func resourceKeycloakRequiredAction() *schema.Resource { }, "config": { Type: schema.TypeMap, + Elem: &schema.Schema{Type: schema.TypeString}, Optional: true, }, }, @@ -57,6 +58,11 @@ func resourceKeycloakRequiredAction() *schema.Resource { } func getRequiredActionFromData(data *schema.ResourceData) (*keycloak.RequiredAction, error) { + config := make(map[string]string) + for key, value := range data.Get("config").(map[string]interface{}) { + config[key] = value.(string) + } + action := &keycloak.RequiredAction{ Id: fmt.Sprintf("%s/%s", data.Get("realm_id").(string), data.Get("alias").(string)), RealmId: data.Get("realm_id").(string), @@ -65,7 +71,7 @@ func getRequiredActionFromData(data *schema.ResourceData) (*keycloak.RequiredAct Enabled: data.Get("enabled").(bool), DefaultAction: data.Get("default_action").(bool), Priority: data.Get("priority").(int), - Config: data.Get("config").(map[string][]string), + Config: config, } return action, nil diff --git a/provider/resource_keycloak_required_action_test.go b/provider/resource_keycloak_required_action_test.go index 989d80ec8..3afa44f5f 100644 --- a/provider/resource_keycloak_required_action_test.go +++ b/provider/resource_keycloak_required_action_test.go @@ -26,6 +26,28 @@ func TestAccKeycloakRequiredAction_basic(t *testing.T) { }) } +func TestAccKeycloakRequiredAction_withConfig(t *testing.T) { + realmName := acctest.RandomWithPrefix("tf-acc") + requiredActionAlias := "UPDATE_PASSWORD" + maxAuthAgeConfig := "3600" + + resource.Test(t, resource.TestCase{ + ProviderFactories: testAccProviderFactories, + PreCheck: func() { testAccPreCheck(t) }, + Steps: []resource.TestStep{ + { + Config: testKeycloakRequiredAction_withConfig(realmName, requiredActionAlias, 37, maxAuthAgeConfig), + Check: resource.ComposeTestCheckFunc( + testAccCheckKeycloakRequiresActionExists(realmName, requiredActionAlias), + resource.TestCheckResourceAttr("keycloak_required_action.required_action", "realm_id", realmName), + resource.TestCheckResourceAttr("keycloak_required_action.required_action", "config.%", "1"), + resource.TestCheckResourceAttr("keycloak_required_action.required_action", "config.max_auth_age", maxAuthAgeConfig), + ), + }, + }, + }) +} + func TestAccKeycloakRequiredAction_unregisteredAction(t *testing.T) { realmName := acctest.RandomWithPrefix("tf-acc") requiredActionAlias := "webauthn-register" @@ -128,6 +150,27 @@ resource "keycloak_required_action" "required_action" { `, realm, requiredActionAlias, priority) } +func testKeycloakRequiredAction_withConfig(realm, requiredActionAlias string, priority int, maxAuthAgeConfig string) string { + return fmt.Sprintf(` +resource "keycloak_realm" "realm" { + realm = "%s" +} + +resource "keycloak_required_action" "required_action" { + realm_id = "${keycloak_realm.realm.realm}" + alias = "%s" + default_action = true + enabled = true + name = "My required Action" + priority = %d + + config = { + max_auth_age = "%s" + } +} + `, realm, requiredActionAlias, priority, maxAuthAgeConfig) +} + func testKeycloakRequiredAction_import(realm, requiredActionAlias string) string { return fmt.Sprintf(` resource "keycloak_realm" "realm" { From b4f0163b9f5981d34c8b2288e061bd30d4307726 Mon Sep 17 00:00:00 2001 From: Laureat Grepi Date: Tue, 3 Sep 2024 12:38:33 +0200 Subject: [PATCH 04/12] update examples Signed-off-by: Laureat Grepi --- docs/resources/required_action.md | 9 +++++-- example/main.tf | 41 ++++++++++++++++++++----------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/docs/resources/required_action.md b/docs/resources/required_action.md index 9ca6901a6..554b03feb 100644 --- a/docs/resources/required_action.md +++ b/docs/resources/required_action.md @@ -19,9 +19,13 @@ resource "keycloak_realm" "realm" { resource "keycloak_required_action" "required_action" { realm_id = keycloak_realm.realm.realm - alias = "webauthn-register" + alias = "UPDATE_PASSWORD" enabled = true - name = "Webauthn Register" + name = "Update Password" + + config = { + max_auth_age = "600" + } } ``` @@ -33,6 +37,7 @@ resource "keycloak_required_action" "required_action" { - `enabled` - (Optional) When `false`, the required action is not enabled for new users. Defaults to `false`. - `default_action` - (Optional) When `true`, the required action is set as the default action for new users. Defaults to `false`. - `priority`- (Optional) The priority of the required action. +- `config`- (Optional) The configuration. Keys are specific to each configurable required action and not checked when applying. ## Import diff --git a/example/main.tf b/example/main.tf index ceb8796b0..966b27153 100644 --- a/example/main.tf +++ b/example/main.tf @@ -109,6 +109,17 @@ resource "keycloak_required_action" "custom-terms-and-conditions" { name = "Custom Terms and Conditions" } +resource "keycloak_required_action" "update-password" { + realm_id = keycloak_realm.test.realm + alias = "UPDATE_PASSWORD" + default_action = true + enabled = true + name = "Update Password" + + config { + max_auth_age = "600" + } +} resource "keycloak_required_action" "custom-configured_totp" { realm_id = keycloak_realm.test.realm alias = "CONFIGURE_TOTP" @@ -427,25 +438,25 @@ resource "keycloak_ldap_full_name_mapper" "full_name_mapper" { } resource "keycloak_ldap_custom_mapper" "custom_mapper" { - name = "custom-mapper" - realm_id = keycloak_ldap_user_federation.openldap.realm_id - ldap_user_federation_id = keycloak_ldap_user_federation.openldap.id + name = "custom-mapper" + realm_id = keycloak_ldap_user_federation.openldap.realm_id + ldap_user_federation_id = keycloak_ldap_user_federation.openldap.id - provider_id = "msad-user-account-control-mapper" - provider_type = "org.keycloak.storage.ldap.mappers.LDAPStorageMapper" + provider_id = "msad-user-account-control-mapper" + provider_type = "org.keycloak.storage.ldap.mappers.LDAPStorageMapper" } resource "keycloak_ldap_custom_mapper" "custom_mapper_with_config" { - name = "custom-mapper-with-config" - realm_id = keycloak_ldap_user_federation.openldap.realm_id - ldap_user_federation_id = keycloak_ldap_user_federation.openldap.id - - provider_id = "user-attribute-ldap-mapper" - provider_type = "org.keycloak.storage.ldap.mappers.LDAPStorageMapper" - config = { - "user.model.attribute" = "username" - "ldap.attribute" = "cn" - } + name = "custom-mapper-with-config" + realm_id = keycloak_ldap_user_federation.openldap.realm_id + ldap_user_federation_id = keycloak_ldap_user_federation.openldap.id + + provider_id = "user-attribute-ldap-mapper" + provider_type = "org.keycloak.storage.ldap.mappers.LDAPStorageMapper" + config = { + "user.model.attribute" = "username" + "ldap.attribute" = "cn" + } } From e75047dbcb2f4a886909b3a2e59540d313fd7e8a Mon Sep 17 00:00:00 2001 From: Michael Parker Date: Thu, 26 Sep 2024 19:04:13 -0500 Subject: [PATCH 05/12] Dual license project under MIT and Apache 2.0 Signed-off-by: Laureat Grepi --- LICENSE-APACHE-2.0 | 177 +++++++++++++++++++++++++++++++++++++++++ LICENSE => LICENSE-MIT | 2 +- README.md | 7 +- 3 files changed, 184 insertions(+), 2 deletions(-) create mode 100644 LICENSE-APACHE-2.0 rename LICENSE => LICENSE-MIT (96%) diff --git a/LICENSE-APACHE-2.0 b/LICENSE-APACHE-2.0 new file mode 100644 index 000000000..f433b1a53 --- /dev/null +++ b/LICENSE-APACHE-2.0 @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/LICENSE b/LICENSE-MIT similarity index 96% rename from LICENSE rename to LICENSE-MIT index d57fe5ccd..3b74241e9 100644 --- a/LICENSE +++ b/LICENSE-MIT @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018-2020 Michael Parker +Copyright (c) 2018-2024 Michael Parker Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index f511e2352..808748514 100644 --- a/README.md +++ b/README.md @@ -94,4 +94,9 @@ make testacc ## License -[MIT](https://github.com/mrparkers/terraform-provider-keycloak/blob/master/LICENSE) +This software is licensed under either of the following, at your option: + +- Apache License, Version 2.0, (LICENSE-APACHE-2.0 or https://www.apache.org/licenses/LICENSE-2.0) +- MIT License (LICENSE-MIT or https://opensource.org/licenses/MIT) + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this software by you shall be dual licensed under the MIT License and Apache License, Version 2.0, without any additional terms or conditions. From 57832575c97d19e0a56904663a07f4ef7466a704 Mon Sep 17 00:00:00 2001 From: Laureat Grepi Date: Mon, 30 Sep 2024 11:05:50 +0200 Subject: [PATCH 06/12] Add multivalued config in user profile Signed-off-by: Laureat Grepi --- docs/resources/realm_user_profile.md | 2 ++ example/main.tf | 3 ++- keycloak/realm_user_profile.go | 1 + provider/resource_keycloak_realm_user_profile.go | 7 +++++++ provider/resource_keycloak_realm_user_profile_test.go | 1 + 5 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/resources/realm_user_profile.md b/docs/resources/realm_user_profile.md index dc4f0071c..5b6ddabb9 100644 --- a/docs/resources/realm_user_profile.md +++ b/docs/resources/realm_user_profile.md @@ -63,6 +63,7 @@ resource "keycloak_realm_user_profile" "userprofile" { attribute { name = "field2" + multivalued = true validator { name = "options" @@ -104,6 +105,7 @@ resource "keycloak_realm_user_profile" "userprofile" { - `name` - (Required) The name of the attribute. - `display_name` - (Optional) The display name of the attribute. - `group` - (Optional) The group that the attribute belong to. +- `multivalued` - (Optional) The attribute can contain multiple values. Defaults to `false`. - `enabled_when_scope` - (Optional) A list of scopes. The attribute will only be enabled when these scopes are requested by clients. - `required_for_roles` - (Optional) A list of roles for which the attribute will be required. - `required_for_scopes` - (Optional) A list of scopes for which the attribute will be required. diff --git a/example/main.tf b/example/main.tf index 966b27153..25af7ab4e 100644 --- a/example/main.tf +++ b/example/main.tf @@ -1139,7 +1139,8 @@ resource "keycloak_realm_user_profile" "userprofile" { } attribute { - name = "field2" + name = "field2" + multivalued = true } group { diff --git a/keycloak/realm_user_profile.go b/keycloak/realm_user_profile.go index ce18ebf47..f67732907 100644 --- a/keycloak/realm_user_profile.go +++ b/keycloak/realm_user_profile.go @@ -31,6 +31,7 @@ type RealmUserProfileAttribute struct { Required *RealmUserProfileRequired `json:"required,omitempty"` Selector *RealmUserProfileSelector `json:"selector,omitempty"` Validations map[string]RealmUserProfileValidationConfig `json:"validations,omitempty"` + Multivalued bool `json:"multivalued"` } type RealmUserProfileGroup struct { diff --git a/provider/resource_keycloak_realm_user_profile.go b/provider/resource_keycloak_realm_user_profile.go index b8ab597de..aa51a084b 100644 --- a/provider/resource_keycloak_realm_user_profile.go +++ b/provider/resource_keycloak_realm_user_profile.go @@ -39,6 +39,11 @@ func resourceKeycloakRealmUserProfile() *schema.Resource { Type: schema.TypeString, Optional: true, }, + "multivalued": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, "enabled_when_scope": { Type: schema.TypeSet, Optional: true, @@ -134,6 +139,7 @@ func getRealmUserProfileAttributeFromData(m map[string]interface{}) *keycloak.Re Name: m["name"].(string), DisplayName: m["display_name"].(string), Group: m["group"].(string), + Multivalued: m["multivalued"].(bool), } if v, ok := m["permissions"]; ok && len(v.([]interface{})) > 0 { @@ -303,6 +309,7 @@ func getRealmUserProfileAttributeData(attr *keycloak.RealmUserProfileAttribute) attributeData["display_name"] = attr.DisplayName attributeData["group"] = attr.Group + attributeData["multivalued"] = attr.Multivalued if attr.Selector != nil && len(attr.Selector.Scopes) != 0 { attributeData["enabled_when_scope"] = attr.Selector.Scopes } diff --git a/provider/resource_keycloak_realm_user_profile_test.go b/provider/resource_keycloak_realm_user_profile_test.go index 116e39dd3..81b990546 100644 --- a/provider/resource_keycloak_realm_user_profile_test.go +++ b/provider/resource_keycloak_realm_user_profile_test.go @@ -81,6 +81,7 @@ func TestAccKeycloakRealmUserProfile_basicFull(t *testing.T) { "foo": "\"bar\"", "inputOptionLabels": "{\"a\":\"b\"}", }, + Multivalued: true, }, }, Groups: []*keycloak.RealmUserProfileGroup{ From 2090b465b835fcba89cca0f6e5d9914efc1aff69 Mon Sep 17 00:00:00 2001 From: Laureat Grepi Date: Mon, 30 Sep 2024 11:10:42 +0200 Subject: [PATCH 07/12] fmt Signed-off-by: Laureat Grepi --- keycloak/realm_user_profile.go | 2 +- provider/resource_keycloak_realm_user_profile.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/keycloak/realm_user_profile.go b/keycloak/realm_user_profile.go index f67732907..82d67c66d 100644 --- a/keycloak/realm_user_profile.go +++ b/keycloak/realm_user_profile.go @@ -31,7 +31,7 @@ type RealmUserProfileAttribute struct { Required *RealmUserProfileRequired `json:"required,omitempty"` Selector *RealmUserProfileSelector `json:"selector,omitempty"` Validations map[string]RealmUserProfileValidationConfig `json:"validations,omitempty"` - Multivalued bool `json:"multivalued"` + Multivalued bool `json:"multivalued"` } type RealmUserProfileGroup struct { diff --git a/provider/resource_keycloak_realm_user_profile.go b/provider/resource_keycloak_realm_user_profile.go index aa51a084b..2efcb529e 100644 --- a/provider/resource_keycloak_realm_user_profile.go +++ b/provider/resource_keycloak_realm_user_profile.go @@ -42,7 +42,7 @@ func resourceKeycloakRealmUserProfile() *schema.Resource { "multivalued": { Type: schema.TypeBool, Optional: true, - Default: false, + Default: false, }, "enabled_when_scope": { Type: schema.TypeSet, From 930d7cf171e6bcdc16f05e68eccfc30c1dc18070 Mon Sep 17 00:00:00 2001 From: Laureat Grepi Date: Mon, 30 Sep 2024 12:09:04 +0200 Subject: [PATCH 08/12] remove default value Signed-off-by: Laureat Grepi --- keycloak/realm_user_profile.go | 2 +- provider/resource_keycloak_realm_user_profile.go | 1 - provider/resource_keycloak_realm_user_profile_test.go | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/keycloak/realm_user_profile.go b/keycloak/realm_user_profile.go index 82d67c66d..4df848547 100644 --- a/keycloak/realm_user_profile.go +++ b/keycloak/realm_user_profile.go @@ -31,7 +31,7 @@ type RealmUserProfileAttribute struct { Required *RealmUserProfileRequired `json:"required,omitempty"` Selector *RealmUserProfileSelector `json:"selector,omitempty"` Validations map[string]RealmUserProfileValidationConfig `json:"validations,omitempty"` - Multivalued bool `json:"multivalued"` + Multivalued bool `json:"multivalued,omitempty"` } type RealmUserProfileGroup struct { diff --git a/provider/resource_keycloak_realm_user_profile.go b/provider/resource_keycloak_realm_user_profile.go index 2efcb529e..463b49c22 100644 --- a/provider/resource_keycloak_realm_user_profile.go +++ b/provider/resource_keycloak_realm_user_profile.go @@ -42,7 +42,6 @@ func resourceKeycloakRealmUserProfile() *schema.Resource { "multivalued": { Type: schema.TypeBool, Optional: true, - Default: false, }, "enabled_when_scope": { Type: schema.TypeSet, diff --git a/provider/resource_keycloak_realm_user_profile_test.go b/provider/resource_keycloak_realm_user_profile_test.go index 81b990546..116e39dd3 100644 --- a/provider/resource_keycloak_realm_user_profile_test.go +++ b/provider/resource_keycloak_realm_user_profile_test.go @@ -81,7 +81,6 @@ func TestAccKeycloakRealmUserProfile_basicFull(t *testing.T) { "foo": "\"bar\"", "inputOptionLabels": "{\"a\":\"b\"}", }, - Multivalued: true, }, }, Groups: []*keycloak.RealmUserProfileGroup{ From ced6c9142667b9a32f81d5a2c1668c02baa46a2d Mon Sep 17 00:00:00 2001 From: Michael Parker Date: Mon, 11 Nov 2024 00:53:15 -0600 Subject: [PATCH 09/12] Update license for project to Apache 2.0 (#1002) Signed-off-by: Laureat Grepi --- LICENSE-MIT | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 LICENSE-MIT diff --git a/LICENSE-MIT b/LICENSE-MIT deleted file mode 100644 index 3b74241e9..000000000 --- a/LICENSE-MIT +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018-2024 Michael Parker - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. From babe676d1ddf6a3d1be4d5b9a27c28ec8c6618a0 Mon Sep 17 00:00:00 2001 From: Sebastian Schuster Date: Fri, 15 Nov 2024 16:19:09 +0100 Subject: [PATCH 10/12] Initial README.md update and adding MAINTAINERS.md after repository owner change (#1014) Signed-off-by: Sebastian Schuster Signed-off-by: Laureat Grepi --- MAINTAINERS.md | 9 +++++++++ README.md | 8 ++++++++ 2 files changed, 17 insertions(+) create mode 100644 MAINTAINERS.md diff --git a/MAINTAINERS.md b/MAINTAINERS.md new file mode 100644 index 000000000..9a9b96e1c --- /dev/null +++ b/MAINTAINERS.md @@ -0,0 +1,9 @@ +# Active maintainers + +* [Sebastian Schuster](https://github.com/sschu) +* [Thomas Darimont](https://github.com/thomasdarimont) + +# Emeritus maintainers + +* [Michael Parker](https://github.com/mrparkers) + diff --git a/README.md b/README.md index 808748514..a357023b6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # terraform-provider-keycloak Terraform provider for [Keycloak](https://www.keycloak.org/). +[!NOTE] +Please note that this is currently work-in-progress, please be patient while we are preparing for the first release in the new organization. + ## Docs All documentation for this provider can now be found on the Terraform Registry: https://registry.terraform.io/providers/mrparkers/keycloak/latest/docs @@ -92,6 +95,11 @@ KEYCLOAK_URL="http://localhost:8080" \ make testacc ``` +## Acknowledgments + +The Keycloak Terraform Provider was originally created by [Michael Parker](https://github.com/mrparkers). Many thanks for the hard work and dedication in building the foundation for this project. +Also, many thanks to all the contributors extending it and approving the license change to maintain it as part of the [Keycloak](https://www.keycloak.org/) project. + ## License This software is licensed under either of the following, at your option: From d90fbfc7f5582d0c79a914cf2f8a79e3a63f138e Mon Sep 17 00:00:00 2001 From: Sebastian Schuster Date: Fri, 15 Nov 2024 17:09:49 +0100 Subject: [PATCH 11/12] Fix README.md nite (#1015) Signed-off-by: Sebastian Schuster Signed-off-by: Laureat Grepi --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a357023b6..abb2ca54d 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # terraform-provider-keycloak Terraform provider for [Keycloak](https://www.keycloak.org/). -[!NOTE] -Please note that this is currently work-in-progress, please be patient while we are preparing for the first release in the new organization. +> [!NOTE] +> Please note that this is currently work-in-progress, please be patient while we are preparing for the first release in the new organization. ## Docs From 14cfdd698e92561126135f7256725fae24e1f85e Mon Sep 17 00:00:00 2001 From: Michael Parker Date: Mon, 11 Nov 2024 00:53:15 -0600 Subject: [PATCH 12/12] Update license for project to Apache 2.0 (#1002) --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index abb2ca54d..37614e6df 100644 --- a/README.md +++ b/README.md @@ -102,9 +102,6 @@ Also, many thanks to all the contributors extending it and approving the license ## License -This software is licensed under either of the following, at your option: +This software is licensed under Apache License, Version 2.0, (LICENSE-APACHE-2.0 or https://www.apache.org/licenses/LICENSE-2.0) -- Apache License, Version 2.0, (LICENSE-APACHE-2.0 or https://www.apache.org/licenses/LICENSE-2.0) -- MIT License (LICENSE-MIT or https://opensource.org/licenses/MIT) - -Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this software by you shall be dual licensed under the MIT License and Apache License, Version 2.0, without any additional terms or conditions. +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this software by you shall be licensed under the Apache License, Version 2.0, without any additional terms or conditions.