diff --git a/.dockerignore b/.dockerignore index 31b16d2aab..ec905b5eb8 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,2 @@ -.github/ -.gitpod.yml bin/ tmp/ diff --git a/.editorconfig b/.editorconfig index 27917441d8..085f9d0e31 100644 --- a/.editorconfig +++ b/.editorconfig @@ -19,3 +19,6 @@ indent_style = tab [{config.yaml.dist,config.dev.yaml}] indent_size = 2 + +[.golangci.yaml] +indent_size = 2 diff --git a/.envrc b/.envrc index 5817bffc67..fb06536f72 100644 --- a/.envrc +++ b/.envrc @@ -1,6 +1,6 @@ -if ! has nix_direnv_version || ! nix_direnv_version 1.5.0; then - source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/1.5.0/direnvrc" "sha256-carKk9aUFHMuHt+IWh74hFj58nY4K3uywpZbwXX0BTI=" +if ! has nix_direnv_version || ! nix_direnv_version 3.0.6; then + source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.6/direnvrc" "sha256-RYcUJaRMf8oF5LznDrlCXbkOQrywm0HDv1VjYGaJGdM=" fi -use flake +use flake . --impure dotenv_if_exists diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 64156bfa7a..7b8f9b7e2e 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1,9 @@ blank_issues_enabled: false contact_links: + - name: 📖 Documentation enhancement + url: https://github.com/dexidp/website/issues + about: Suggest an improvement to the documentation + - name: ❓ Ask a question url: https://github.com/dexidp/dex/discussions/new?category=q-a about: Ask and discuss questions with other Dex community members @@ -13,5 +17,5 @@ contact_links: about: Please ask and answer questions here - name: 💡 Dex Enhancement Proposal - url: https://github.com/dexidp/dex/tree/master/enhancements/README.md + url: https://github.com/dexidp/dex/tree/master/docs/enhancements/README.md about: Open a proposal for significant architectural change diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index bcaee00ae3..a706b551a1 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -21,15 +21,3 @@ Thank you for sending a pull request! Here are some tips for contributors: --> #### Special notes for your reviewer - -#### Does this PR introduce a user-facing change? - - - -```release-note - -``` diff --git a/.github/SECURITY.md b/.github/SECURITY.md index 9decd34e3e..eab38858be 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -11,10 +11,10 @@ to confirm receipt of the issue. ## Review Process Once a maintainer has confirmed the relevance of the report, a draft security -advisory will be created on Github. The draft advisory will be used to discuss +advisory will be created on GitHub. The draft advisory will be used to discuss the issue with maintainers, the reporter(s). If the reporter(s) wishes to participate in this discussion, then provide -reporter Github username(s) to be invited to the discussion. If the reporter(s) +reporter GitHub username(s) to be invited to the discussion. If the reporter(s) does not wish to participate directly in the discussion, then the reporter(s) can request to be updated regularly via email. diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index b3129d93cf..f66cc18740 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -7,6 +7,10 @@ updates: - "area/dependencies" schedule: interval: "daily" + groups: + etcd: + patterns: + - "go.etcd.io/*" - package-ecosystem: "gomod" directory: "/api/v2" @@ -15,6 +19,13 @@ updates: schedule: interval: "daily" + - package-ecosystem: "gomod" + directory: "/examples" + labels: + - "area/dependencies" + schedule: + interval: "daily" + - package-ecosystem: "docker" directory: "/" labels: diff --git a/.github/workflows/analysis-scorecard.yaml b/.github/workflows/analysis-scorecard.yaml new file mode 100644 index 0000000000..5031899ebd --- /dev/null +++ b/.github/workflows/analysis-scorecard.yaml @@ -0,0 +1,47 @@ +name: OpenSSF Scorecard + +on: + branch_protection_rule: + push: + branches: [ main ] + schedule: + - cron: '30 0 * * 5' + +permissions: + contents: read + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + permissions: + actions: read + contents: read + id-token: write + security-events: write + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: Run analysis + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 + with: + results_file: results.sarif + results_format: sarif + publish_results: true + + - name: Upload results as artifact + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + with: + name: OpenSSF Scorecard results + path: results.sarif + retention-days: 5 + + - name: Upload results to GitHub Security tab + uses: github/codeql-action/upload-sarif@014f16e7ab1402f30e7c3329d33797e7948572db # v3.29.5 + with: + sarif_file: results.sarif diff --git a/.github/workflows/artifacts.yaml b/.github/workflows/artifacts.yaml index 0237b3ac66..a464cd1767 100644 --- a/.github/workflows/artifacts.yaml +++ b/.github/workflows/artifacts.yaml @@ -1,12 +1,31 @@ name: Artifacts on: - push: - branches: - - master - tags: - - v[0-9]+.[0-9]+.[0-9]+ - pull_request: + workflow_call: + inputs: + publish: + description: Publish artifacts to the artifact store + default: false + required: false + type: boolean + secrets: + DOCKER_USERNAME: + required: true + DOCKER_PASSWORD: + required: true + outputs: + container-image-name: + description: Container image name + value: ${{ jobs.container-images.outputs.name }} + container-image-digest: + description: Container image digest + value: ${{ jobs.container-images.outputs.digest }} + container-image-ref: + description: Container image ref + value: ${{ jobs.container-images.outputs.ref }} + +permissions: + contents: read jobs: container-images: @@ -18,62 +37,90 @@ jobs: - alpine - distroless + permissions: + attestations: write + contents: read + packages: write + id-token: write + security-events: write + + outputs: + name: ${{ steps.image-name.outputs.value }} + digest: ${{ steps.build.outputs.digest }} + ref: ${{ steps.image-ref.outputs.value }} + steps: - - name: Checkout - uses: actions/checkout@v3 + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Set up QEMU + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Set up Syft + uses: anchore/sbom-action/download-syft@8e94d75ddd33f69f691467e42275782e4bfefe84 # v0.20.9 - - name: Gather metadata + - name: Install cosign + uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0 + + - name: Set image name + id: image-name + run: echo "value=ghcr.io/${{ github.repository }}" >> "$GITHUB_OUTPUT" + + - name: Gather build metadata id: meta - uses: docker/metadata-action@v4 + uses: docker/metadata-action@318604b99e75e41977312d83839a89be02ca4893 # v5.9.0 with: images: | - ghcr.io/dexidp/dex - dexidp/dex + ${{ steps.image-name.outputs.value }} + ${{ github.repository == 'dexidp/dex' && 'dexidp/dex' || '' }} flavor: | latest = false tags: | type=ref,event=branch,enable=${{ matrix.variant == 'alpine' }} - type=ref,event=pr,enable=${{ matrix.variant == 'alpine' }} + type=ref,event=pr,prefix=pr-,enable=${{ matrix.variant == 'alpine' }} type=semver,pattern={{raw}},enable=${{ matrix.variant == 'alpine' }} - type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && matrix.variant == 'alpine' }} + type=raw,value=latest,enable=${{ github.ref_name == github.event.repository.default_branch && matrix.variant == 'alpine' }} type=ref,event=branch,suffix=-${{ matrix.variant }} - type=ref,event=pr,suffix=-${{ matrix.variant }} + type=ref,event=pr,prefix=pr-,suffix=-${{ matrix.variant }} type=semver,pattern={{raw}},suffix=-${{ matrix.variant }} - type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }},suffix=-${{ matrix.variant }} + type=raw,value=latest,enable={{is_default_branch}},suffix=-${{ matrix.variant }} labels: | org.opencontainers.image.documentation=https://dexidp.io/docs/ - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 + # Multiple exporters are not supported yet + # See https://github.com/moby/buildkit/pull/2760 + - name: Determine build output + uses: haya14busa/action-cond@94f77f7a80cd666cb3155084e428254fea4281fd # v1.2.1 + id: build-output with: - platforms: all - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + cond: ${{ inputs.publish }} + if_true: type=image,push=true + if_false: type=oci,dest=image.tar - name: Login to GitHub Container Registry - uses: docker/login-action@v2 + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 with: registry: ghcr.io - username: ${{ github.repository_owner }} + username: ${{ github.actor }} password: ${{ github.token }} - if: github.event_name == 'push' + if: inputs.publish - name: Login to Docker Hub - uses: docker/login-action@v2 + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - if: github.event_name == 'push' + if: inputs.publish - - name: Build and push - uses: docker/build-push-action@v3 + - name: Build and push image + id: build + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: . - platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le - # cache-from: type=gha - # cache-to: type=gha,mode=max - push: ${{ github.event_name == 'push' }} + platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x tags: ${{ steps.meta.outputs.tags }} build-args: | BASE_IMAGE=${{ matrix.variant }} @@ -81,17 +128,111 @@ jobs: COMMIT_HASH=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }} BUILD_DATE=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }} labels: ${{ steps.meta.outputs.labels }} + # cache-from: type=gha + # cache-to: type=gha,mode=max + outputs: ${{ steps.build-output.outputs.value }} + # push: ${{ inputs.publish }} + + - name: Sign the images with GitHub OIDC Token + run: | + cosign sign --yes ${{ steps.image-name.outputs.value }}@${{ steps.build.outputs.digest }} + if: inputs.publish + + - name: Set image ref + id: image-ref + run: echo "value=${{ steps.image-name.outputs.value }}@${{ steps.build.outputs.digest }}" >> "$GITHUB_OUTPUT" + + - name: Fetch image + run: skopeo --insecure-policy copy docker://${{ steps.image-ref.outputs.value }} oci-archive:image.tar + if: inputs.publish + + # Uncomment the following lines for debugging: + # - name: Upload image as artifact + # uses: actions/upload-artifact@v3 + # with: + # name: "[${{ github.job }}] OCI tarball" + # path: image.tar + + - name: Extract OCI tarball + run: | + mkdir -p image + tar -xf image.tar -C image + + # - name: List tags + # run: skopeo --insecure-policy list-tags oci:image + # + # # See https://github.com/anchore/syft/issues/1545 + # - name: Extract image from multi-arch image + # run: skopeo --override-os linux --override-arch amd64 --insecure-policy copy oci:image:${{ steps.image-name.outputs.value }}:${{ steps.meta.outputs.version }} docker-archive:docker.tar + # + # - name: Generate SBOM + # run: syft -o spdx-json=sbom-spdx.json docker-archive:docker.tar + # + # - name: Upload SBOM as artifact + # uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + # with: + # name: "[${{ github.job }}] SBOM" + # path: sbom-spdx.json + # retention-days: 5 + + # TODO: uncomment when the action is working for non ghcr.io pushes. GH Issue: https://github.com/actions/attest-build-provenance/issues/80 + # - name: Generate build provenance attestation + # uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0 + # with: + # subject-name: dexidp/dex + # subject-digest: ${{ steps.build.outputs.digest }} + # push-to-registry: true + + - name: Generate build provenance attestation + uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0 + with: + subject-name: ghcr.io/${{ github.repository }} + subject-digest: ${{ steps.build.outputs.digest }} + push-to-registry: true + if: inputs.publish + + ## Use cache for the trivy-db to avoid the TOOMANYREQUESTS error https://github.com/aquasecurity/trivy-action/pull/397 + ## To avoid the trivy-db becoming outdated, we save the cache for one day + - name: Get data + id: date + run: echo "date=$(date +%Y-%m-%d)" >> $GITHUB_OUTPUT + + - name: Restore trivy cache + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + with: + path: cache/db + key: trivy-cache-${{ steps.date.outputs.date }} + restore-keys: trivy-cache- - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@0.7.1 + uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # 0.33.1 + with: + input: image + format: sarif + output: trivy-results.sarif + scan-type: "fs" + scan-ref: "." + cache-dir: "./cache" + # Disable skipping trivy cache for now + # env: + # TRIVY_SKIP_DB_UPDATE: true + # TRIVY_SKIP_JAVA_DB_UPDATE: true + + ## Trivy-db uses `0600` permissions. + ## But `action/cache` use `runner` user by default + ## So we need to change the permissions before caching the database. + - name: change permissions for trivy.db + run: sudo chmod 0644 ./cache/db/trivy.db + + - name: Upload Trivy scan results as artifact + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: - image-ref: "ghcr.io/dexidp/dex:${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }}" - format: "sarif" - output: "trivy-results.sarif" - if: github.event_name == 'push' + name: "[${{ github.job }}] Trivy scan results" + path: trivy-results.sarif + retention-days: 5 + overwrite: true - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v2 + uses: github/codeql-action/upload-sarif@014f16e7ab1402f30e7c3329d33797e7948572db # v3.29.5 with: - sarif_file: "trivy-results.sarif" - if: github.event_name == 'push' + sarif_file: trivy-results.sarif diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index c7eb4ea73c..feb7cf38f6 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -4,14 +4,19 @@ on: pull_request: types: [opened, labeled, unlabeled, synchronize] +permissions: + contents: read + jobs: release-label: name: Release note label runs-on: ubuntu-latest + if: github.repository == 'dexidp/dex' + steps: - name: Check minimum labels - uses: mheap/github-action-required-labels@v2 + uses: mheap/github-action-required-labels@8afbe8ae6ab7647d0c9f0cfa7c2f939650d22509 # v5.5 with: mode: minimum count: 1 diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 192a44046e..201ca36443 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -2,26 +2,30 @@ name: CI on: push: - branches: - - master + branches: [master] pull_request: +permissions: + contents: read + jobs: - build: - name: Build + test: + name: Test runs-on: ubuntu-latest - env: - GOFLAGS: -mod=readonly services: postgres: image: postgres:10.8 + env: + TZ: UTC ports: - 5432 options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 postgres-ent: image: postgres:10.8 + env: + TZ: UTC ports: - 5432 options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 @@ -61,25 +65,31 @@ jobs: options: --health-cmd "curl --fail http://localhost:5000/v3" --health-interval 10s --health-timeout 5s --health-retries 5 steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 with: - go-version: 1.18 + go-version: "1.25" - - name: Checkout code - uses: actions/checkout@v3 + - name: Download tool dependencies + run: make deps + + # Ensure that generated files were committed. + # It can help us determine, that the code is in the intermediate state, which should not be tested. + # Thus, heavy jobs like creating a kind cluster and testing / linting will be skipped. + - name: Verify + run: make verify - name: Start services - run: docker-compose -f docker-compose.test.yaml up -d + run: docker compose -f docker-compose.test.yaml up -d - name: Create kind cluster - uses: helm/kind-action@v1.3.0 + uses: helm/kind-action@92086f6be054225fa813e0a4b13787fc9088faab # v1.13.0 with: - version: v0.11.1 - node_image: kindest/node:v1.19.11@sha256:07db187ae84b4b7de440a73886f008cf903fcf5764ba8106a9fd5243d6f32729 - - - name: Download tool dependencies - run: make deps + version: "v0.17.0" + node_image: "kindest/node:v1.25.3@sha256:cd248d1438192f7814fbca8fede13cfe5b9918746dfa12583976158a834fd5c5" - name: Test run: make testall @@ -111,8 +121,8 @@ jobs: DEX_ETCD_ENDPOINTS: http://localhost:${{ job.services.etcd.ports[2379] }} DEX_LDAP_HOST: localhost - DEX_LDAP_PORT: 389 - DEX_LDAP_TLS_PORT: 636 + DEX_LDAP_PORT: 3890 + DEX_LDAP_TLS_PORT: 6360 DEX_KEYSTONE_URL: http://localhost:${{ job.services.keystone.ports[5000] }} DEX_KEYSTONE_ADMIN_URL: http://localhost:${{ job.services.keystone.ports[35357] }} @@ -121,9 +131,48 @@ jobs: DEX_KUBERNETES_CONFIG_PATH: ~/.kube/config + lint: + name: Lint + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Set up Go + uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + with: + go-version: "1.25" + + - name: Download golangci-lint + run: make bin/golangci-lint + - name: Lint run: make lint - # Ensure proto generation doesn't depend on external packages. - - name: Verify proto - run: make verify-proto + artifacts: + name: Artifacts + uses: ./.github/workflows/artifacts.yaml + with: + publish: ${{ github.event_name == 'push' }} + secrets: + DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} + permissions: + attestations: write + contents: read + packages: write + id-token: write + security-events: write + + dependency-review: + name: Dependency review + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Dependency Review + uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2 diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml deleted file mode 100644 index 926f8be539..0000000000 --- a/.github/workflows/codeql-analysis.yaml +++ /dev/null @@ -1,67 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: [ master, v1 ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ master ] - schedule: - - cron: '28 10 * * 6' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - language: [ 'go' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] - # Learn more: - # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - 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. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - - # 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@v2 - - # â„šī¸ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml deleted file mode 100644 index f841d55640..0000000000 --- a/.github/workflows/docker.yaml +++ /dev/null @@ -1,111 +0,0 @@ -name: Docker - -on: - # push: - # branches: - # - master - # tags: - # - v[0-9]+.[0-9]+.[0-9]+ - pull_request: - -jobs: - docker: - name: Docker - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Calculate Docker image tags - id: tags - env: - DOCKER_IMAGES: "ghcr.io/dexidp/dex dexidp/dex" - run: | - case $GITHUB_REF in - refs/tags/*) VERSION=${GITHUB_REF#refs/tags/};; - refs/heads/*) VERSION=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g');; - refs/pull/*) VERSION=pr-${{ github.event.number }};; - *) VERSION=sha-${GITHUB_SHA::8};; - esac - - TAGS=() - for image in $DOCKER_IMAGES; do - TAGS+=("${image}:${VERSION}") - - if [[ "${{ github.event.repository.default_branch }}" == "$VERSION" ]]; then - TAGS+=("${image}:latest") - fi - done - - echo ::set-output name=version::${VERSION} - echo ::set-output name=tags::$(IFS=,; echo "${TAGS[*]}") - echo ::set-output name=commit_hash::${GITHUB_SHA::8} - echo ::set-output name=build_date::$(git show -s --format=%cI) - - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - with: - platforms: all - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - with: - install: true - version: latest - # TODO: Remove driver-opts once fix is released docker/buildx#386 - driver-opts: image=moby/buildkit:master - - - name: Login to GitHub Container Registry - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ github.token }} - if: github.event_name == 'push' - - - name: Login to Docker Hub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - if: github.event_name == 'push' - - - name: Build and push - uses: docker/build-push-action@v3 - with: - context: . - platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le - # cache-from: type=gha - # cache-to: type=gha,mode=max - push: ${{ github.event_name == 'push' }} - tags: ${{ steps.tags.outputs.tags }} - build-args: | - VERSION=${{ steps.tags.outputs.version }} - COMMIT_HASH=${{ steps.tags.outputs.commit_hash }} - BUILD_DATE=${{ steps.tags.outputs.build_date }} - labels: | - org.opencontainers.image.title=${{ github.event.repository.name }} - org.opencontainers.image.description=${{ github.event.repository.description }} - org.opencontainers.image.url=${{ github.event.repository.html_url }} - org.opencontainers.image.source=${{ github.event.repository.clone_url }} - org.opencontainers.image.version=${{ steps.tags.outputs.version }} - org.opencontainers.image.created=${{ steps.tags.outputs.build_date }} - org.opencontainers.image.revision=${{ github.sha }} - org.opencontainers.image.licenses=${{ github.event.repository.license.spdx_id }} - org.opencontainers.image.documentation=https://dexidp.io/docs/ - - - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@0.7.1 - with: - image-ref: "ghcr.io/dexidp/dex:${{ steps.tags.outputs.version }}" - format: "template" - template: "@/contrib/sarif.tpl" - output: "trivy-results.sarif" - if: github.event_name == 'push' - - - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v2 - with: - sarif_file: "trivy-results.sarif" - if: github.event_name == 'push' diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000000..dbf397cbbe --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,24 @@ +name: Release + +on: + push: + tags: [ "v[0-9]+.[0-9]+.[0-9]+" ] + +permissions: + contents: read + +jobs: + artifacts: + name: Artifacts + uses: ./.github/workflows/artifacts.yaml + with: + publish: true + secrets: + DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} + permissions: + attestations: write + contents: read + packages: write + id-token: write + security-events: write diff --git a/.github/workflows/trivydb-cache.yaml b/.github/workflows/trivydb-cache.yaml new file mode 100644 index 0000000000..f66f29e858 --- /dev/null +++ b/.github/workflows/trivydb-cache.yaml @@ -0,0 +1,39 @@ +# Note: This workflow only updates the cache. You should create a separate workflow for your actual Trivy scans. +# In your scan workflow, set TRIVY_SKIP_DB_UPDATE=true and TRIVY_SKIP_JAVA_DB_UPDATE=true. +name: Update Trivy Cache + +on: + schedule: + - cron: '0 0 * * *' # Run daily at midnight UTC + workflow_dispatch: # Allow manual triggering + +jobs: + update-trivy-db: + runs-on: ubuntu-latest + steps: + - name: Setup oras + uses: oras-project/setup-oras@22ce207df3b08e061f537244349aac6ae1d214f6 # v1.2.4 + + - name: Get current date + id: date + run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT + + - name: Download and extract the vulnerability DB + run: | + mkdir -p $GITHUB_WORKSPACE/.cache/trivy/db + oras pull ghcr.io/aquasecurity/trivy-db:2 + tar -xzf db.tar.gz -C $GITHUB_WORKSPACE/.cache/trivy/db + rm db.tar.gz + + - name: Download and extract the Java DB + run: | + mkdir -p $GITHUB_WORKSPACE/.cache/trivy/java-db + oras pull ghcr.io/aquasecurity/trivy-java-db:1 + tar -xzf javadb.tar.gz -C $GITHUB_WORKSPACE/.cache/trivy/java-db + rm javadb.tar.gz + + - name: Cache DBs + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + with: + path: ${{ github.workspace }}/.cache/trivy + key: cache-trivy-${{ steps.date.outputs.date }} diff --git a/.gitignore b/.gitignore index 66dc41ccfe..11cfbe81a6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/.devenv/ /.direnv/ /.idea/ /bin/ diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 0000000000..9fa3141874 --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,124 @@ +version: "2" + +run: + timeout: 5m + +linters: + disable: + - staticcheck + - errcheck + enable: + - depguard + - dogsled + - exhaustive + - gochecknoinits + # - gocritic + - goprintffuncname + - govet + - ineffassign + - misspell + - nakedret + - nolintlint + - prealloc + # - revive + # - sqlclosecheck + # - staticcheck + - unconvert + - unused + - whitespace + + # Disable temporarily until everything works with Go 1.20 + # - bodyclose + # - rowserrcheck + # - tparallel + # - unparam + + # Disable temporarily until the following issue is resolved: https://github.com/golangci/golangci-lint/issues/3086 + # - sqlclosecheck + + # TODO: fix linter errors before enabling + # - exhaustivestruct + # - gochecknoglobals + # - errorlint + # - gocognit + # - godot + # - nlreturn + # - noctx + # - revive + # - wrapcheck + + # TODO: fix linter errors before enabling (from original config) + # - dupl + # - errcheck + # - goconst + # - gocyclo + # - gosec + # - lll + # - scopelint + + # unused + # - goheader + # - gomodguard + + # don't enable: + # - asciicheck + # - funlen + # - godox + # - goerr113 + # - gomnd + # - interfacer + # - maligned + # - nestif + # - testpackage + # - wsl + + exclusions: + rules: + - linters: + - errcheck + - noctx + path: _test.go + presets: + - comments + - std-error-handling + + settings: + misspell: + locale: US + nolintlint: + allow-unused: false # report any unused nolint directives + require-specific: false # don't require nolint directives to be specific about which linter is being skipped + gocritic: + # Enable multiple checks by tags. See "Tags" section in https://github.com/go-critic/go-critic#usage. + enabled-tags: + - diagnostic + - experimental + - opinionated + - style + disabled-checks: + - importShadow + - unnamedResult + depguard: + rules: + deprecated: + deny: + - pkg: "io/ioutil" + desc: "The 'io/ioutil' package is deprecated. Use corresponding 'os' or 'io' functions instead." + +formatters: + enable: + - gci + - gofmt + - gofumpt + - goimports + # - golines + + settings: + gci: + sections: + - standard + - default + - localmodule +# issues: +# exclude-dirs: +# - storage/ent/db # generated ent code diff --git a/.golangci.yml b/.golangci.yml deleted file mode 100644 index cfb64a75bf..0000000000 --- a/.golangci.yml +++ /dev/null @@ -1,90 +0,0 @@ -run: - timeout: 4m - -linters-settings: - depguard: - list-type: blacklist - include-go-root: true - packages: - - io/ioutil - packages-with-error-message: - - io/ioutil: "The 'io/ioutil' package is deprecated. Use corresponding 'os' or 'io' functions instead." - gci: - local-prefixes: github.com/dexidp/dex - goimports: - local-prefixes: github.com/dexidp/dex - - -linters: - disable-all: true - enable: - - bodyclose - - deadcode - - depguard - - dogsled - - exhaustive - - exportloopref - - gci - - gochecknoinits - - gocritic - - gofmt - - gofumpt - - goimports - - goprintffuncname - - gosimple - - govet - - ineffassign - - misspell - - nakedret - - nolintlint - - prealloc - - revive - - rowserrcheck - - sqlclosecheck - - staticcheck - - structcheck - - stylecheck - - tparallel - - unconvert - - unparam - - unused - - varcheck - - whitespace - - # Disable temporarily until everything works with Go 1.18 - # - typecheck - - # TODO: fix linter errors before enabling - # - exhaustivestruct - # - gochecknoglobals - # - errorlint - # - gocognit - # - godot - # - nlreturn - # - noctx - # - wrapcheck - - # TODO: fix linter errors before enabling (from original config) - # - dupl - # - errcheck - # - goconst - # - gocyclo - # - gosec - # - lll - # - scopelint - - # unused - # - goheader - # - gomodguard - - # don't enable: - # - asciicheck - # - funlen - # - godox - # - goerr113 - # - gomnd - # - interfacer - # - maligned - # - nestif - # - testpackage - # - wsl diff --git a/ADOPTERS.md b/ADOPTERS.md index 50f9ba988d..88a835cbdd 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -1,15 +1,26 @@ # Adopters -This is a list of production adopters of Dex (in alphabetical order): +This is a list of production adopters of Dex (in alphabetical order). + +# Companies - [Aspect](https://www.aspect.com/) uses Dex for authenticating users across their Kubernetes infrastructure (using Kubernetes OIDC support). - [Banzai Cloud](https://banzaicloud.com) is using Dex for authenticating to its Pipeline control plane and also to authenticate users against provisioned Kubernetes clusters (via Kubernetes OIDC support). -- [Chef](https://chef.io) uses Dex for authenticating users in [Chef Automate](https://automate.chef.io/). The code is Open Source, available at [`github.com/chef/automate`](https://github.com/chef/automate). -- [Elastisys](https://elastisys.com) uses Dex for authentication in their [Compliant Kubernetes](https://compliantkubernetes.io) distribution, including SSO to the custom dashboard, Grafana, Kibana, and Harbor. +- [Ericsson](https://www.ericsson.com) is using Dex to authenticate access to Kubernetes API server in [Cloud Container Distribution](https://www.ericsson.com/en/portfolio/cloud-software-and-services/cloud-core/cloud-infrastructure/nfvi/cloud-container-distribution). - [Flant](https://flant.com) uses Dex for providing access to core components of [Managed Kubernetes as a Service](https://flant.com/services/managed-kubernetes-as-a-service), integration with various authentication providers, plugging custom applications. - [JuliaBox](https://juliabox.com/) is leveraging federated OIDC provided by Dex for authenticating users to their compute infrastructure based on Kubernetes. +- [Pusher](https://pusher.com) uses Dex for authenticating users across their Kubernetes infrastructure (using Kubernetes OIDC support) in conjunction with the [OAuth2 Proxy](https://github.com/pusher/oauth2_proxy) for protecting web UIs. + +# Projects + +- [Argo CD](https://argoproj.github.io/cd) integrates Dex to provide convenient Single Sign On capabilities to its web UI and CLI +- [Chef](https://chef.io) uses Dex for authenticating users in [Chef Automate](https://automate.chef.io/). The code is Open Source, available at [`github.com/chef/automate`](https://github.com/chef/automate). +- [Elastisys](https://elastisys.com) uses Dex for authentication in [Welkin, The Application Platform for Software Critical to Society](https://elastisys.io/welkin/), including SSO to Grafana, OpenSearch, and Harbor. - [Kasten](https://www.kasten.io) is using Dex for authenticating access to the dashboard of [K10](https://www.kasten.io/product/), a Kubernetes-native platform for backup, disaster recovery and mobility of Kubernetes applications. K10 is widely used by a variety of customers including large enterprises, financial services, design firms, and IT companies. +- [Kubeflow](https://www.kubeflow.org/) [uses](https://github.com/kubeflow/manifests#dex) Dex as one of its components in the Kubeflow Platform for external OIDC authentication. - [Kyma](https://kyma-project.io) is using Dex to authenticate access to Kubernetes API server (even for managed Kubernetes like Google Kubernetes Engine or Azure Kubernetes Service) and for protecting web UI of [Kyma Console](https://github.com/kyma-project/console) and other UIs integrated in Kyma ([Grafana](https://github.com/grafana/grafana), [Loki](https://github.com/grafana/loki), and [Jaeger](https://github.com/jaegertracing/jaeger)). Kyma is an open-source project ([`github.com/kyma-project`](https://github.com/kyma-project/kyma)) designed natively on Kubernetes, that allows you to extend and customize your applications in a quick and modern way, using serverless computing or microservice architecture. -- [Pusher](https://pusher.com) uses Dex for authenticating users across their Kubernetes infrastructure (using Kubernetes OIDC support) in conjunction with the [OAuth2 Proxy](https://github.com/pusher/oauth2_proxy) for protecting web UIs. +- [LitmusChaos](https://litmuschaos.io/) uses Dex to [implement](https://docs.litmuschaos.io/docs/user-guides/chaoscenter-oauth-dex-installation#deploy-dex-oidc-provider) OAuth2 login support in ChaosCenter, its centralized chaos management tool. +- [LLMariner](https://llmariner.ai/) uses Dex for [user management](https://llmariner.ai/docs/features/user_management/). - [Pydio](https://pydio.com/) Pydio Cells is an open source sync & share platform written in Go. Cells is using Dex as an OIDC service for authentication and authorizations. Check out [Pydio Cells repository](https://github.com/pydio/cells) for more information and/or to contribute. - [sigstore](https://sigstore.dev) uses Dex for authentication in their public Fulcio instance, which is a certificate authority for code signing certificates bound to OIDC-based identities. +- [Terrakube](https://docs.terrakube.io/) relies on Dex for [user authentication](https://docs.terrakube.io/getting-started/deployment/user-authentication-dex). Its Helm chart uses Dex as a dependency. diff --git a/Dockerfile b/Dockerfile index 3462ae52ac..90376dc7f0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,48 +1,61 @@ ARG BASE_IMAGE=alpine -FROM golang:1.19.1-alpine3.16 AS builder +FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.9.0@sha256:c64defb9ed5a91eacb37f96ccc3d4cd72521c4bd18d5442905b95e2226b0e707 AS xx -WORKDIR /usr/local/src/dex +FROM --platform=$BUILDPLATFORM golang:1.25.5-alpine3.22@sha256:3587db7cc96576822c606d119729370dbf581931c5f43ac6d3fa03ab4ed85a10 AS builder -RUN apk add --no-cache --update alpine-sdk ca-certificates openssl +COPY --from=xx / / -ARG TARGETOS -ARG TARGETARCH -ARG TARGETVARIANT="" +RUN apk add --update alpine-sdk ca-certificates openssl clang lld + +ARG TARGETPLATFORM + +RUN xx-apk --update add musl-dev gcc -ENV GOOS=${TARGETOS} GOARCH=${TARGETARCH} GOARM=${TARGETVARIANT} +# lld has issues building static binaries for ppc so prefer ld for it +RUN [ "$(xx-info arch)" != "ppc64le" ] || XX_CC_PREFER_LINKER=ld xx-clang --setup-target-triple + +RUN xx-go --wrap + +WORKDIR /usr/local/src/dex ARG GOPROXY +ENV CGO_ENABLED=1 + COPY go.mod go.sum ./ COPY api/v2/go.mod api/v2/go.sum ./api/v2/ RUN go mod download COPY . . +# Propagate Dex version from build args to the build environment +ARG VERSION RUN make release-binary -FROM alpine:3.16.2 AS stager +RUN xx-verify /go/bin/dex && xx-verify /go/bin/docker-entrypoint + +FROM alpine:3.23.0@sha256:51183f2cfa6320055da30872f211093f9ff1d3cf06f39a0bdb212314c5dc7375 AS stager RUN mkdir -p /var/dex RUN mkdir -p /etc/dex COPY config.docker.yaml /etc/dex/ -FROM alpine:3.16.2 AS gomplate +FROM alpine:3.23.0@sha256:51183f2cfa6320055da30872f211093f9ff1d3cf06f39a0bdb212314c5dc7375 AS gomplate ARG TARGETOS ARG TARGETARCH ARG TARGETVARIANT -ENV GOMPLATE_VERSION=v3.11.2 +ENV GOMPLATE_VERSION=v4.3.3 RUN wget -O /usr/local/bin/gomplate \ "https://github.com/hairyhenderson/gomplate/releases/download/${GOMPLATE_VERSION}/gomplate_${TARGETOS:-linux}-${TARGETARCH:-amd64}${TARGETVARIANT}" \ && chmod +x /usr/local/bin/gomplate # For Dependabot to detect base image versions -FROM alpine:3.16.2 AS alpine -FROM gcr.io/distroless/static:latest AS distroless +FROM alpine:3.23.0@sha256:51183f2cfa6320055da30872f211093f9ff1d3cf06f39a0bdb212314c5dc7375 AS alpine +FROM gcr.io/distroless/static-debian12:nonroot@sha256:2b7c93f6d6648c11f0e80a48558c8f77885eb0445213b8e69a6a0d7c89fc6ae4 AS distroless FROM $BASE_IMAGE diff --git a/Makefile b/Makefile index 9c55ad2b11..c9a568cbfa 100644 --- a/Makefile +++ b/Makefile @@ -1,42 +1,50 @@ -OS = $(shell uname | tr A-Z a-z) - export PATH := $(abspath bin/protoc/bin/):$(abspath bin/):${PATH} -PROJ=dex -ORG_PATH=github.com/dexidp -REPO_PATH=$(ORG_PATH)/$(PROJ) - -VERSION ?= $(shell ./scripts/git-version) +OS = $(shell uname | tr A-Z a-z) -DOCKER_REPO=quay.io/dexidp/dex -DOCKER_IMAGE=$(DOCKER_REPO):$(VERSION) +user=$(shell id -u -n) +group=$(shell id -g -n) $( shell mkdir -p bin ) -user=$(shell id -u -n) -group=$(shell id -g -n) +PROJ = dex +ORG_PATH = github.com/dexidp +REPO_PATH = $(ORG_PATH)/$(PROJ) +VERSION ?= $(shell ./scripts/git-version) -export GOBIN=$(PWD)/bin +export GOBIN=$(PWD)/bin LD_FLAGS="-w -X main.version=$(VERSION)" # Dependency versions +GOLANGCI_VERSION = 2.4.0 +GOTESTSUM_VERSION ?= 1.12.0 -KIND_NODE_IMAGE = "kindest/node:v1.19.11@sha256:07db187ae84b4b7de440a73886f008cf903fcf5764ba8106a9fd5243d6f32729" -KIND_TMP_DIR = "$(PWD)/bin/test/dex-kind-kubeconfig" +PROTOC_VERSION = 29.3 +PROTOC_GEN_GO_VERSION = 1.36.5 +PROTOC_GEN_GO_GRPC_VERSION = 1.5.1 -.PHONY: generate -generate: - @go generate $(REPO_PATH)/storage/ent/ +KIND_VERSION = 0.22.0 +KIND_NODE_IMAGE = "kindest/node:v1.25.3@sha256:cd248d1438192f7814fbca8fede13cfe5b9918746dfa12583976158a834fd5c5" +KIND_TMP_DIR = "$(PWD)/bin/test/dex-kind-kubeconfig" + + +##@ Build + +build: bin/dex ## Build Dex binaries. -build: generate bin/dex +examples: bin/grpc-client bin/example-app ## Build example app. + +.PHONY: release-binary +release-binary: LD_FLAGS = "-w -X main.version=$(VERSION) -extldflags \"-static\"" +release-binary: ## Build release binaries (used to build a final container image). + @go build -o /go/bin/dex -v -ldflags $(LD_FLAGS) $(REPO_PATH)/cmd/dex + @go build -o /go/bin/docker-entrypoint -v -ldflags $(LD_FLAGS) $(REPO_PATH)/cmd/docker-entrypoint bin/dex: @mkdir -p bin/ @go install -v -ldflags $(LD_FLAGS) $(REPO_PATH)/cmd/dex -examples: bin/grpc-client bin/example-app - bin/grpc-client: @mkdir -p bin/ @cd examples/ && go install -v -ldflags $(LD_FLAGS) $(REPO_PATH)/examples/grpc-client @@ -45,95 +53,29 @@ bin/example-app: @mkdir -p bin/ @cd examples/ && go install -v -ldflags $(LD_FLAGS) $(REPO_PATH)/examples/example-app -.PHONY: release-binary -release-binary: LD_FLAGS = "-w -X main.version=$(VERSION) -extldflags \"-static\"" -release-binary: generate - @go build -o /go/bin/dex -v -ldflags $(LD_FLAGS) $(REPO_PATH)/cmd/dex - @go build -o /go/bin/docker-entrypoint -v -ldflags $(LD_FLAGS) $(REPO_PATH)/cmd/docker-entrypoint -docker-compose.override.yaml: - cp docker-compose.override.yaml.dist docker-compose.override.yaml +##@ Generate -.PHONY: up -up: docker-compose.override.yaml ## Launch the development environment - @ if [ docker-compose.override.yaml -ot docker-compose.override.yaml.dist ]; then diff -u docker-compose.override.yaml docker-compose.override.yaml.dist || (echo "!!! The distributed docker-compose.override.yaml example changed. Please update your file accordingly (or at least touch it). !!!" && false); fi - docker-compose up -d - -.PHONY: down -down: clear ## Destroy the development environment - docker-compose down --volumes --remove-orphans --rmi local - -test: - @go test -v ./... - -testrace: - @go test -v --race ./... - -.PHONY: kind-up kind-down kind-tests -kind-up: - @mkdir -p bin/test - @kind create cluster --image ${KIND_NODE_IMAGE} --kubeconfig ${KIND_TMP_DIR} - -kind-down: - @kind delete cluster - rm ${KIND_TMP_DIR} - -kind-tests: export DEX_KUBERNETES_CONFIG_PATH=${KIND_TMP_DIR} -kind-tests: testall - -.PHONY: lint lint-fix -lint: ## Run linter - golangci-lint run - -.PHONY: fix -fix: ## Fix lint violations - golangci-lint run --fix - -.PHONY: docker-image -docker-image: - @sudo docker build -t $(DOCKER_IMAGE) . - -.PHONY: verify-proto -verify-proto: proto - @./scripts/git-diff - -clean: - @rm -rf bin/ - -testall: testrace - -FORCE: +.PHONY: generate +generate: generate-proto generate-proto-internal generate-ent go-mod-tidy ## Run all generators. -.PHONY: test testrace testall +.PHONY: generate-ent +generate-ent: ## Generate code for database ORM. + @go generate $(REPO_PATH)/storage/ent/ -.PHONY: proto -proto: +.PHONY: generate-proto +generate-proto: ## Generate the Dex client's protobuf code. @protoc --go_out=paths=source_relative:. --go-grpc_out=paths=source_relative:. api/v2/*.proto @protoc --go_out=paths=source_relative:. --go-grpc_out=paths=source_relative:. api/*.proto - #@cp api/v2/*.proto api/ -.PHONY: proto-internal -proto-internal: +.PHONY: generate-proto-internal +generate-proto-internal: ## Generate protobuf code for token encoding. @protoc --go_out=paths=source_relative:. server/internal/*.proto -# Dependency versions -GOLANGCI_VERSION = 1.46.0 -GOTESTSUM_VERSION ?= 1.7.0 -PROTOC_VERSION = 3.15.6 -PROTOC_GEN_GO_VERSION = 1.26.0 -PROTOC_GEN_GO_GRPC_VERSION = 1.1.0 -KIND_VERSION = 0.11.1 - -deps: bin/gotestsum bin/golangci-lint bin/protoc bin/protoc-gen-go bin/protoc-gen-go-grpc bin/kind - -bin/gotestsum: - @mkdir -p bin - curl -L https://github.com/gotestyourself/gotestsum/releases/download/v${GOTESTSUM_VERSION}/gotestsum_${GOTESTSUM_VERSION}_$(shell uname | tr A-Z a-z)_amd64.tar.gz | tar -zOxf - gotestsum > ./bin/gotestsum - @chmod +x ./bin/gotestsum - -bin/golangci-lint: - @mkdir -p bin - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | BINARY=golangci-lint bash -s -- v${GOLANGCI_VERSION} +go-mod-tidy: ## Run go mod tidy for all targets. + @go mod tidy + @cd examples/ && go mod tidy + @cd api/v2/ && go mod tidy bin/protoc: @mkdir -p bin/protoc @@ -156,7 +98,112 @@ bin/protoc-gen-go-grpc: curl -L https://github.com/grpc/grpc-go/releases/download/cmd/protoc-gen-go-grpc/v${PROTOC_GEN_GO_GRPC_VERSION}/protoc-gen-go-grpc.v${PROTOC_GEN_GO_GRPC_VERSION}.$(shell uname | tr A-Z a-z).amd64.tar.gz | tar -zOxf - ./protoc-gen-go-grpc > ./bin/protoc-gen-go-grpc @chmod +x ./bin/protoc-gen-go-grpc +##@ Verify + +verify: generate ## Verify that all the code was generated and committed to repository. + @git diff --exit-code + +.PHONY: verify-proto +verify-proto: generate-proto ## Verify that the Dex client's protobuf code was generated. + @git diff --exit-code + +.PHONY: verify-proto +verify-proto-internal: generate-proto-internal ## Verify internal protobuf code for token encoding was generated. + @git diff --exit-code + +.PHONY: verify-ent +verify-ent: generate-ent ## Verify code for database ORM was generated. + @git diff --exit-code + +.PHONY: verify-go-mod +verify-go-mod: go-mod-tidy ## Check that go.mod and go.sum formatted according to the changes. + @git diff --exit-code + +##@ Test and Lint + +deps: bin/gotestsum bin/golangci-lint bin/protoc bin/protoc-gen-go bin/protoc-gen-go-grpc bin/kind ## Install dev dependencies. + +.PHONY: test testrace testall +test: ## Test go code. + @go test -v ./... + +testrace: ## Test go code and check for possible race conditions. + @go test -v --race ./... + +testall: testrace ## Run all tests for go code. + +.PHONY: lint +lint: ## Run linter. + @golangci-lint version + @golangci-lint run + +.PHONY: fix +fix: ## Fix lint violations. + @golangci-lint version + @golangci-lint fmt + +docker-compose.override.yaml: + cp docker-compose.override.yaml.dist docker-compose.override.yaml + +.PHONY: up +up: docker-compose.override.yaml ## Launch the development environment. + @ if [ docker-compose.override.yaml -ot docker-compose.override.yaml.dist ]; then diff -u docker-compose.override.yaml docker-compose.override.yaml.dist || (echo "!!! The distributed docker-compose.override.yaml example changed. Please update your file accordingly (or at least touch it). !!!" && false); fi + docker-compose up -d + +.PHONY: down +down: clear ## Destroy the development environment. + docker-compose down --volumes --remove-orphans --rmi local + +.PHONY: kind-up kind-down kind-tests +kind-up: ## Create a kind cluster. + @mkdir -p bin/test + @kind create cluster --image ${KIND_NODE_IMAGE} --kubeconfig ${KIND_TMP_DIR} --name dex-tests + +kind-tests: export DEX_KUBERNETES_CONFIG_PATH=${KIND_TMP_DIR} +kind-tests: testall ## Run test on kind cluster (kind cluster must be created). + +kind-down: ## Delete the kind cluster. + @kind delete cluster --name dex-tests + rm ${KIND_TMP_DIR} + +bin/golangci-lint: + @mkdir -p bin + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | BINARY=golangci-lint bash -s -- v${GOLANGCI_VERSION} + +bin/gotestsum: + @mkdir -p bin + curl -L https://github.com/gotestyourself/gotestsum/releases/download/v${GOTESTSUM_VERSION}/gotestsum_${GOTESTSUM_VERSION}_$(shell uname | tr A-Z a-z)_amd64.tar.gz | tar -zOxf - gotestsum > ./bin/gotestsum + @chmod +x ./bin/gotestsum + bin/kind: @mkdir -p bin curl -L https://github.com/kubernetes-sigs/kind/releases/download/v${KIND_VERSION}/kind-$(shell uname | tr A-Z a-z)-amd64 > ./bin/kind @chmod +x ./bin/kind + +##@ Clean +clean: ## Delete all builds and downloaded dependencies. + @rm -rf bin/ + + +FORMATTING_BEGIN_YELLOW = \033[0;33m +FORMATTING_BEGIN_BLUE = \033[36m +FORMATTING_END = \033[0m + +.PHONY: help +help: + @printf -- "${FORMATTING_BEGIN_BLUE}%s${FORMATTING_END}\n" \ + "" \ + " ___ " \ + " / _ \_____ __ " \ + " / // / -_) \ / " \ + " /____/\__/_\_\ " \ + "" \ + "-----------------------" \ + "" + @awk 'BEGIN {\ + FS = ":.*##"; \ + printf "Usage: ${FORMATTING_BEGIN_BLUE}OPTION${FORMATTING_END}= make ${FORMATTING_BEGIN_YELLOW}${FORMATTING_END}\n"\ + } \ + /^[a-zA-Z0-9_-]+:.*?##/ { printf " ${FORMATTING_BEGIN_BLUE}%-46s${FORMATTING_END} %s\n", $$1, $$2 } \ + /^.?.?##~/ { printf " %-46s${FORMATTING_BEGIN_YELLOW}%-46s${FORMATTING_END}\n", "", substr($$1, 6) } \ + /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) diff --git a/README.md b/README.md index 271376d65e..dac886ee4a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # dex - A federated OpenID Connect provider -![GitHub Workflow Status](https://img.shields.io/github/workflow/status/dexidp/dex/CI?style=flat-square) +![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/dexidp/dex/ci.yaml?style=flat-square&branch=master) +[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/dexidp/dex/badge?style=flat-square)](https://api.securityscorecards.dev/projects/github.com/dexidp/dex) [![Go Report Card](https://goreportcard.com/badge/github.com/dexidp/dex?style=flat-square)](https://goreportcard.com/report/github.com/dexidp/dex) [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod&style=flat-square)](https://gitpod.io/#https://github.com/dexidp/dex) @@ -12,7 +13,7 @@ Dex acts as a portal to other identity providers through ["connectors."](#connec ## ID Tokens -ID Tokens are an OAuth2 extension introduced by OpenID Connect and dex's primary feature. ID Tokens are [JSON Web Tokens][jwt-io] (JWTs) signed by dex and returned as part of the OAuth2 response that attest to the end user's identity. An example JWT might look like: +ID Tokens are an OAuth2 extension introduced by OpenID Connect and dex's primary feature. ID Tokens are [JSON Web Tokens][jwt-io] (JWTs) signed by dex and returned as part of the OAuth2 response that attests to the end user's identity. An example JWT might look like: ``` eyJhbGciOiJSUzI1NiIsImtpZCI6IjlkNDQ3NDFmNzczYjkzOGNmNjVkZDMyNjY4NWI4NjE4MGMzMjRkOTkifQ.eyJpc3MiOiJodHRwOi8vMTI3LjAuMC4xOjU1NTYvZGV4Iiwic3ViIjoiQ2djeU16UXlOelE1RWdabmFYUm9kV0kiLCJhdWQiOiJleGFtcGxlLWFwcCIsImV4cCI6MTQ5Mjg4MjA0MiwiaWF0IjoxNDkyNzk1NjQyLCJhdF9oYXNoIjoiYmk5NmdPWFpTaHZsV1l0YWw5RXFpdyIsImVtYWlsIjoiZXJpYy5jaGlhbmdAY29yZW9zLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJncm91cHMiOlsiYWRtaW5zIiwiZGV2ZWxvcGVycyJdLCJuYW1lIjoiRXJpYyBDaGlhbmcifQ.OhROPq_0eP-zsQRjg87KZ4wGkjiQGnTi5QuG877AdJDb3R2ZCOk2Vkf5SdP8cPyb3VMqL32G4hLDayniiv8f1_ZXAde0sKrayfQ10XAXFgZl_P1yilkLdknxn6nbhDRVllpWcB12ki9vmAxklAr0B1C4kr5nI3-BZLrFcUR5sQbxwJj4oW1OuG6jJCNGHXGNTBTNEaM28eD-9nhfBeuBTzzO7BKwPsojjj4C9ogU4JQhGvm_l4yfVi0boSx8c0FX3JsiB0yLa1ZdJVWVl9m90XmbWRSD85pNDQHcWZP9hR6CMgbvGkZsgjG32qeRwUL_eNkNowSBNWLrGNPoON1gMg @@ -49,8 +50,8 @@ For details on how to request or validate an ID Token, see [_"Writing apps that Dex runs natively on top of any Kubernetes cluster using Custom Resource Definitions and can drive API server authentication through the OpenID Connect plugin. Clients, such as the [`kubernetes-dashboard`](https://github.com/kubernetes/dashboard) and `kubectl`, can act on behalf of users who can login to the cluster through any identity provider dex supports. -* More docs for running dex as a Kubernetes authenticator can be found [here](https://dexidp.io/docs/kubernetes/). -* You can find more about companies and projects, which uses dex, [here](./ADOPTERS.md). +* More docs for running dex as a Kubernetes authenticator can be found [here](https://dexidp.io/docs/guides/kubernetes/). +* You can find more about companies and projects which use dex, [here](./ADOPTERS.md). ## Connectors @@ -77,8 +78,8 @@ Dex implements the following connectors: | [Microsoft](https://dexidp.io/docs/connectors/microsoft/) | yes | yes | no | beta | | | [AuthProxy](https://dexidp.io/docs/connectors/authproxy/) | no | yes | no | alpha | Authentication proxies such as Apache2 mod_auth, etc. | | [Bitbucket Cloud](https://dexidp.io/docs/connectors/bitbucketcloud/) | yes | yes | no | alpha | | -| [OpenShift](https://dexidp.io/docs/connectors/openshift/) | no | yes | no | alpha | | -| [Atlassian Crowd](https://dexidp.io/docs/connectors/atlassiancrowd/) | yes | yes | yes * | beta | preferred_username claim must be configured through config | +| [OpenShift](https://dexidp.io/docs/connectors/openshift/) | yes | yes | no | alpha | | +| [Atlassian Crowd](https://dexidp.io/docs/connectors/atlassian-crowd/) | yes | yes | yes * | beta | preferred_username claim must be configured through config | | [Gitea](https://dexidp.io/docs/connectors/gitea/) | yes | no | yes | beta | | | [OpenStack Keystone](https://dexidp.io/docs/connectors/keystone/) | yes | yes | no | alpha | | @@ -95,7 +96,7 @@ All changes or deprecations of connector features will be announced in the [rele * [Getting started](https://dexidp.io/docs/getting-started/) * [Intro to OpenID Connect](https://dexidp.io/docs/openid-connect/) * [Writing apps that use dex][using-dex] -* [What's new in v2](https://dexidp.io/docs/v2/) +* [What's new in v2](https://dexidp.io/docs/archive/v2/) * [Custom scopes, claims, and client features](https://dexidp.io/docs/custom-scopes-claims-clients/) * [Storage options](https://dexidp.io/docs/storage/) * [gRPC API](https://dexidp.io/docs/api/) @@ -120,7 +121,7 @@ Please see our [security policy](.github/SECURITY.md) for details about reportin [scopes]: https://dexidp.io/docs/custom-scopes-claims-clients/#scopes [using-dex]: https://dexidp.io/docs/using-dex/ [jwt-io]: https://jwt.io/ -[kubernetes]: http://kubernetes.io/docs/admin/authentication/#openid-connect-tokens +[kubernetes]: https://kubernetes.io/docs/reference/access-authn-authz/authentication/#openid-connect-tokens [aws-sts]: https://docs.aws.amazon.com/STS/latest/APIReference/Welcome.html [go-oidc]: https://github.com/coreos/go-oidc [issue-1065]: https://github.com/dexidp/dex/issues/1065 @@ -138,6 +139,8 @@ For the best developer experience, install [Nix](https://builtwithnix.org/) and Alternatively, install Go and Docker manually or using a package manager. Install the rest of the dependencies by running `make deps`. +For release process, please read the [release documentation](https://dexidp.io/docs/development/releases/). + ## License The project is licensed under the [Apache License, Version 2.0](LICENSE). diff --git a/api/api.pb.go b/api/api.pb.go index 6d1c2ca82e..702d3758fa 100644 --- a/api/api.pb.go +++ b/api/api.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.15.6 +// protoc-gen-go v1.36.5 +// protoc v5.29.3 // source: api/api.proto package api @@ -11,6 +11,7 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -22,26 +23,23 @@ const ( // Client represents an OAuth2 client. type Client struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Secret string `protobuf:"bytes,2,opt,name=secret,proto3" json:"secret,omitempty"` + RedirectUris []string `protobuf:"bytes,3,rep,name=redirect_uris,json=redirectUris,proto3" json:"redirect_uris,omitempty"` + TrustedPeers []string `protobuf:"bytes,4,rep,name=trusted_peers,json=trustedPeers,proto3" json:"trusted_peers,omitempty"` + Public bool `protobuf:"varint,5,opt,name=public,proto3" json:"public,omitempty"` + Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"` + LogoUrl string `protobuf:"bytes,7,opt,name=logo_url,json=logoUrl,proto3" json:"logo_url,omitempty"` unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Secret string `protobuf:"bytes,2,opt,name=secret,proto3" json:"secret,omitempty"` - RedirectUris []string `protobuf:"bytes,3,rep,name=redirect_uris,json=redirectUris,proto3" json:"redirect_uris,omitempty"` - TrustedPeers []string `protobuf:"bytes,4,rep,name=trusted_peers,json=trustedPeers,proto3" json:"trusted_peers,omitempty"` - Public bool `protobuf:"varint,5,opt,name=public,proto3" json:"public,omitempty"` - Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"` - LogoUrl string `protobuf:"bytes,7,opt,name=logo_url,json=logoUrl,proto3" json:"logo_url,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Client) Reset() { *x = Client{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Client) String() string { @@ -52,7 +50,7 @@ func (*Client) ProtoMessage() {} func (x *Client) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -118,20 +116,17 @@ func (x *Client) GetLogoUrl() string { // CreateClientReq is a request to make a client. type CreateClientReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Client *Client `protobuf:"bytes,1,opt,name=client,proto3" json:"client,omitempty"` unknownFields protoimpl.UnknownFields - - Client *Client `protobuf:"bytes,1,opt,name=client,proto3" json:"client,omitempty"` + sizeCache protoimpl.SizeCache } func (x *CreateClientReq) Reset() { *x = CreateClientReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CreateClientReq) String() string { @@ -142,7 +137,7 @@ func (*CreateClientReq) ProtoMessage() {} func (x *CreateClientReq) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -166,21 +161,18 @@ func (x *CreateClientReq) GetClient() *Client { // CreateClientResp returns the response from creating a client. type CreateClientResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + AlreadyExists bool `protobuf:"varint,1,opt,name=already_exists,json=alreadyExists,proto3" json:"already_exists,omitempty"` + Client *Client `protobuf:"bytes,2,opt,name=client,proto3" json:"client,omitempty"` unknownFields protoimpl.UnknownFields - - AlreadyExists bool `protobuf:"varint,1,opt,name=already_exists,json=alreadyExists,proto3" json:"already_exists,omitempty"` - Client *Client `protobuf:"bytes,2,opt,name=client,proto3" json:"client,omitempty"` + sizeCache protoimpl.SizeCache } func (x *CreateClientResp) Reset() { *x = CreateClientResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CreateClientResp) String() string { @@ -191,7 +183,7 @@ func (*CreateClientResp) ProtoMessage() {} func (x *CreateClientResp) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -222,21 +214,18 @@ func (x *CreateClientResp) GetClient() *Client { // DeleteClientReq is a request to delete a client. type DeleteClientReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // The ID of the client. - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *DeleteClientReq) Reset() { *x = DeleteClientReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DeleteClientReq) String() string { @@ -247,7 +236,7 @@ func (*DeleteClientReq) ProtoMessage() {} func (x *DeleteClientReq) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -271,20 +260,17 @@ func (x *DeleteClientReq) GetId() string { // DeleteClientResp determines if the client is deleted successfully. type DeleteClientResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` unknownFields protoimpl.UnknownFields - - NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DeleteClientResp) Reset() { *x = DeleteClientResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DeleteClientResp) String() string { @@ -295,7 +281,7 @@ func (*DeleteClientResp) ProtoMessage() {} func (x *DeleteClientResp) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -319,24 +305,21 @@ func (x *DeleteClientResp) GetNotFound() bool { // UpdateClientReq is a request to update an existing client. type UpdateClientReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + RedirectUris []string `protobuf:"bytes,2,rep,name=redirect_uris,json=redirectUris,proto3" json:"redirect_uris,omitempty"` + TrustedPeers []string `protobuf:"bytes,3,rep,name=trusted_peers,json=trustedPeers,proto3" json:"trusted_peers,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + LogoUrl string `protobuf:"bytes,5,opt,name=logo_url,json=logoUrl,proto3" json:"logo_url,omitempty"` unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - RedirectUris []string `protobuf:"bytes,2,rep,name=redirect_uris,json=redirectUris,proto3" json:"redirect_uris,omitempty"` - TrustedPeers []string `protobuf:"bytes,3,rep,name=trusted_peers,json=trustedPeers,proto3" json:"trusted_peers,omitempty"` - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` - LogoUrl string `protobuf:"bytes,5,opt,name=logo_url,json=logoUrl,proto3" json:"logo_url,omitempty"` + sizeCache protoimpl.SizeCache } func (x *UpdateClientReq) Reset() { *x = UpdateClientReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UpdateClientReq) String() string { @@ -347,7 +330,7 @@ func (*UpdateClientReq) ProtoMessage() {} func (x *UpdateClientReq) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -399,20 +382,17 @@ func (x *UpdateClientReq) GetLogoUrl() string { // UpdateClientResp returns the response from updating a client. type UpdateClientResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` unknownFields protoimpl.UnknownFields - - NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` + sizeCache protoimpl.SizeCache } func (x *UpdateClientResp) Reset() { *x = UpdateClientResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UpdateClientResp) String() string { @@ -423,7 +403,7 @@ func (*UpdateClientResp) ProtoMessage() {} func (x *UpdateClientResp) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -447,24 +427,21 @@ func (x *UpdateClientResp) GetNotFound() bool { // Password is an email for password mapping managed by the storage. type Password struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` // Currently we do not accept plain text passwords. Could be an option in the future. - Hash []byte `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` - Username string `protobuf:"bytes,3,opt,name=username,proto3" json:"username,omitempty"` - UserId string `protobuf:"bytes,4,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + Hash []byte `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` + Username string `protobuf:"bytes,3,opt,name=username,proto3" json:"username,omitempty"` + UserId string `protobuf:"bytes,4,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Password) Reset() { *x = Password{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Password) String() string { @@ -475,7 +452,7 @@ func (*Password) ProtoMessage() {} func (x *Password) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -520,20 +497,17 @@ func (x *Password) GetUserId() string { // CreatePasswordReq is a request to make a password. type CreatePasswordReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Password *Password `protobuf:"bytes,1,opt,name=password,proto3" json:"password,omitempty"` unknownFields protoimpl.UnknownFields - - Password *Password `protobuf:"bytes,1,opt,name=password,proto3" json:"password,omitempty"` + sizeCache protoimpl.SizeCache } func (x *CreatePasswordReq) Reset() { *x = CreatePasswordReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CreatePasswordReq) String() string { @@ -544,7 +518,7 @@ func (*CreatePasswordReq) ProtoMessage() {} func (x *CreatePasswordReq) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -568,20 +542,17 @@ func (x *CreatePasswordReq) GetPassword() *Password { // CreatePasswordResp returns the response from creating a password. type CreatePasswordResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + AlreadyExists bool `protobuf:"varint,1,opt,name=already_exists,json=alreadyExists,proto3" json:"already_exists,omitempty"` unknownFields protoimpl.UnknownFields - - AlreadyExists bool `protobuf:"varint,1,opt,name=already_exists,json=alreadyExists,proto3" json:"already_exists,omitempty"` + sizeCache protoimpl.SizeCache } func (x *CreatePasswordResp) Reset() { *x = CreatePasswordResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CreatePasswordResp) String() string { @@ -592,7 +563,7 @@ func (*CreatePasswordResp) ProtoMessage() {} func (x *CreatePasswordResp) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -616,23 +587,20 @@ func (x *CreatePasswordResp) GetAlreadyExists() bool { // UpdatePasswordReq is a request to modify an existing password. type UpdatePasswordReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // The email used to lookup the password. This field cannot be modified - Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` - NewHash []byte `protobuf:"bytes,2,opt,name=new_hash,json=newHash,proto3" json:"new_hash,omitempty"` - NewUsername string `protobuf:"bytes,3,opt,name=new_username,json=newUsername,proto3" json:"new_username,omitempty"` + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` + NewHash []byte `protobuf:"bytes,2,opt,name=new_hash,json=newHash,proto3" json:"new_hash,omitempty"` + NewUsername string `protobuf:"bytes,3,opt,name=new_username,json=newUsername,proto3" json:"new_username,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *UpdatePasswordReq) Reset() { *x = UpdatePasswordReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UpdatePasswordReq) String() string { @@ -643,7 +611,7 @@ func (*UpdatePasswordReq) ProtoMessage() {} func (x *UpdatePasswordReq) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -681,20 +649,17 @@ func (x *UpdatePasswordReq) GetNewUsername() string { // UpdatePasswordResp returns the response from modifying an existing password. type UpdatePasswordResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` unknownFields protoimpl.UnknownFields - - NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` + sizeCache protoimpl.SizeCache } func (x *UpdatePasswordResp) Reset() { *x = UpdatePasswordResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UpdatePasswordResp) String() string { @@ -705,7 +670,7 @@ func (*UpdatePasswordResp) ProtoMessage() {} func (x *UpdatePasswordResp) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -729,20 +694,17 @@ func (x *UpdatePasswordResp) GetNotFound() bool { // DeletePasswordReq is a request to delete a password. type DeletePasswordReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` unknownFields protoimpl.UnknownFields - - Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DeletePasswordReq) Reset() { *x = DeletePasswordReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DeletePasswordReq) String() string { @@ -753,7 +715,7 @@ func (*DeletePasswordReq) ProtoMessage() {} func (x *DeletePasswordReq) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -777,20 +739,17 @@ func (x *DeletePasswordReq) GetEmail() string { // DeletePasswordResp returns the response from deleting a password. type DeletePasswordResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` unknownFields protoimpl.UnknownFields - - NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DeletePasswordResp) Reset() { *x = DeletePasswordResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DeletePasswordResp) String() string { @@ -801,7 +760,7 @@ func (*DeletePasswordResp) ProtoMessage() {} func (x *DeletePasswordResp) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -825,18 +784,16 @@ func (x *DeletePasswordResp) GetNotFound() bool { // ListPasswordReq is a request to enumerate passwords. type ListPasswordReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ListPasswordReq) Reset() { *x = ListPasswordReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ListPasswordReq) String() string { @@ -847,7 +804,7 @@ func (*ListPasswordReq) ProtoMessage() {} func (x *ListPasswordReq) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -864,20 +821,17 @@ func (*ListPasswordReq) Descriptor() ([]byte, []int) { // ListPasswordResp returns a list of passwords. type ListPasswordResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Passwords []*Password `protobuf:"bytes,1,rep,name=passwords,proto3" json:"passwords,omitempty"` unknownFields protoimpl.UnknownFields - - Passwords []*Password `protobuf:"bytes,1,rep,name=passwords,proto3" json:"passwords,omitempty"` + sizeCache protoimpl.SizeCache } func (x *ListPasswordResp) Reset() { *x = ListPasswordResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ListPasswordResp) String() string { @@ -888,7 +842,7 @@ func (*ListPasswordResp) ProtoMessage() {} func (x *ListPasswordResp) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -912,18 +866,16 @@ func (x *ListPasswordResp) GetPasswords() []*Password { // VersionReq is a request to fetch version info. type VersionReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *VersionReq) Reset() { *x = VersionReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *VersionReq) String() string { @@ -934,7 +886,7 @@ func (*VersionReq) ProtoMessage() {} func (x *VersionReq) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -951,24 +903,21 @@ func (*VersionReq) Descriptor() ([]byte, []int) { // VersionResp holds the version info of components. type VersionResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // Semantic version of the server. Server string `protobuf:"bytes,1,opt,name=server,proto3" json:"server,omitempty"` - // Numeric version of the API. It increases everytime a new call is added to the API. + // Numeric version of the API. It increases every time a new call is added to the API. // Clients should use this info to determine if the server supports specific features. - Api int32 `protobuf:"varint,2,opt,name=api,proto3" json:"api,omitempty"` + Api int32 `protobuf:"varint,2,opt,name=api,proto3" json:"api,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *VersionResp) Reset() { *x = VersionResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *VersionResp) String() string { @@ -979,7 +928,7 @@ func (*VersionResp) ProtoMessage() {} func (x *VersionResp) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1010,24 +959,21 @@ func (x *VersionResp) GetApi() int32 { // RefreshTokenRef contains the metadata for a refresh token that is managed by the storage. type RefreshTokenRef struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // ID of the refresh token. - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - ClientId string `protobuf:"bytes,2,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` - CreatedAt int64 `protobuf:"varint,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - LastUsed int64 `protobuf:"varint,6,opt,name=last_used,json=lastUsed,proto3" json:"last_used,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + ClientId string `protobuf:"bytes,2,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + CreatedAt int64 `protobuf:"varint,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + LastUsed int64 `protobuf:"varint,6,opt,name=last_used,json=lastUsed,proto3" json:"last_used,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *RefreshTokenRef) Reset() { *x = RefreshTokenRef{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *RefreshTokenRef) String() string { @@ -1038,7 +984,7 @@ func (*RefreshTokenRef) ProtoMessage() {} func (x *RefreshTokenRef) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[18] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1083,21 +1029,18 @@ func (x *RefreshTokenRef) GetLastUsed() int64 { // ListRefreshReq is a request to enumerate the refresh tokens of a user. type ListRefreshReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // The "sub" claim returned in the ID Token. - UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ListRefreshReq) Reset() { *x = ListRefreshReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ListRefreshReq) String() string { @@ -1108,7 +1051,7 @@ func (*ListRefreshReq) ProtoMessage() {} func (x *ListRefreshReq) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[19] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1132,20 +1075,17 @@ func (x *ListRefreshReq) GetUserId() string { // ListRefreshResp returns a list of refresh tokens for a user. type ListRefreshResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + RefreshTokens []*RefreshTokenRef `protobuf:"bytes,1,rep,name=refresh_tokens,json=refreshTokens,proto3" json:"refresh_tokens,omitempty"` unknownFields protoimpl.UnknownFields - - RefreshTokens []*RefreshTokenRef `protobuf:"bytes,1,rep,name=refresh_tokens,json=refreshTokens,proto3" json:"refresh_tokens,omitempty"` + sizeCache protoimpl.SizeCache } func (x *ListRefreshResp) Reset() { *x = ListRefreshResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ListRefreshResp) String() string { @@ -1156,7 +1096,7 @@ func (*ListRefreshResp) ProtoMessage() {} func (x *ListRefreshResp) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[20] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1180,22 +1120,19 @@ func (x *ListRefreshResp) GetRefreshTokens() []*RefreshTokenRef { // RevokeRefreshReq is a request to revoke the refresh token of the user-client pair. type RevokeRefreshReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // The "sub" claim returned in the ID Token. - UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` - ClientId string `protobuf:"bytes,2,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + ClientId string `protobuf:"bytes,2,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *RevokeRefreshReq) Reset() { *x = RevokeRefreshReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *RevokeRefreshReq) String() string { @@ -1206,7 +1143,7 @@ func (*RevokeRefreshReq) ProtoMessage() {} func (x *RevokeRefreshReq) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[21] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1237,21 +1174,18 @@ func (x *RevokeRefreshReq) GetClientId() string { // RevokeRefreshResp determines if the refresh token is revoked successfully. type RevokeRefreshResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // Set to true is refresh token was not found and token could not be revoked. - NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` + NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *RevokeRefreshResp) Reset() { *x = RevokeRefreshResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *RevokeRefreshResp) String() string { @@ -1262,7 +1196,7 @@ func (*RevokeRefreshResp) ProtoMessage() {} func (x *RevokeRefreshResp) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[22] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1285,21 +1219,18 @@ func (x *RevokeRefreshResp) GetNotFound() bool { } type VerifyPasswordReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` unknownFields protoimpl.UnknownFields - - Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` - Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + sizeCache protoimpl.SizeCache } func (x *VerifyPasswordReq) Reset() { *x = VerifyPasswordReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *VerifyPasswordReq) String() string { @@ -1310,7 +1241,7 @@ func (*VerifyPasswordReq) ProtoMessage() {} func (x *VerifyPasswordReq) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[23] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1340,21 +1271,18 @@ func (x *VerifyPasswordReq) GetPassword() string { } type VerifyPasswordResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Verified bool `protobuf:"varint,1,opt,name=verified,proto3" json:"verified,omitempty"` + NotFound bool `protobuf:"varint,2,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` unknownFields protoimpl.UnknownFields - - Verified bool `protobuf:"varint,1,opt,name=verified,proto3" json:"verified,omitempty"` - NotFound bool `protobuf:"varint,2,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` + sizeCache protoimpl.SizeCache } func (x *VerifyPasswordResp) Reset() { *x = VerifyPasswordResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_api_proto_msgTypes[24] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_api_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *VerifyPasswordResp) String() string { @@ -1365,7 +1293,7 @@ func (*VerifyPasswordResp) ProtoMessage() {} func (x *VerifyPasswordResp) ProtoReflect() protoreflect.Message { mi := &file_api_api_proto_msgTypes[24] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1396,7 +1324,7 @@ func (x *VerifyPasswordResp) GetNotFound() bool { var File_api_api_proto protoreflect.FileDescriptor -var file_api_api_proto_rawDesc = []byte{ +var file_api_api_proto_rawDesc = string([]byte{ 0x0a, 0x0d, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x61, 0x70, 0x69, 0x22, 0xc1, 0x01, 0x0a, 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, @@ -1559,22 +1487,22 @@ var file_api_api_proto_rawDesc = []byte{ 0x2e, 0x64, 0x65, 0x78, 0x2e, 0x61, 0x70, 0x69, 0x5a, 0x19, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, 0x78, 0x69, 0x64, 0x70, 0x2f, 0x64, 0x65, 0x78, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} +}) var ( file_api_api_proto_rawDescOnce sync.Once - file_api_api_proto_rawDescData = file_api_api_proto_rawDesc + file_api_api_proto_rawDescData []byte ) func file_api_api_proto_rawDescGZIP() []byte { file_api_api_proto_rawDescOnce.Do(func() { - file_api_api_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_api_proto_rawDescData) + file_api_api_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_api_api_proto_rawDesc), len(file_api_api_proto_rawDesc))) }) return file_api_api_proto_rawDescData } var file_api_api_proto_msgTypes = make([]protoimpl.MessageInfo, 25) -var file_api_api_proto_goTypes = []interface{}{ +var file_api_api_proto_goTypes = []any{ (*Client)(nil), // 0: api.Client (*CreateClientReq)(nil), // 1: api.CreateClientReq (*CreateClientResp)(nil), // 2: api.CreateClientResp @@ -1641,313 +1569,11 @@ func file_api_api_proto_init() { if File_api_api_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_api_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Client); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateClientReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateClientResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteClientReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteClientResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateClientReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateClientResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Password); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreatePasswordReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreatePasswordResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdatePasswordReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdatePasswordResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeletePasswordReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeletePasswordResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListPasswordReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListPasswordResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VersionReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VersionResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RefreshTokenRef); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRefreshReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRefreshResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RevokeRefreshReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RevokeRefreshResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VerifyPasswordReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_api_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VerifyPasswordResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_api_api_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_api_proto_rawDesc), len(file_api_api_proto_rawDesc)), NumEnums: 0, NumMessages: 25, NumExtensions: 0, @@ -1958,7 +1584,6 @@ func file_api_api_proto_init() { MessageInfos: file_api_api_proto_msgTypes, }.Build() File_api_api_proto = out.File - file_api_api_proto_rawDesc = nil file_api_api_proto_goTypes = nil file_api_api_proto_depIdxs = nil } diff --git a/api/api.proto b/api/api.proto index 7d25771a6e..cfb7979c5a 100644 --- a/api/api.proto +++ b/api/api.proto @@ -112,7 +112,7 @@ message VersionReq {} message VersionResp { // Semantic version of the server. string server = 1; - // Numeric version of the API. It increases everytime a new call is added to the API. + // Numeric version of the API. It increases every time a new call is added to the API. // Clients should use this info to determine if the server supports specific features. int32 api = 2; } diff --git a/api/api_grpc.pb.go b/api/api_grpc.pb.go index e8c9873cb5..aeeaa508c0 100644 --- a/api/api_grpc.pb.go +++ b/api/api_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v5.29.3 +// source: api/api.proto package api @@ -11,12 +15,28 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + Dex_CreateClient_FullMethodName = "/api.Dex/CreateClient" + Dex_UpdateClient_FullMethodName = "/api.Dex/UpdateClient" + Dex_DeleteClient_FullMethodName = "/api.Dex/DeleteClient" + Dex_CreatePassword_FullMethodName = "/api.Dex/CreatePassword" + Dex_UpdatePassword_FullMethodName = "/api.Dex/UpdatePassword" + Dex_DeletePassword_FullMethodName = "/api.Dex/DeletePassword" + Dex_ListPasswords_FullMethodName = "/api.Dex/ListPasswords" + Dex_GetVersion_FullMethodName = "/api.Dex/GetVersion" + Dex_ListRefresh_FullMethodName = "/api.Dex/ListRefresh" + Dex_RevokeRefresh_FullMethodName = "/api.Dex/RevokeRefresh" + Dex_VerifyPassword_FullMethodName = "/api.Dex/VerifyPassword" +) // DexClient is the client API for Dex service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// Dex represents the dex gRPC service. type DexClient interface { // CreateClient creates a client. CreateClient(ctx context.Context, in *CreateClientReq, opts ...grpc.CallOption) (*CreateClientResp, error) @@ -53,8 +73,9 @@ func NewDexClient(cc grpc.ClientConnInterface) DexClient { } func (c *dexClient) CreateClient(ctx context.Context, in *CreateClientReq, opts ...grpc.CallOption) (*CreateClientResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(CreateClientResp) - err := c.cc.Invoke(ctx, "/api.Dex/CreateClient", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_CreateClient_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -62,8 +83,9 @@ func (c *dexClient) CreateClient(ctx context.Context, in *CreateClientReq, opts } func (c *dexClient) UpdateClient(ctx context.Context, in *UpdateClientReq, opts ...grpc.CallOption) (*UpdateClientResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(UpdateClientResp) - err := c.cc.Invoke(ctx, "/api.Dex/UpdateClient", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_UpdateClient_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -71,8 +93,9 @@ func (c *dexClient) UpdateClient(ctx context.Context, in *UpdateClientReq, opts } func (c *dexClient) DeleteClient(ctx context.Context, in *DeleteClientReq, opts ...grpc.CallOption) (*DeleteClientResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(DeleteClientResp) - err := c.cc.Invoke(ctx, "/api.Dex/DeleteClient", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_DeleteClient_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -80,8 +103,9 @@ func (c *dexClient) DeleteClient(ctx context.Context, in *DeleteClientReq, opts } func (c *dexClient) CreatePassword(ctx context.Context, in *CreatePasswordReq, opts ...grpc.CallOption) (*CreatePasswordResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(CreatePasswordResp) - err := c.cc.Invoke(ctx, "/api.Dex/CreatePassword", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_CreatePassword_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -89,8 +113,9 @@ func (c *dexClient) CreatePassword(ctx context.Context, in *CreatePasswordReq, o } func (c *dexClient) UpdatePassword(ctx context.Context, in *UpdatePasswordReq, opts ...grpc.CallOption) (*UpdatePasswordResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(UpdatePasswordResp) - err := c.cc.Invoke(ctx, "/api.Dex/UpdatePassword", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_UpdatePassword_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -98,8 +123,9 @@ func (c *dexClient) UpdatePassword(ctx context.Context, in *UpdatePasswordReq, o } func (c *dexClient) DeletePassword(ctx context.Context, in *DeletePasswordReq, opts ...grpc.CallOption) (*DeletePasswordResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(DeletePasswordResp) - err := c.cc.Invoke(ctx, "/api.Dex/DeletePassword", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_DeletePassword_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -107,8 +133,9 @@ func (c *dexClient) DeletePassword(ctx context.Context, in *DeletePasswordReq, o } func (c *dexClient) ListPasswords(ctx context.Context, in *ListPasswordReq, opts ...grpc.CallOption) (*ListPasswordResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ListPasswordResp) - err := c.cc.Invoke(ctx, "/api.Dex/ListPasswords", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_ListPasswords_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -116,8 +143,9 @@ func (c *dexClient) ListPasswords(ctx context.Context, in *ListPasswordReq, opts } func (c *dexClient) GetVersion(ctx context.Context, in *VersionReq, opts ...grpc.CallOption) (*VersionResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(VersionResp) - err := c.cc.Invoke(ctx, "/api.Dex/GetVersion", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_GetVersion_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -125,8 +153,9 @@ func (c *dexClient) GetVersion(ctx context.Context, in *VersionReq, opts ...grpc } func (c *dexClient) ListRefresh(ctx context.Context, in *ListRefreshReq, opts ...grpc.CallOption) (*ListRefreshResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ListRefreshResp) - err := c.cc.Invoke(ctx, "/api.Dex/ListRefresh", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_ListRefresh_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -134,8 +163,9 @@ func (c *dexClient) ListRefresh(ctx context.Context, in *ListRefreshReq, opts .. } func (c *dexClient) RevokeRefresh(ctx context.Context, in *RevokeRefreshReq, opts ...grpc.CallOption) (*RevokeRefreshResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(RevokeRefreshResp) - err := c.cc.Invoke(ctx, "/api.Dex/RevokeRefresh", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_RevokeRefresh_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -143,8 +173,9 @@ func (c *dexClient) RevokeRefresh(ctx context.Context, in *RevokeRefreshReq, opt } func (c *dexClient) VerifyPassword(ctx context.Context, in *VerifyPasswordReq, opts ...grpc.CallOption) (*VerifyPasswordResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(VerifyPasswordResp) - err := c.cc.Invoke(ctx, "/api.Dex/VerifyPassword", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_VerifyPassword_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -153,7 +184,9 @@ func (c *dexClient) VerifyPassword(ctx context.Context, in *VerifyPasswordReq, o // DexServer is the server API for Dex service. // All implementations must embed UnimplementedDexServer -// for forward compatibility +// for forward compatibility. +// +// Dex represents the dex gRPC service. type DexServer interface { // CreateClient creates a client. CreateClient(context.Context, *CreateClientReq) (*CreateClientResp, error) @@ -182,9 +215,12 @@ type DexServer interface { mustEmbedUnimplementedDexServer() } -// UnimplementedDexServer must be embedded to have forward compatible implementations. -type UnimplementedDexServer struct { -} +// UnimplementedDexServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedDexServer struct{} func (UnimplementedDexServer) CreateClient(context.Context, *CreateClientReq) (*CreateClientResp, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateClient not implemented") @@ -220,6 +256,7 @@ func (UnimplementedDexServer) VerifyPassword(context.Context, *VerifyPasswordReq return nil, status.Errorf(codes.Unimplemented, "method VerifyPassword not implemented") } func (UnimplementedDexServer) mustEmbedUnimplementedDexServer() {} +func (UnimplementedDexServer) testEmbeddedByValue() {} // UnsafeDexServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to DexServer will @@ -229,6 +266,13 @@ type UnsafeDexServer interface { } func RegisterDexServer(s grpc.ServiceRegistrar, srv DexServer) { + // If the following call pancis, it indicates UnimplementedDexServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Dex_ServiceDesc, srv) } @@ -242,7 +286,7 @@ func _Dex_CreateClient_Handler(srv interface{}, ctx context.Context, dec func(in } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/CreateClient", + FullMethod: Dex_CreateClient_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).CreateClient(ctx, req.(*CreateClientReq)) @@ -260,7 +304,7 @@ func _Dex_UpdateClient_Handler(srv interface{}, ctx context.Context, dec func(in } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/UpdateClient", + FullMethod: Dex_UpdateClient_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).UpdateClient(ctx, req.(*UpdateClientReq)) @@ -278,7 +322,7 @@ func _Dex_DeleteClient_Handler(srv interface{}, ctx context.Context, dec func(in } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/DeleteClient", + FullMethod: Dex_DeleteClient_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).DeleteClient(ctx, req.(*DeleteClientReq)) @@ -296,7 +340,7 @@ func _Dex_CreatePassword_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/CreatePassword", + FullMethod: Dex_CreatePassword_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).CreatePassword(ctx, req.(*CreatePasswordReq)) @@ -314,7 +358,7 @@ func _Dex_UpdatePassword_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/UpdatePassword", + FullMethod: Dex_UpdatePassword_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).UpdatePassword(ctx, req.(*UpdatePasswordReq)) @@ -332,7 +376,7 @@ func _Dex_DeletePassword_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/DeletePassword", + FullMethod: Dex_DeletePassword_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).DeletePassword(ctx, req.(*DeletePasswordReq)) @@ -350,7 +394,7 @@ func _Dex_ListPasswords_Handler(srv interface{}, ctx context.Context, dec func(i } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/ListPasswords", + FullMethod: Dex_ListPasswords_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).ListPasswords(ctx, req.(*ListPasswordReq)) @@ -368,7 +412,7 @@ func _Dex_GetVersion_Handler(srv interface{}, ctx context.Context, dec func(inte } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/GetVersion", + FullMethod: Dex_GetVersion_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).GetVersion(ctx, req.(*VersionReq)) @@ -386,7 +430,7 @@ func _Dex_ListRefresh_Handler(srv interface{}, ctx context.Context, dec func(int } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/ListRefresh", + FullMethod: Dex_ListRefresh_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).ListRefresh(ctx, req.(*ListRefreshReq)) @@ -404,7 +448,7 @@ func _Dex_RevokeRefresh_Handler(srv interface{}, ctx context.Context, dec func(i } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/RevokeRefresh", + FullMethod: Dex_RevokeRefresh_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).RevokeRefresh(ctx, req.(*RevokeRefreshReq)) @@ -422,7 +466,7 @@ func _Dex_VerifyPassword_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/VerifyPassword", + FullMethod: Dex_VerifyPassword_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).VerifyPassword(ctx, req.(*VerifyPasswordReq)) diff --git a/api/v2/api.pb.go b/api/v2/api.pb.go index f49310f311..6e8a134e93 100644 --- a/api/v2/api.pb.go +++ b/api/v2/api.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.15.6 +// protoc-gen-go v1.36.5 +// protoc v5.29.3 // source: api/v2/api.proto package api @@ -11,6 +11,7 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -22,26 +23,23 @@ const ( // Client represents an OAuth2 client. type Client struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Secret string `protobuf:"bytes,2,opt,name=secret,proto3" json:"secret,omitempty"` + RedirectUris []string `protobuf:"bytes,3,rep,name=redirect_uris,json=redirectUris,proto3" json:"redirect_uris,omitempty"` + TrustedPeers []string `protobuf:"bytes,4,rep,name=trusted_peers,json=trustedPeers,proto3" json:"trusted_peers,omitempty"` + Public bool `protobuf:"varint,5,opt,name=public,proto3" json:"public,omitempty"` + Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"` + LogoUrl string `protobuf:"bytes,7,opt,name=logo_url,json=logoUrl,proto3" json:"logo_url,omitempty"` unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Secret string `protobuf:"bytes,2,opt,name=secret,proto3" json:"secret,omitempty"` - RedirectUris []string `protobuf:"bytes,3,rep,name=redirect_uris,json=redirectUris,proto3" json:"redirect_uris,omitempty"` - TrustedPeers []string `protobuf:"bytes,4,rep,name=trusted_peers,json=trustedPeers,proto3" json:"trusted_peers,omitempty"` - Public bool `protobuf:"varint,5,opt,name=public,proto3" json:"public,omitempty"` - Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"` - LogoUrl string `protobuf:"bytes,7,opt,name=logo_url,json=logoUrl,proto3" json:"logo_url,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Client) Reset() { *x = Client{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Client) String() string { @@ -52,7 +50,7 @@ func (*Client) ProtoMessage() {} func (x *Client) ProtoReflect() protoreflect.Message { mi := &file_api_v2_api_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -116,22 +114,195 @@ func (x *Client) GetLogoUrl() string { return "" } -// CreateClientReq is a request to make a client. -type CreateClientReq struct { - state protoimpl.MessageState +// ClientInfo represents an OAuth2 client without sensitive information. +type ClientInfo struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + RedirectUris []string `protobuf:"bytes,2,rep,name=redirect_uris,json=redirectUris,proto3" json:"redirect_uris,omitempty"` + TrustedPeers []string `protobuf:"bytes,3,rep,name=trusted_peers,json=trustedPeers,proto3" json:"trusted_peers,omitempty"` + Public bool `protobuf:"varint,4,opt,name=public,proto3" json:"public,omitempty"` + Name string `protobuf:"bytes,5,opt,name=name,proto3" json:"name,omitempty"` + LogoUrl string `protobuf:"bytes,6,opt,name=logo_url,json=logoUrl,proto3" json:"logo_url,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ClientInfo) Reset() { + *x = ClientInfo{} + mi := &file_api_v2_api_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ClientInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientInfo) ProtoMessage() {} + +func (x *ClientInfo) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientInfo.ProtoReflect.Descriptor instead. +func (*ClientInfo) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{1} +} + +func (x *ClientInfo) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ClientInfo) GetRedirectUris() []string { + if x != nil { + return x.RedirectUris + } + return nil +} + +func (x *ClientInfo) GetTrustedPeers() []string { + if x != nil { + return x.TrustedPeers + } + return nil +} + +func (x *ClientInfo) GetPublic() bool { + if x != nil { + return x.Public + } + return false +} + +func (x *ClientInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ClientInfo) GetLogoUrl() string { + if x != nil { + return x.LogoUrl + } + return "" +} + +// GetClientReq is a request to retrieve client details. +type GetClientReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The ID of the client. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache +} + +func (x *GetClientReq) Reset() { + *x = GetClientReq{} + mi := &file_api_v2_api_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetClientReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetClientReq) ProtoMessage() {} + +func (x *GetClientReq) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetClientReq.ProtoReflect.Descriptor instead. +func (*GetClientReq) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{2} +} + +func (x *GetClientReq) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +// GetClientResp returns the client details. +type GetClientResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + Client *Client `protobuf:"bytes,1,opt,name=client,proto3" json:"client,omitempty"` unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetClientResp) Reset() { + *x = GetClientResp{} + mi := &file_api_v2_api_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} - Client *Client `protobuf:"bytes,1,opt,name=client,proto3" json:"client,omitempty"` +func (x *GetClientResp) String() string { + return protoimpl.X.MessageStringOf(x) } -func (x *CreateClientReq) Reset() { - *x = CreateClientReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[1] +func (*GetClientResp) ProtoMessage() {} + +func (x *GetClientResp) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[3] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetClientResp.ProtoReflect.Descriptor instead. +func (*GetClientResp) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{3} +} + +func (x *GetClientResp) GetClient() *Client { + if x != nil { + return x.Client } + return nil +} + +// CreateClientReq is a request to make a client. +type CreateClientReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Client *Client `protobuf:"bytes,1,opt,name=client,proto3" json:"client,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateClientReq) Reset() { + *x = CreateClientReq{} + mi := &file_api_v2_api_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CreateClientReq) String() string { @@ -141,8 +312,8 @@ func (x *CreateClientReq) String() string { func (*CreateClientReq) ProtoMessage() {} func (x *CreateClientReq) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[4] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -154,7 +325,7 @@ func (x *CreateClientReq) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateClientReq.ProtoReflect.Descriptor instead. func (*CreateClientReq) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{1} + return file_api_v2_api_proto_rawDescGZIP(), []int{4} } func (x *CreateClientReq) GetClient() *Client { @@ -166,21 +337,18 @@ func (x *CreateClientReq) GetClient() *Client { // CreateClientResp returns the response from creating a client. type CreateClientResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + AlreadyExists bool `protobuf:"varint,1,opt,name=already_exists,json=alreadyExists,proto3" json:"already_exists,omitempty"` + Client *Client `protobuf:"bytes,2,opt,name=client,proto3" json:"client,omitempty"` unknownFields protoimpl.UnknownFields - - AlreadyExists bool `protobuf:"varint,1,opt,name=already_exists,json=alreadyExists,proto3" json:"already_exists,omitempty"` - Client *Client `protobuf:"bytes,2,opt,name=client,proto3" json:"client,omitempty"` + sizeCache protoimpl.SizeCache } func (x *CreateClientResp) Reset() { *x = CreateClientResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CreateClientResp) String() string { @@ -190,8 +358,8 @@ func (x *CreateClientResp) String() string { func (*CreateClientResp) ProtoMessage() {} func (x *CreateClientResp) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[5] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -203,7 +371,7 @@ func (x *CreateClientResp) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateClientResp.ProtoReflect.Descriptor instead. func (*CreateClientResp) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{2} + return file_api_v2_api_proto_rawDescGZIP(), []int{5} } func (x *CreateClientResp) GetAlreadyExists() bool { @@ -222,21 +390,18 @@ func (x *CreateClientResp) GetClient() *Client { // DeleteClientReq is a request to delete a client. type DeleteClientReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // The ID of the client. - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *DeleteClientReq) Reset() { *x = DeleteClientReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DeleteClientReq) String() string { @@ -246,8 +411,8 @@ func (x *DeleteClientReq) String() string { func (*DeleteClientReq) ProtoMessage() {} func (x *DeleteClientReq) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[6] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -259,7 +424,7 @@ func (x *DeleteClientReq) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteClientReq.ProtoReflect.Descriptor instead. func (*DeleteClientReq) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{3} + return file_api_v2_api_proto_rawDescGZIP(), []int{6} } func (x *DeleteClientReq) GetId() string { @@ -271,20 +436,17 @@ func (x *DeleteClientReq) GetId() string { // DeleteClientResp determines if the client is deleted successfully. type DeleteClientResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` unknownFields protoimpl.UnknownFields - - NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DeleteClientResp) Reset() { *x = DeleteClientResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DeleteClientResp) String() string { @@ -294,8 +456,8 @@ func (x *DeleteClientResp) String() string { func (*DeleteClientResp) ProtoMessage() {} func (x *DeleteClientResp) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[7] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -307,7 +469,7 @@ func (x *DeleteClientResp) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteClientResp.ProtoReflect.Descriptor instead. func (*DeleteClientResp) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{4} + return file_api_v2_api_proto_rawDescGZIP(), []int{7} } func (x *DeleteClientResp) GetNotFound() bool { @@ -319,24 +481,21 @@ func (x *DeleteClientResp) GetNotFound() bool { // UpdateClientReq is a request to update an existing client. type UpdateClientReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + RedirectUris []string `protobuf:"bytes,2,rep,name=redirect_uris,json=redirectUris,proto3" json:"redirect_uris,omitempty"` + TrustedPeers []string `protobuf:"bytes,3,rep,name=trusted_peers,json=trustedPeers,proto3" json:"trusted_peers,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + LogoUrl string `protobuf:"bytes,5,opt,name=logo_url,json=logoUrl,proto3" json:"logo_url,omitempty"` unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - RedirectUris []string `protobuf:"bytes,2,rep,name=redirect_uris,json=redirectUris,proto3" json:"redirect_uris,omitempty"` - TrustedPeers []string `protobuf:"bytes,3,rep,name=trusted_peers,json=trustedPeers,proto3" json:"trusted_peers,omitempty"` - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` - LogoUrl string `protobuf:"bytes,5,opt,name=logo_url,json=logoUrl,proto3" json:"logo_url,omitempty"` + sizeCache protoimpl.SizeCache } func (x *UpdateClientReq) Reset() { *x = UpdateClientReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UpdateClientReq) String() string { @@ -346,8 +505,8 @@ func (x *UpdateClientReq) String() string { func (*UpdateClientReq) ProtoMessage() {} func (x *UpdateClientReq) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[8] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -359,7 +518,7 @@ func (x *UpdateClientReq) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateClientReq.ProtoReflect.Descriptor instead. func (*UpdateClientReq) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{5} + return file_api_v2_api_proto_rawDescGZIP(), []int{8} } func (x *UpdateClientReq) GetId() string { @@ -399,20 +558,17 @@ func (x *UpdateClientReq) GetLogoUrl() string { // UpdateClientResp returns the response from updating a client. type UpdateClientResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` unknownFields protoimpl.UnknownFields - - NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` + sizeCache protoimpl.SizeCache } func (x *UpdateClientResp) Reset() { *x = UpdateClientResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UpdateClientResp) String() string { @@ -422,8 +578,8 @@ func (x *UpdateClientResp) String() string { func (*UpdateClientResp) ProtoMessage() {} func (x *UpdateClientResp) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[9] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -435,7 +591,7 @@ func (x *UpdateClientResp) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateClientResp.ProtoReflect.Descriptor instead. func (*UpdateClientResp) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{6} + return file_api_v2_api_proto_rawDescGZIP(), []int{9} } func (x *UpdateClientResp) GetNotFound() bool { @@ -445,37 +601,29 @@ func (x *UpdateClientResp) GetNotFound() bool { return false } -// Password is an email for password mapping managed by the storage. -type Password struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache +// ListClientReq is a request to enumerate clients. +type ListClientReq struct { + state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields - - Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` - // Currently we do not accept plain text passwords. Could be an option in the future. - Hash []byte `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` - Username string `protobuf:"bytes,3,opt,name=username,proto3" json:"username,omitempty"` - UserId string `protobuf:"bytes,4,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + sizeCache protoimpl.SizeCache } -func (x *Password) Reset() { - *x = Password{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } +func (x *ListClientReq) Reset() { + *x = ListClientReq{} + mi := &file_api_v2_api_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *Password) String() string { +func (x *ListClientReq) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Password) ProtoMessage() {} +func (*ListClientReq) ProtoMessage() {} -func (x *Password) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { +func (x *ListClientReq) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[10] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -485,55 +633,139 @@ func (x *Password) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Password.ProtoReflect.Descriptor instead. -func (*Password) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{7} +// Deprecated: Use ListClientReq.ProtoReflect.Descriptor instead. +func (*ListClientReq) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{10} } -func (x *Password) GetEmail() string { - if x != nil { - return x.Email - } - return "" +// ListClientResp returns a list of clients. +type ListClientResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + Clients []*ClientInfo `protobuf:"bytes,1,rep,name=clients,proto3" json:"clients,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *Password) GetHash() []byte { - if x != nil { - return x.Hash - } - return nil +func (x *ListClientResp) Reset() { + *x = ListClientResp{} + mi := &file_api_v2_api_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *Password) GetUsername() string { - if x != nil { - return x.Username - } - return "" +func (x *ListClientResp) String() string { + return protoimpl.X.MessageStringOf(x) } -func (x *Password) GetUserId() string { +func (*ListClientResp) ProtoMessage() {} + +func (x *ListClientResp) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[11] if x != nil { - return x.UserId + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return "" + return mi.MessageOf(x) } -// CreatePasswordReq is a request to make a password. -type CreatePasswordReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Password *Password `protobuf:"bytes,1,opt,name=password,proto3" json:"password,omitempty"` +// Deprecated: Use ListClientResp.ProtoReflect.Descriptor instead. +func (*ListClientResp) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{11} } -func (x *CreatePasswordReq) Reset() { - *x = CreatePasswordReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[8] +func (x *ListClientResp) GetClients() []*ClientInfo { + if x != nil { + return x.Clients + } + return nil +} + +// Password is an email for password mapping managed by the storage. +type Password struct { + state protoimpl.MessageState `protogen:"open.v1"` + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` + // Currently we do not accept plain text passwords. Could be an option in the future. + Hash []byte `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` + Username string `protobuf:"bytes,3,opt,name=username,proto3" json:"username,omitempty"` + UserId string `protobuf:"bytes,4,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Password) Reset() { + *x = Password{} + mi := &file_api_v2_api_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Password) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Password) ProtoMessage() {} + +func (x *Password) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[12] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Password.ProtoReflect.Descriptor instead. +func (*Password) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{12} +} + +func (x *Password) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *Password) GetHash() []byte { + if x != nil { + return x.Hash } + return nil +} + +func (x *Password) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *Password) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +// CreatePasswordReq is a request to make a password. +type CreatePasswordReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Password *Password `protobuf:"bytes,1,opt,name=password,proto3" json:"password,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreatePasswordReq) Reset() { + *x = CreatePasswordReq{} + mi := &file_api_v2_api_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CreatePasswordReq) String() string { @@ -543,8 +775,8 @@ func (x *CreatePasswordReq) String() string { func (*CreatePasswordReq) ProtoMessage() {} func (x *CreatePasswordReq) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[13] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -556,7 +788,7 @@ func (x *CreatePasswordReq) ProtoReflect() protoreflect.Message { // Deprecated: Use CreatePasswordReq.ProtoReflect.Descriptor instead. func (*CreatePasswordReq) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{8} + return file_api_v2_api_proto_rawDescGZIP(), []int{13} } func (x *CreatePasswordReq) GetPassword() *Password { @@ -568,20 +800,17 @@ func (x *CreatePasswordReq) GetPassword() *Password { // CreatePasswordResp returns the response from creating a password. type CreatePasswordResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + AlreadyExists bool `protobuf:"varint,1,opt,name=already_exists,json=alreadyExists,proto3" json:"already_exists,omitempty"` unknownFields protoimpl.UnknownFields - - AlreadyExists bool `protobuf:"varint,1,opt,name=already_exists,json=alreadyExists,proto3" json:"already_exists,omitempty"` + sizeCache protoimpl.SizeCache } func (x *CreatePasswordResp) Reset() { *x = CreatePasswordResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CreatePasswordResp) String() string { @@ -591,8 +820,8 @@ func (x *CreatePasswordResp) String() string { func (*CreatePasswordResp) ProtoMessage() {} func (x *CreatePasswordResp) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[14] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -604,7 +833,7 @@ func (x *CreatePasswordResp) ProtoReflect() protoreflect.Message { // Deprecated: Use CreatePasswordResp.ProtoReflect.Descriptor instead. func (*CreatePasswordResp) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{9} + return file_api_v2_api_proto_rawDescGZIP(), []int{14} } func (x *CreatePasswordResp) GetAlreadyExists() bool { @@ -616,23 +845,20 @@ func (x *CreatePasswordResp) GetAlreadyExists() bool { // UpdatePasswordReq is a request to modify an existing password. type UpdatePasswordReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // The email used to lookup the password. This field cannot be modified - Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` - NewHash []byte `protobuf:"bytes,2,opt,name=new_hash,json=newHash,proto3" json:"new_hash,omitempty"` - NewUsername string `protobuf:"bytes,3,opt,name=new_username,json=newUsername,proto3" json:"new_username,omitempty"` + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` + NewHash []byte `protobuf:"bytes,2,opt,name=new_hash,json=newHash,proto3" json:"new_hash,omitempty"` + NewUsername string `protobuf:"bytes,3,opt,name=new_username,json=newUsername,proto3" json:"new_username,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *UpdatePasswordReq) Reset() { *x = UpdatePasswordReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UpdatePasswordReq) String() string { @@ -642,8 +868,8 @@ func (x *UpdatePasswordReq) String() string { func (*UpdatePasswordReq) ProtoMessage() {} func (x *UpdatePasswordReq) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[15] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -655,7 +881,7 @@ func (x *UpdatePasswordReq) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdatePasswordReq.ProtoReflect.Descriptor instead. func (*UpdatePasswordReq) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{10} + return file_api_v2_api_proto_rawDescGZIP(), []int{15} } func (x *UpdatePasswordReq) GetEmail() string { @@ -681,20 +907,17 @@ func (x *UpdatePasswordReq) GetNewUsername() string { // UpdatePasswordResp returns the response from modifying an existing password. type UpdatePasswordResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` unknownFields protoimpl.UnknownFields - - NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` + sizeCache protoimpl.SizeCache } func (x *UpdatePasswordResp) Reset() { *x = UpdatePasswordResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UpdatePasswordResp) String() string { @@ -704,8 +927,8 @@ func (x *UpdatePasswordResp) String() string { func (*UpdatePasswordResp) ProtoMessage() {} func (x *UpdatePasswordResp) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[16] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -717,7 +940,7 @@ func (x *UpdatePasswordResp) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdatePasswordResp.ProtoReflect.Descriptor instead. func (*UpdatePasswordResp) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{11} + return file_api_v2_api_proto_rawDescGZIP(), []int{16} } func (x *UpdatePasswordResp) GetNotFound() bool { @@ -729,20 +952,17 @@ func (x *UpdatePasswordResp) GetNotFound() bool { // DeletePasswordReq is a request to delete a password. type DeletePasswordReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` unknownFields protoimpl.UnknownFields - - Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DeletePasswordReq) Reset() { *x = DeletePasswordReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DeletePasswordReq) String() string { @@ -752,8 +972,8 @@ func (x *DeletePasswordReq) String() string { func (*DeletePasswordReq) ProtoMessage() {} func (x *DeletePasswordReq) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[17] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -765,7 +985,7 @@ func (x *DeletePasswordReq) ProtoReflect() protoreflect.Message { // Deprecated: Use DeletePasswordReq.ProtoReflect.Descriptor instead. func (*DeletePasswordReq) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{12} + return file_api_v2_api_proto_rawDescGZIP(), []int{17} } func (x *DeletePasswordReq) GetEmail() string { @@ -777,20 +997,17 @@ func (x *DeletePasswordReq) GetEmail() string { // DeletePasswordResp returns the response from deleting a password. type DeletePasswordResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` unknownFields protoimpl.UnknownFields - - NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DeletePasswordResp) Reset() { *x = DeletePasswordResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DeletePasswordResp) String() string { @@ -800,8 +1017,8 @@ func (x *DeletePasswordResp) String() string { func (*DeletePasswordResp) ProtoMessage() {} func (x *DeletePasswordResp) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[18] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -813,7 +1030,7 @@ func (x *DeletePasswordResp) ProtoReflect() protoreflect.Message { // Deprecated: Use DeletePasswordResp.ProtoReflect.Descriptor instead. func (*DeletePasswordResp) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{13} + return file_api_v2_api_proto_rawDescGZIP(), []int{18} } func (x *DeletePasswordResp) GetNotFound() bool { @@ -825,29 +1042,473 @@ func (x *DeletePasswordResp) GetNotFound() bool { // ListPasswordReq is a request to enumerate passwords. type ListPasswordReq struct { - state protoimpl.MessageState + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListPasswordReq) Reset() { + *x = ListPasswordReq{} + mi := &file_api_v2_api_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListPasswordReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListPasswordReq) ProtoMessage() {} + +func (x *ListPasswordReq) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[19] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListPasswordReq.ProtoReflect.Descriptor instead. +func (*ListPasswordReq) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{19} +} + +// ListPasswordResp returns a list of passwords. +type ListPasswordResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + Passwords []*Password `protobuf:"bytes,1,rep,name=passwords,proto3" json:"passwords,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListPasswordResp) Reset() { + *x = ListPasswordResp{} + mi := &file_api_v2_api_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListPasswordResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListPasswordResp) ProtoMessage() {} + +func (x *ListPasswordResp) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListPasswordResp.ProtoReflect.Descriptor instead. +func (*ListPasswordResp) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{20} +} + +func (x *ListPasswordResp) GetPasswords() []*Password { + if x != nil { + return x.Passwords + } + return nil +} + +// Connector is a strategy used by Dex for authenticating a user against another identity provider +type Connector struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Config []byte `protobuf:"bytes,4,opt,name=config,proto3" json:"config,omitempty"` + unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache +} + +func (x *Connector) Reset() { + *x = Connector{} + mi := &file_api_v2_api_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Connector) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Connector) ProtoMessage() {} + +func (x *Connector) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[21] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Connector.ProtoReflect.Descriptor instead. +func (*Connector) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{21} +} + +func (x *Connector) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Connector) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *Connector) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Connector) GetConfig() []byte { + if x != nil { + return x.Config + } + return nil +} + +// CreateConnectorReq is a request to make a connector. +type CreateConnectorReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Connector *Connector `protobuf:"bytes,1,opt,name=connector,proto3" json:"connector,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateConnectorReq) Reset() { + *x = CreateConnectorReq{} + mi := &file_api_v2_api_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateConnectorReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateConnectorReq) ProtoMessage() {} + +func (x *CreateConnectorReq) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[22] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateConnectorReq.ProtoReflect.Descriptor instead. +func (*CreateConnectorReq) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{22} +} + +func (x *CreateConnectorReq) GetConnector() *Connector { + if x != nil { + return x.Connector + } + return nil +} + +// CreateConnectorResp returns the response from creating a connector. +type CreateConnectorResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + AlreadyExists bool `protobuf:"varint,1,opt,name=already_exists,json=alreadyExists,proto3" json:"already_exists,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateConnectorResp) Reset() { + *x = CreateConnectorResp{} + mi := &file_api_v2_api_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateConnectorResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateConnectorResp) ProtoMessage() {} + +func (x *CreateConnectorResp) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[23] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateConnectorResp.ProtoReflect.Descriptor instead. +func (*CreateConnectorResp) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{23} +} + +func (x *CreateConnectorResp) GetAlreadyExists() bool { + if x != nil { + return x.AlreadyExists + } + return false +} + +// UpdateConnectorReq is a request to modify an existing connector. +type UpdateConnectorReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The id used to lookup the connector. This field cannot be modified + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + NewType string `protobuf:"bytes,2,opt,name=new_type,json=newType,proto3" json:"new_type,omitempty"` + NewName string `protobuf:"bytes,3,opt,name=new_name,json=newName,proto3" json:"new_name,omitempty"` + NewConfig []byte `protobuf:"bytes,4,opt,name=new_config,json=newConfig,proto3" json:"new_config,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateConnectorReq) Reset() { + *x = UpdateConnectorReq{} + mi := &file_api_v2_api_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateConnectorReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateConnectorReq) ProtoMessage() {} + +func (x *UpdateConnectorReq) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[24] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateConnectorReq.ProtoReflect.Descriptor instead. +func (*UpdateConnectorReq) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{24} +} + +func (x *UpdateConnectorReq) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateConnectorReq) GetNewType() string { + if x != nil { + return x.NewType + } + return "" +} + +func (x *UpdateConnectorReq) GetNewName() string { + if x != nil { + return x.NewName + } + return "" +} + +func (x *UpdateConnectorReq) GetNewConfig() []byte { + if x != nil { + return x.NewConfig + } + return nil +} + +// UpdateConnectorResp returns the response from modifying an existing connector. +type UpdateConnectorResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateConnectorResp) Reset() { + *x = UpdateConnectorResp{} + mi := &file_api_v2_api_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateConnectorResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateConnectorResp) ProtoMessage() {} + +func (x *UpdateConnectorResp) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[25] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateConnectorResp.ProtoReflect.Descriptor instead. +func (*UpdateConnectorResp) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{25} +} + +func (x *UpdateConnectorResp) GetNotFound() bool { + if x != nil { + return x.NotFound + } + return false +} + +// DeleteConnectorReq is a request to delete a connector. +type DeleteConnectorReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeleteConnectorReq) Reset() { + *x = DeleteConnectorReq{} + mi := &file_api_v2_api_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteConnectorReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteConnectorReq) ProtoMessage() {} + +func (x *DeleteConnectorReq) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[26] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteConnectorReq.ProtoReflect.Descriptor instead. +func (*DeleteConnectorReq) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{26} +} + +func (x *DeleteConnectorReq) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +// DeleteConnectorResp returns the response from deleting a connector. +type DeleteConnectorResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeleteConnectorResp) Reset() { + *x = DeleteConnectorResp{} + mi := &file_api_v2_api_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteConnectorResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteConnectorResp) ProtoMessage() {} + +func (x *DeleteConnectorResp) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[27] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteConnectorResp.ProtoReflect.Descriptor instead. +func (*DeleteConnectorResp) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{27} +} + +func (x *DeleteConnectorResp) GetNotFound() bool { + if x != nil { + return x.NotFound + } + return false +} + +// ListConnectorReq is a request to enumerate connectors. +type ListConnectorReq struct { + state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *ListPasswordReq) Reset() { - *x = ListPasswordReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } +func (x *ListConnectorReq) Reset() { + *x = ListConnectorReq{} + mi := &file_api_v2_api_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *ListPasswordReq) String() string { +func (x *ListConnectorReq) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ListPasswordReq) ProtoMessage() {} +func (*ListConnectorReq) ProtoMessage() {} -func (x *ListPasswordReq) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { +func (x *ListConnectorReq) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[28] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -857,38 +1518,35 @@ func (x *ListPasswordReq) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ListPasswordReq.ProtoReflect.Descriptor instead. -func (*ListPasswordReq) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{14} +// Deprecated: Use ListConnectorReq.ProtoReflect.Descriptor instead. +func (*ListConnectorReq) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{28} } -// ListPasswordResp returns a list of passwords. -type ListPasswordResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache +// ListConnectorResp returns a list of connectors. +type ListConnectorResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + Connectors []*Connector `protobuf:"bytes,1,rep,name=connectors,proto3" json:"connectors,omitempty"` unknownFields protoimpl.UnknownFields - - Passwords []*Password `protobuf:"bytes,1,rep,name=passwords,proto3" json:"passwords,omitempty"` + sizeCache protoimpl.SizeCache } -func (x *ListPasswordResp) Reset() { - *x = ListPasswordResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } +func (x *ListConnectorResp) Reset() { + *x = ListConnectorResp{} + mi := &file_api_v2_api_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *ListPasswordResp) String() string { +func (x *ListConnectorResp) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ListPasswordResp) ProtoMessage() {} +func (*ListConnectorResp) ProtoMessage() {} -func (x *ListPasswordResp) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { +func (x *ListConnectorResp) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[29] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -898,32 +1556,30 @@ func (x *ListPasswordResp) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ListPasswordResp.ProtoReflect.Descriptor instead. -func (*ListPasswordResp) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{15} +// Deprecated: Use ListConnectorResp.ProtoReflect.Descriptor instead. +func (*ListConnectorResp) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{29} } -func (x *ListPasswordResp) GetPasswords() []*Password { +func (x *ListConnectorResp) GetConnectors() []*Connector { if x != nil { - return x.Passwords + return x.Connectors } return nil } // VersionReq is a request to fetch version info. type VersionReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *VersionReq) Reset() { *x = VersionReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *VersionReq) String() string { @@ -933,8 +1589,8 @@ func (x *VersionReq) String() string { func (*VersionReq) ProtoMessage() {} func (x *VersionReq) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[30] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -946,29 +1602,26 @@ func (x *VersionReq) ProtoReflect() protoreflect.Message { // Deprecated: Use VersionReq.ProtoReflect.Descriptor instead. func (*VersionReq) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{16} + return file_api_v2_api_proto_rawDescGZIP(), []int{30} } // VersionResp holds the version info of components. type VersionResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // Semantic version of the server. Server string `protobuf:"bytes,1,opt,name=server,proto3" json:"server,omitempty"` - // Numeric version of the API. It increases everytime a new call is added to the API. + // Numeric version of the API. It increases every time a new call is added to the API. // Clients should use this info to determine if the server supports specific features. - Api int32 `protobuf:"varint,2,opt,name=api,proto3" json:"api,omitempty"` + Api int32 `protobuf:"varint,2,opt,name=api,proto3" json:"api,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *VersionResp) Reset() { *x = VersionResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *VersionResp) String() string { @@ -978,8 +1631,8 @@ func (x *VersionResp) String() string { func (*VersionResp) ProtoMessage() {} func (x *VersionResp) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[31] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -991,7 +1644,7 @@ func (x *VersionResp) ProtoReflect() protoreflect.Message { // Deprecated: Use VersionResp.ProtoReflect.Descriptor instead. func (*VersionResp) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{17} + return file_api_v2_api_proto_rawDescGZIP(), []int{31} } func (x *VersionResp) GetServer() string { @@ -1008,26 +1661,217 @@ func (x *VersionResp) GetApi() int32 { return 0 } -// RefreshTokenRef contains the metadata for a refresh token that is managed by the storage. -type RefreshTokenRef struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache +// DiscoveryReq is a request to fetch discover information. +type DiscoveryReq struct { + state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DiscoveryReq) Reset() { + *x = DiscoveryReq{} + mi := &file_api_v2_api_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DiscoveryReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DiscoveryReq) ProtoMessage() {} + +func (x *DiscoveryReq) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[32] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DiscoveryReq.ProtoReflect.Descriptor instead. +func (*DiscoveryReq) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{32} +} + +// DiscoverResp holds the version oidc disovery info. +type DiscoveryResp struct { + state protoimpl.MessageState `protogen:"open.v1"` + Issuer string `protobuf:"bytes,1,opt,name=issuer,proto3" json:"issuer,omitempty"` + AuthorizationEndpoint string `protobuf:"bytes,2,opt,name=authorization_endpoint,json=authorizationEndpoint,proto3" json:"authorization_endpoint,omitempty"` + TokenEndpoint string `protobuf:"bytes,3,opt,name=token_endpoint,json=tokenEndpoint,proto3" json:"token_endpoint,omitempty"` + JwksUri string `protobuf:"bytes,4,opt,name=jwks_uri,json=jwksUri,proto3" json:"jwks_uri,omitempty"` + UserinfoEndpoint string `protobuf:"bytes,5,opt,name=userinfo_endpoint,json=userinfoEndpoint,proto3" json:"userinfo_endpoint,omitempty"` + DeviceAuthorizationEndpoint string `protobuf:"bytes,6,opt,name=device_authorization_endpoint,json=deviceAuthorizationEndpoint,proto3" json:"device_authorization_endpoint,omitempty"` + IntrospectionEndpoint string `protobuf:"bytes,7,opt,name=introspection_endpoint,json=introspectionEndpoint,proto3" json:"introspection_endpoint,omitempty"` + GrantTypesSupported []string `protobuf:"bytes,8,rep,name=grant_types_supported,json=grantTypesSupported,proto3" json:"grant_types_supported,omitempty"` + ResponseTypesSupported []string `protobuf:"bytes,9,rep,name=response_types_supported,json=responseTypesSupported,proto3" json:"response_types_supported,omitempty"` + SubjectTypesSupported []string `protobuf:"bytes,10,rep,name=subject_types_supported,json=subjectTypesSupported,proto3" json:"subject_types_supported,omitempty"` + IdTokenSigningAlgValuesSupported []string `protobuf:"bytes,11,rep,name=id_token_signing_alg_values_supported,json=idTokenSigningAlgValuesSupported,proto3" json:"id_token_signing_alg_values_supported,omitempty"` + CodeChallengeMethodsSupported []string `protobuf:"bytes,12,rep,name=code_challenge_methods_supported,json=codeChallengeMethodsSupported,proto3" json:"code_challenge_methods_supported,omitempty"` + ScopesSupported []string `protobuf:"bytes,13,rep,name=scopes_supported,json=scopesSupported,proto3" json:"scopes_supported,omitempty"` + TokenEndpointAuthMethodsSupported []string `protobuf:"bytes,14,rep,name=token_endpoint_auth_methods_supported,json=tokenEndpointAuthMethodsSupported,proto3" json:"token_endpoint_auth_methods_supported,omitempty"` + ClaimsSupported []string `protobuf:"bytes,15,rep,name=claims_supported,json=claimsSupported,proto3" json:"claims_supported,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DiscoveryResp) Reset() { + *x = DiscoveryResp{} + mi := &file_api_v2_api_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DiscoveryResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DiscoveryResp) ProtoMessage() {} + +func (x *DiscoveryResp) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[33] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DiscoveryResp.ProtoReflect.Descriptor instead. +func (*DiscoveryResp) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{33} +} + +func (x *DiscoveryResp) GetIssuer() string { + if x != nil { + return x.Issuer + } + return "" +} + +func (x *DiscoveryResp) GetAuthorizationEndpoint() string { + if x != nil { + return x.AuthorizationEndpoint + } + return "" +} + +func (x *DiscoveryResp) GetTokenEndpoint() string { + if x != nil { + return x.TokenEndpoint + } + return "" +} + +func (x *DiscoveryResp) GetJwksUri() string { + if x != nil { + return x.JwksUri + } + return "" +} + +func (x *DiscoveryResp) GetUserinfoEndpoint() string { + if x != nil { + return x.UserinfoEndpoint + } + return "" +} + +func (x *DiscoveryResp) GetDeviceAuthorizationEndpoint() string { + if x != nil { + return x.DeviceAuthorizationEndpoint + } + return "" +} + +func (x *DiscoveryResp) GetIntrospectionEndpoint() string { + if x != nil { + return x.IntrospectionEndpoint + } + return "" +} + +func (x *DiscoveryResp) GetGrantTypesSupported() []string { + if x != nil { + return x.GrantTypesSupported + } + return nil +} + +func (x *DiscoveryResp) GetResponseTypesSupported() []string { + if x != nil { + return x.ResponseTypesSupported + } + return nil +} + +func (x *DiscoveryResp) GetSubjectTypesSupported() []string { + if x != nil { + return x.SubjectTypesSupported + } + return nil +} + +func (x *DiscoveryResp) GetIdTokenSigningAlgValuesSupported() []string { + if x != nil { + return x.IdTokenSigningAlgValuesSupported + } + return nil +} + +func (x *DiscoveryResp) GetCodeChallengeMethodsSupported() []string { + if x != nil { + return x.CodeChallengeMethodsSupported + } + return nil +} + +func (x *DiscoveryResp) GetScopesSupported() []string { + if x != nil { + return x.ScopesSupported + } + return nil +} + +func (x *DiscoveryResp) GetTokenEndpointAuthMethodsSupported() []string { + if x != nil { + return x.TokenEndpointAuthMethodsSupported + } + return nil +} + +func (x *DiscoveryResp) GetClaimsSupported() []string { + if x != nil { + return x.ClaimsSupported + } + return nil +} +// RefreshTokenRef contains the metadata for a refresh token that is managed by the storage. +type RefreshTokenRef struct { + state protoimpl.MessageState `protogen:"open.v1"` // ID of the refresh token. - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - ClientId string `protobuf:"bytes,2,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` - CreatedAt int64 `protobuf:"varint,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - LastUsed int64 `protobuf:"varint,6,opt,name=last_used,json=lastUsed,proto3" json:"last_used,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + ClientId string `protobuf:"bytes,2,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + CreatedAt int64 `protobuf:"varint,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + LastUsed int64 `protobuf:"varint,6,opt,name=last_used,json=lastUsed,proto3" json:"last_used,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *RefreshTokenRef) Reset() { *x = RefreshTokenRef{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *RefreshTokenRef) String() string { @@ -1037,8 +1881,8 @@ func (x *RefreshTokenRef) String() string { func (*RefreshTokenRef) ProtoMessage() {} func (x *RefreshTokenRef) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[18] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[34] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1050,7 +1894,7 @@ func (x *RefreshTokenRef) ProtoReflect() protoreflect.Message { // Deprecated: Use RefreshTokenRef.ProtoReflect.Descriptor instead. func (*RefreshTokenRef) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{18} + return file_api_v2_api_proto_rawDescGZIP(), []int{34} } func (x *RefreshTokenRef) GetId() string { @@ -1083,21 +1927,18 @@ func (x *RefreshTokenRef) GetLastUsed() int64 { // ListRefreshReq is a request to enumerate the refresh tokens of a user. type ListRefreshReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // The "sub" claim returned in the ID Token. - UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ListRefreshReq) Reset() { *x = ListRefreshReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ListRefreshReq) String() string { @@ -1107,8 +1948,8 @@ func (x *ListRefreshReq) String() string { func (*ListRefreshReq) ProtoMessage() {} func (x *ListRefreshReq) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[19] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[35] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1120,7 +1961,7 @@ func (x *ListRefreshReq) ProtoReflect() protoreflect.Message { // Deprecated: Use ListRefreshReq.ProtoReflect.Descriptor instead. func (*ListRefreshReq) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{19} + return file_api_v2_api_proto_rawDescGZIP(), []int{35} } func (x *ListRefreshReq) GetUserId() string { @@ -1132,20 +1973,17 @@ func (x *ListRefreshReq) GetUserId() string { // ListRefreshResp returns a list of refresh tokens for a user. type ListRefreshResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + RefreshTokens []*RefreshTokenRef `protobuf:"bytes,1,rep,name=refresh_tokens,json=refreshTokens,proto3" json:"refresh_tokens,omitempty"` unknownFields protoimpl.UnknownFields - - RefreshTokens []*RefreshTokenRef `protobuf:"bytes,1,rep,name=refresh_tokens,json=refreshTokens,proto3" json:"refresh_tokens,omitempty"` + sizeCache protoimpl.SizeCache } func (x *ListRefreshResp) Reset() { *x = ListRefreshResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ListRefreshResp) String() string { @@ -1155,8 +1993,8 @@ func (x *ListRefreshResp) String() string { func (*ListRefreshResp) ProtoMessage() {} func (x *ListRefreshResp) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[20] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[36] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1168,7 +2006,7 @@ func (x *ListRefreshResp) ProtoReflect() protoreflect.Message { // Deprecated: Use ListRefreshResp.ProtoReflect.Descriptor instead. func (*ListRefreshResp) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{20} + return file_api_v2_api_proto_rawDescGZIP(), []int{36} } func (x *ListRefreshResp) GetRefreshTokens() []*RefreshTokenRef { @@ -1180,22 +2018,19 @@ func (x *ListRefreshResp) GetRefreshTokens() []*RefreshTokenRef { // RevokeRefreshReq is a request to revoke the refresh token of the user-client pair. type RevokeRefreshReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // The "sub" claim returned in the ID Token. - UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` - ClientId string `protobuf:"bytes,2,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + ClientId string `protobuf:"bytes,2,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *RevokeRefreshReq) Reset() { *x = RevokeRefreshReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *RevokeRefreshReq) String() string { @@ -1205,8 +2040,8 @@ func (x *RevokeRefreshReq) String() string { func (*RevokeRefreshReq) ProtoMessage() {} func (x *RevokeRefreshReq) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[21] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[37] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1218,7 +2053,7 @@ func (x *RevokeRefreshReq) ProtoReflect() protoreflect.Message { // Deprecated: Use RevokeRefreshReq.ProtoReflect.Descriptor instead. func (*RevokeRefreshReq) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{21} + return file_api_v2_api_proto_rawDescGZIP(), []int{37} } func (x *RevokeRefreshReq) GetUserId() string { @@ -1237,21 +2072,18 @@ func (x *RevokeRefreshReq) GetClientId() string { // RevokeRefreshResp determines if the refresh token is revoked successfully. type RevokeRefreshResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // Set to true is refresh token was not found and token could not be revoked. - NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` + NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *RevokeRefreshResp) Reset() { *x = RevokeRefreshResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *RevokeRefreshResp) String() string { @@ -1261,8 +2093,8 @@ func (x *RevokeRefreshResp) String() string { func (*RevokeRefreshResp) ProtoMessage() {} func (x *RevokeRefreshResp) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[22] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[38] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1274,7 +2106,7 @@ func (x *RevokeRefreshResp) ProtoReflect() protoreflect.Message { // Deprecated: Use RevokeRefreshResp.ProtoReflect.Descriptor instead. func (*RevokeRefreshResp) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{22} + return file_api_v2_api_proto_rawDescGZIP(), []int{38} } func (x *RevokeRefreshResp) GetNotFound() bool { @@ -1285,21 +2117,18 @@ func (x *RevokeRefreshResp) GetNotFound() bool { } type VerifyPasswordReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` unknownFields protoimpl.UnknownFields - - Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` - Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + sizeCache protoimpl.SizeCache } func (x *VerifyPasswordReq) Reset() { *x = VerifyPasswordReq{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *VerifyPasswordReq) String() string { @@ -1309,8 +2138,8 @@ func (x *VerifyPasswordReq) String() string { func (*VerifyPasswordReq) ProtoMessage() {} func (x *VerifyPasswordReq) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[23] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[39] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1322,7 +2151,7 @@ func (x *VerifyPasswordReq) ProtoReflect() protoreflect.Message { // Deprecated: Use VerifyPasswordReq.ProtoReflect.Descriptor instead. func (*VerifyPasswordReq) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{23} + return file_api_v2_api_proto_rawDescGZIP(), []int{39} } func (x *VerifyPasswordReq) GetEmail() string { @@ -1340,21 +2169,18 @@ func (x *VerifyPasswordReq) GetPassword() string { } type VerifyPasswordResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Verified bool `protobuf:"varint,1,opt,name=verified,proto3" json:"verified,omitempty"` + NotFound bool `protobuf:"varint,2,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` unknownFields protoimpl.UnknownFields - - Verified bool `protobuf:"varint,1,opt,name=verified,proto3" json:"verified,omitempty"` - NotFound bool `protobuf:"varint,2,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` + sizeCache protoimpl.SizeCache } func (x *VerifyPasswordResp) Reset() { *x = VerifyPasswordResp{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[24] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_api_v2_api_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *VerifyPasswordResp) String() string { @@ -1364,8 +2190,8 @@ func (x *VerifyPasswordResp) String() string { func (*VerifyPasswordResp) ProtoMessage() {} func (x *VerifyPasswordResp) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[24] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_api_v2_api_proto_msgTypes[40] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1377,7 +2203,7 @@ func (x *VerifyPasswordResp) ProtoReflect() protoreflect.Message { // Deprecated: Use VerifyPasswordResp.ProtoReflect.Descriptor instead. func (*VerifyPasswordResp) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{24} + return file_api_v2_api_proto_rawDescGZIP(), []int{40} } func (x *VerifyPasswordResp) GetVerified() bool { @@ -1396,7 +2222,7 @@ func (x *VerifyPasswordResp) GetNotFound() bool { var File_api_v2_api_proto protoreflect.FileDescriptor -var file_api_v2_api_proto_rawDesc = []byte{ +var file_api_v2_api_proto_rawDesc = string([]byte{ 0x0a, 0x10, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x61, 0x70, 0x69, 0x22, 0xc1, 0x01, 0x0a, 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, @@ -1410,231 +2236,403 @@ var file_api_v2_api_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x6f, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x6f, 0x55, 0x72, 0x6c, 0x22, 0x36, 0x0a, 0x0f, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x12, 0x23, - 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x22, 0x5e, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x72, 0x65, 0x61, + 0x28, 0x09, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x6f, 0x55, 0x72, 0x6c, 0x22, 0xad, 0x01, 0x0a, 0x0a, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, + 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x5f, 0x75, 0x72, 0x69, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x0c, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x55, 0x72, 0x69, 0x73, 0x12, + 0x23, 0x0a, 0x0d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x50, + 0x65, 0x65, 0x72, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x6f, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x6f, 0x55, 0x72, 0x6c, 0x22, 0x1e, 0x0a, 0x0c, 0x47, + 0x65, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x34, 0x0a, 0x0d, 0x47, + 0x65, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x23, 0x0a, 0x06, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x22, 0x36, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x52, 0x65, 0x71, 0x12, 0x23, 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22, 0x5e, 0x0a, 0x10, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x25, 0x0a, + 0x0e, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x45, 0x78, + 0x69, 0x73, 0x74, 0x73, 0x12, 0x23, 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22, 0x21, 0x0a, 0x0f, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x2f, 0x0a, 0x10, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x9a, 0x01, + 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x5f, 0x75, 0x72, + 0x69, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x55, 0x72, 0x69, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x19, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x6f, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x6f, 0x55, 0x72, 0x6c, 0x22, 0x2f, 0x0a, 0x10, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1b, + 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x0f, 0x0a, 0x0d, 0x4c, + 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x22, 0x3b, 0x0a, 0x0e, + 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x29, + 0x0a, 0x07, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x07, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x69, 0x0a, 0x08, 0x50, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x68, + 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, + 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, + 0x65, 0x72, 0x49, 0x64, 0x22, 0x3e, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x12, 0x29, 0x0a, 0x08, 0x70, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x22, 0x3b, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, + 0x72, 0x65, 0x61, 0x64, 0x79, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, + 0x73, 0x22, 0x67, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x19, 0x0a, 0x08, + 0x6e, 0x65, 0x77, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x6e, 0x65, 0x77, 0x48, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x77, 0x5f, 0x75, + 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, + 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x31, 0x0a, 0x12, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x29, 0x0a, + 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, + 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x31, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1b, + 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x11, 0x0a, 0x0f, 0x4c, + 0x69, 0x73, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x22, 0x3f, + 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x12, 0x2b, 0x0a, 0x09, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x52, 0x09, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x22, + 0x5b, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x42, 0x0a, 0x12, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, + 0x65, 0x71, 0x12, 0x2c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x22, 0x3c, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0d, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x23, - 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x22, 0x21, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x2f, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, + 0x0d, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, 0x79, + 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x19, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, + 0x77, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, + 0x6e, 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x32, 0x0a, 0x13, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x24, 0x0a, + 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x02, 0x69, 0x64, 0x22, 0x32, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, - 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x9a, 0x01, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x72, - 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x5f, 0x75, 0x72, 0x69, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x55, 0x72, 0x69, 0x73, - 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x65, 0x72, - 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, - 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x6f, 0x67, - 0x6f, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6c, 0x6f, 0x67, - 0x6f, 0x55, 0x72, 0x6c, 0x22, 0x2f, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, - 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, - 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x69, 0x0a, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, - 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x75, - 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, - 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, - 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, - 0x22, 0x3e, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, - 0x72, 0x64, 0x52, 0x65, 0x71, 0x12, 0x29, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61, - 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x22, 0x3b, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, - 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, - 0x79, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, - 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, 0x67, 0x0a, - 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, + 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x12, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x22, 0x43, 0x0a, 0x11, 0x4c, + 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x12, 0x2e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, + 0x22, 0x0c, 0x0a, 0x0a, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x22, 0x37, + 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x16, 0x0a, + 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x70, 0x69, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x03, 0x61, 0x70, 0x69, 0x22, 0x0e, 0x0a, 0x0c, 0x44, 0x69, 0x73, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x22, 0xb0, 0x06, 0x0a, 0x0d, 0x44, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, + 0x75, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, + 0x72, 0x12, 0x35, 0x0a, 0x16, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x15, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, + 0x19, 0x0a, 0x08, 0x6a, 0x77, 0x6b, 0x73, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x6a, 0x77, 0x6b, 0x73, 0x55, 0x72, 0x69, 0x12, 0x2b, 0x0a, 0x11, 0x75, 0x73, + 0x65, 0x72, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x66, 0x6f, 0x45, + 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x42, 0x0a, 0x1d, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1b, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x35, 0x0a, 0x16, 0x69, + 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x64, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x69, 0x6e, 0x74, + 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x08, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x13, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x53, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x18, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x16, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x12, 0x36, 0x0a, 0x17, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x15, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x53, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4f, 0x0a, 0x25, 0x69, 0x64, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x6c, 0x67, + 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x20, 0x69, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x41, 0x6c, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, + 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x47, 0x0a, 0x20, 0x63, 0x6f, 0x64, + 0x65, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x73, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x0c, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x1d, 0x63, 0x6f, 0x64, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, + 0x67, 0x65, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x5f, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x63, + 0x6f, 0x70, 0x65, 0x73, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x50, 0x0a, + 0x25, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, + 0x61, 0x75, 0x74, 0x68, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x5f, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x09, 0x52, 0x21, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x4d, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, + 0x29, 0x0a, 0x10, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x6c, 0x61, 0x69, 0x6d, + 0x73, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x22, 0x7a, 0x0a, 0x0f, 0x52, 0x65, + 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x66, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, + 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x61, 0x73, + 0x74, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6c, 0x61, + 0x73, 0x74, 0x55, 0x73, 0x65, 0x64, 0x22, 0x29, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, + 0x64, 0x22, 0x4e, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, + 0x52, 0x65, 0x73, 0x70, 0x12, 0x3b, 0x0a, 0x0e, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, + 0x65, 0x66, 0x52, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x73, 0x22, 0x48, 0x0a, 0x10, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, + 0x73, 0x68, 0x52, 0x65, 0x71, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1b, + 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x30, 0x0a, 0x11, 0x52, + 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, + 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x45, 0x0a, + 0x11, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, - 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x48, - 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x77, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x65, 0x77, 0x55, 0x73, - 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x31, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x09, - 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x29, 0x0a, 0x11, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x12, 0x14, - 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, - 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x31, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, - 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, - 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, - 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x11, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x50, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x22, 0x3f, 0x0a, 0x10, 0x4c, 0x69, - 0x73, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x2b, - 0x0a, 0x09, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x52, 0x09, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x22, 0x0c, 0x0a, 0x0a, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x22, 0x37, 0x0a, 0x0b, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x12, 0x10, 0x0a, 0x03, 0x61, 0x70, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x61, - 0x70, 0x69, 0x22, 0x7a, 0x0a, 0x0f, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x52, 0x65, 0x66, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, - 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x73, 0x65, 0x64, 0x22, 0x29, - 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, - 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x4e, 0x0a, 0x0f, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x12, 0x3b, 0x0a, 0x0e, - 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, - 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x66, 0x52, 0x0d, 0x72, 0x65, 0x66, 0x72, - 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0x48, 0x0a, 0x10, 0x52, 0x65, 0x76, - 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x12, 0x17, 0x0a, - 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x49, 0x64, 0x22, 0x30, 0x0a, 0x11, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, - 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, - 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, - 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x45, 0x0a, 0x11, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, - 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, - 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x4d, 0x0a, 0x12, - 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x1b, - 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x32, 0xc7, 0x05, 0x0a, 0x03, - 0x44, 0x65, 0x78, 0x12, 0x3d, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, - 0x00, 0x12, 0x3d, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, - 0x12, 0x43, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, - 0x72, 0x64, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, + 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x22, 0x4d, 0x0a, 0x12, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x76, 0x65, + 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x76, 0x65, + 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, + 0x75, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f, + 0x75, 0x6e, 0x64, 0x32, 0x8b, 0x09, 0x0a, 0x03, 0x44, 0x65, 0x78, 0x12, 0x34, 0x0a, 0x09, 0x47, + 0x65, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, + 0x65, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, + 0x00, 0x12, 0x3d, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, + 0x12, 0x3d, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, + 0x3d, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, + 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x38, + 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x12, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x71, 0x1a, 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, - 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, - 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, - 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, 0x2e, 0x61, + 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, + 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x43, 0x0a, + 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, + 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, - 0x64, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, - 0x3e, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, - 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, - 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, - 0x31, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0f, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x10, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, - 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, - 0x68, 0x12, 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, - 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x40, - 0x0a, 0x0d, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, - 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, - 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x76, - 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, - 0x12, 0x43, 0x0a, 0x0e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, - 0x72, 0x64, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, - 0x65, 0x73, 0x70, 0x22, 0x00, 0x42, 0x36, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x72, - 0x65, 0x6f, 0x73, 0x2e, 0x64, 0x65, 0x78, 0x2e, 0x61, 0x70, 0x69, 0x5a, 0x20, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, 0x78, 0x69, 0x64, 0x70, 0x2f, 0x64, - 0x65, 0x78, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, -} + 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x50, + 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x15, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x17, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, + 0x46, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x12, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x17, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, + 0x41, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x73, 0x12, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x22, 0x00, 0x12, 0x31, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x1a, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x79, 0x12, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, + 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x3a, + 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x13, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, + 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, + 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0d, 0x52, 0x65, + 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x15, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, + 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, + 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, + 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x72, + 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, + 0x00, 0x42, 0x36, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x6f, 0x73, 0x2e, + 0x64, 0x65, 0x78, 0x2e, 0x61, 0x70, 0x69, 0x5a, 0x20, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, 0x78, 0x69, 0x64, 0x70, 0x2f, 0x64, 0x65, 0x78, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +}) var ( file_api_v2_api_proto_rawDescOnce sync.Once - file_api_v2_api_proto_rawDescData = file_api_v2_api_proto_rawDesc + file_api_v2_api_proto_rawDescData []byte ) func file_api_v2_api_proto_rawDescGZIP() []byte { file_api_v2_api_proto_rawDescOnce.Do(func() { - file_api_v2_api_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_v2_api_proto_rawDescData) + file_api_v2_api_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_api_v2_api_proto_rawDesc), len(file_api_v2_api_proto_rawDesc))) }) return file_api_v2_api_proto_rawDescData } -var file_api_v2_api_proto_msgTypes = make([]protoimpl.MessageInfo, 25) -var file_api_v2_api_proto_goTypes = []interface{}{ - (*Client)(nil), // 0: api.Client - (*CreateClientReq)(nil), // 1: api.CreateClientReq - (*CreateClientResp)(nil), // 2: api.CreateClientResp - (*DeleteClientReq)(nil), // 3: api.DeleteClientReq - (*DeleteClientResp)(nil), // 4: api.DeleteClientResp - (*UpdateClientReq)(nil), // 5: api.UpdateClientReq - (*UpdateClientResp)(nil), // 6: api.UpdateClientResp - (*Password)(nil), // 7: api.Password - (*CreatePasswordReq)(nil), // 8: api.CreatePasswordReq - (*CreatePasswordResp)(nil), // 9: api.CreatePasswordResp - (*UpdatePasswordReq)(nil), // 10: api.UpdatePasswordReq - (*UpdatePasswordResp)(nil), // 11: api.UpdatePasswordResp - (*DeletePasswordReq)(nil), // 12: api.DeletePasswordReq - (*DeletePasswordResp)(nil), // 13: api.DeletePasswordResp - (*ListPasswordReq)(nil), // 14: api.ListPasswordReq - (*ListPasswordResp)(nil), // 15: api.ListPasswordResp - (*VersionReq)(nil), // 16: api.VersionReq - (*VersionResp)(nil), // 17: api.VersionResp - (*RefreshTokenRef)(nil), // 18: api.RefreshTokenRef - (*ListRefreshReq)(nil), // 19: api.ListRefreshReq - (*ListRefreshResp)(nil), // 20: api.ListRefreshResp - (*RevokeRefreshReq)(nil), // 21: api.RevokeRefreshReq - (*RevokeRefreshResp)(nil), // 22: api.RevokeRefreshResp - (*VerifyPasswordReq)(nil), // 23: api.VerifyPasswordReq - (*VerifyPasswordResp)(nil), // 24: api.VerifyPasswordResp +var file_api_v2_api_proto_msgTypes = make([]protoimpl.MessageInfo, 41) +var file_api_v2_api_proto_goTypes = []any{ + (*Client)(nil), // 0: api.Client + (*ClientInfo)(nil), // 1: api.ClientInfo + (*GetClientReq)(nil), // 2: api.GetClientReq + (*GetClientResp)(nil), // 3: api.GetClientResp + (*CreateClientReq)(nil), // 4: api.CreateClientReq + (*CreateClientResp)(nil), // 5: api.CreateClientResp + (*DeleteClientReq)(nil), // 6: api.DeleteClientReq + (*DeleteClientResp)(nil), // 7: api.DeleteClientResp + (*UpdateClientReq)(nil), // 8: api.UpdateClientReq + (*UpdateClientResp)(nil), // 9: api.UpdateClientResp + (*ListClientReq)(nil), // 10: api.ListClientReq + (*ListClientResp)(nil), // 11: api.ListClientResp + (*Password)(nil), // 12: api.Password + (*CreatePasswordReq)(nil), // 13: api.CreatePasswordReq + (*CreatePasswordResp)(nil), // 14: api.CreatePasswordResp + (*UpdatePasswordReq)(nil), // 15: api.UpdatePasswordReq + (*UpdatePasswordResp)(nil), // 16: api.UpdatePasswordResp + (*DeletePasswordReq)(nil), // 17: api.DeletePasswordReq + (*DeletePasswordResp)(nil), // 18: api.DeletePasswordResp + (*ListPasswordReq)(nil), // 19: api.ListPasswordReq + (*ListPasswordResp)(nil), // 20: api.ListPasswordResp + (*Connector)(nil), // 21: api.Connector + (*CreateConnectorReq)(nil), // 22: api.CreateConnectorReq + (*CreateConnectorResp)(nil), // 23: api.CreateConnectorResp + (*UpdateConnectorReq)(nil), // 24: api.UpdateConnectorReq + (*UpdateConnectorResp)(nil), // 25: api.UpdateConnectorResp + (*DeleteConnectorReq)(nil), // 26: api.DeleteConnectorReq + (*DeleteConnectorResp)(nil), // 27: api.DeleteConnectorResp + (*ListConnectorReq)(nil), // 28: api.ListConnectorReq + (*ListConnectorResp)(nil), // 29: api.ListConnectorResp + (*VersionReq)(nil), // 30: api.VersionReq + (*VersionResp)(nil), // 31: api.VersionResp + (*DiscoveryReq)(nil), // 32: api.DiscoveryReq + (*DiscoveryResp)(nil), // 33: api.DiscoveryResp + (*RefreshTokenRef)(nil), // 34: api.RefreshTokenRef + (*ListRefreshReq)(nil), // 35: api.ListRefreshReq + (*ListRefreshResp)(nil), // 36: api.ListRefreshResp + (*RevokeRefreshReq)(nil), // 37: api.RevokeRefreshReq + (*RevokeRefreshResp)(nil), // 38: api.RevokeRefreshResp + (*VerifyPasswordReq)(nil), // 39: api.VerifyPasswordReq + (*VerifyPasswordResp)(nil), // 40: api.VerifyPasswordResp } var file_api_v2_api_proto_depIdxs = []int32{ - 0, // 0: api.CreateClientReq.client:type_name -> api.Client - 0, // 1: api.CreateClientResp.client:type_name -> api.Client - 7, // 2: api.CreatePasswordReq.password:type_name -> api.Password - 7, // 3: api.ListPasswordResp.passwords:type_name -> api.Password - 18, // 4: api.ListRefreshResp.refresh_tokens:type_name -> api.RefreshTokenRef - 1, // 5: api.Dex.CreateClient:input_type -> api.CreateClientReq - 5, // 6: api.Dex.UpdateClient:input_type -> api.UpdateClientReq - 3, // 7: api.Dex.DeleteClient:input_type -> api.DeleteClientReq - 8, // 8: api.Dex.CreatePassword:input_type -> api.CreatePasswordReq - 10, // 9: api.Dex.UpdatePassword:input_type -> api.UpdatePasswordReq - 12, // 10: api.Dex.DeletePassword:input_type -> api.DeletePasswordReq - 14, // 11: api.Dex.ListPasswords:input_type -> api.ListPasswordReq - 16, // 12: api.Dex.GetVersion:input_type -> api.VersionReq - 19, // 13: api.Dex.ListRefresh:input_type -> api.ListRefreshReq - 21, // 14: api.Dex.RevokeRefresh:input_type -> api.RevokeRefreshReq - 23, // 15: api.Dex.VerifyPassword:input_type -> api.VerifyPasswordReq - 2, // 16: api.Dex.CreateClient:output_type -> api.CreateClientResp - 6, // 17: api.Dex.UpdateClient:output_type -> api.UpdateClientResp - 4, // 18: api.Dex.DeleteClient:output_type -> api.DeleteClientResp - 9, // 19: api.Dex.CreatePassword:output_type -> api.CreatePasswordResp - 11, // 20: api.Dex.UpdatePassword:output_type -> api.UpdatePasswordResp - 13, // 21: api.Dex.DeletePassword:output_type -> api.DeletePasswordResp - 15, // 22: api.Dex.ListPasswords:output_type -> api.ListPasswordResp - 17, // 23: api.Dex.GetVersion:output_type -> api.VersionResp - 20, // 24: api.Dex.ListRefresh:output_type -> api.ListRefreshResp - 22, // 25: api.Dex.RevokeRefresh:output_type -> api.RevokeRefreshResp - 24, // 26: api.Dex.VerifyPassword:output_type -> api.VerifyPasswordResp - 16, // [16:27] is the sub-list for method output_type - 5, // [5:16] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 0, // 0: api.GetClientResp.client:type_name -> api.Client + 0, // 1: api.CreateClientReq.client:type_name -> api.Client + 0, // 2: api.CreateClientResp.client:type_name -> api.Client + 1, // 3: api.ListClientResp.clients:type_name -> api.ClientInfo + 12, // 4: api.CreatePasswordReq.password:type_name -> api.Password + 12, // 5: api.ListPasswordResp.passwords:type_name -> api.Password + 21, // 6: api.CreateConnectorReq.connector:type_name -> api.Connector + 21, // 7: api.ListConnectorResp.connectors:type_name -> api.Connector + 34, // 8: api.ListRefreshResp.refresh_tokens:type_name -> api.RefreshTokenRef + 2, // 9: api.Dex.GetClient:input_type -> api.GetClientReq + 4, // 10: api.Dex.CreateClient:input_type -> api.CreateClientReq + 8, // 11: api.Dex.UpdateClient:input_type -> api.UpdateClientReq + 6, // 12: api.Dex.DeleteClient:input_type -> api.DeleteClientReq + 10, // 13: api.Dex.ListClients:input_type -> api.ListClientReq + 13, // 14: api.Dex.CreatePassword:input_type -> api.CreatePasswordReq + 15, // 15: api.Dex.UpdatePassword:input_type -> api.UpdatePasswordReq + 17, // 16: api.Dex.DeletePassword:input_type -> api.DeletePasswordReq + 19, // 17: api.Dex.ListPasswords:input_type -> api.ListPasswordReq + 22, // 18: api.Dex.CreateConnector:input_type -> api.CreateConnectorReq + 24, // 19: api.Dex.UpdateConnector:input_type -> api.UpdateConnectorReq + 26, // 20: api.Dex.DeleteConnector:input_type -> api.DeleteConnectorReq + 28, // 21: api.Dex.ListConnectors:input_type -> api.ListConnectorReq + 30, // 22: api.Dex.GetVersion:input_type -> api.VersionReq + 32, // 23: api.Dex.GetDiscovery:input_type -> api.DiscoveryReq + 35, // 24: api.Dex.ListRefresh:input_type -> api.ListRefreshReq + 37, // 25: api.Dex.RevokeRefresh:input_type -> api.RevokeRefreshReq + 39, // 26: api.Dex.VerifyPassword:input_type -> api.VerifyPasswordReq + 3, // 27: api.Dex.GetClient:output_type -> api.GetClientResp + 5, // 28: api.Dex.CreateClient:output_type -> api.CreateClientResp + 9, // 29: api.Dex.UpdateClient:output_type -> api.UpdateClientResp + 7, // 30: api.Dex.DeleteClient:output_type -> api.DeleteClientResp + 11, // 31: api.Dex.ListClients:output_type -> api.ListClientResp + 14, // 32: api.Dex.CreatePassword:output_type -> api.CreatePasswordResp + 16, // 33: api.Dex.UpdatePassword:output_type -> api.UpdatePasswordResp + 18, // 34: api.Dex.DeletePassword:output_type -> api.DeletePasswordResp + 20, // 35: api.Dex.ListPasswords:output_type -> api.ListPasswordResp + 23, // 36: api.Dex.CreateConnector:output_type -> api.CreateConnectorResp + 25, // 37: api.Dex.UpdateConnector:output_type -> api.UpdateConnectorResp + 27, // 38: api.Dex.DeleteConnector:output_type -> api.DeleteConnectorResp + 29, // 39: api.Dex.ListConnectors:output_type -> api.ListConnectorResp + 31, // 40: api.Dex.GetVersion:output_type -> api.VersionResp + 33, // 41: api.Dex.GetDiscovery:output_type -> api.DiscoveryResp + 36, // 42: api.Dex.ListRefresh:output_type -> api.ListRefreshResp + 38, // 43: api.Dex.RevokeRefresh:output_type -> api.RevokeRefreshResp + 40, // 44: api.Dex.VerifyPassword:output_type -> api.VerifyPasswordResp + 27, // [27:45] is the sub-list for method output_type + 9, // [9:27] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name } func init() { file_api_v2_api_proto_init() } @@ -1642,315 +2640,13 @@ func file_api_v2_api_proto_init() { if File_api_v2_api_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_api_v2_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Client); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateClientReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateClientResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteClientReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteClientResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateClientReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateClientResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Password); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreatePasswordReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreatePasswordResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdatePasswordReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdatePasswordResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeletePasswordReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeletePasswordResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListPasswordReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListPasswordResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VersionReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VersionResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RefreshTokenRef); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRefreshReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRefreshResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RevokeRefreshReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RevokeRefreshResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VerifyPasswordReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_api_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VerifyPasswordResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_api_v2_api_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_v2_api_proto_rawDesc), len(file_api_v2_api_proto_rawDesc)), NumEnums: 0, - NumMessages: 25, + NumMessages: 41, NumExtensions: 0, NumServices: 1, }, @@ -1959,7 +2655,6 @@ func file_api_v2_api_proto_init() { MessageInfos: file_api_v2_api_proto_msgTypes, }.Build() File_api_v2_api_proto = out.File - file_api_v2_api_proto_rawDesc = nil file_api_v2_api_proto_goTypes = nil file_api_v2_api_proto_depIdxs = nil } diff --git a/api/v2/api.proto b/api/v2/api.proto index 82a2e2afa1..fc14913b81 100644 --- a/api/v2/api.proto +++ b/api/v2/api.proto @@ -16,6 +16,27 @@ message Client { string logo_url = 7; } +// ClientInfo represents an OAuth2 client without sensitive information. +message ClientInfo { + string id = 1; + repeated string redirect_uris = 2; + repeated string trusted_peers = 3; + bool public = 4; + string name = 5; + string logo_url = 6; +} + +// GetClientReq is a request to retrieve client details. +message GetClientReq { + // The ID of the client. + string id = 1; +} + +// GetClientResp returns the client details. +message GetClientResp { + Client client = 1; +} + // CreateClientReq is a request to make a client. message CreateClientReq { Client client = 1; @@ -52,6 +73,14 @@ message UpdateClientResp { bool not_found = 1; } +// ListClientReq is a request to enumerate clients. +message ListClientReq {} + +// ListClientResp returns a list of clients. +message ListClientResp { + repeated ClientInfo clients = 1; +} + // TODO(ericchiang): expand this. // Password is an email for password mapping managed by the storage. @@ -105,6 +134,56 @@ message ListPasswordResp { repeated Password passwords = 1; } +// Connector is a strategy used by Dex for authenticating a user against another identity provider +message Connector { + string id = 1; + string type = 2; + string name = 3; + bytes config = 4; +} + +// CreateConnectorReq is a request to make a connector. +message CreateConnectorReq { + Connector connector = 1; +} + +// CreateConnectorResp returns the response from creating a connector. +message CreateConnectorResp { + bool already_exists = 1; +} + +// UpdateConnectorReq is a request to modify an existing connector. +message UpdateConnectorReq { + // The id used to lookup the connector. This field cannot be modified + string id = 1; + string new_type = 2; + string new_name = 3; + bytes new_config = 4; +} + +// UpdateConnectorResp returns the response from modifying an existing connector. +message UpdateConnectorResp { + bool not_found = 1; +} + +// DeleteConnectorReq is a request to delete a connector. +message DeleteConnectorReq { + string id = 1; +} + +// DeleteConnectorResp returns the response from deleting a connector. +message DeleteConnectorResp { + bool not_found = 1; +} + +// ListConnectorReq is a request to enumerate connectors. +message ListConnectorReq {} + +// ListConnectorResp returns a list of connectors. +message ListConnectorResp { + repeated Connector connectors = 1; +} + // VersionReq is a request to fetch version info. message VersionReq {} @@ -112,11 +191,33 @@ message VersionReq {} message VersionResp { // Semantic version of the server. string server = 1; - // Numeric version of the API. It increases everytime a new call is added to the API. + // Numeric version of the API. It increases every time a new call is added to the API. // Clients should use this info to determine if the server supports specific features. int32 api = 2; } +// DiscoveryReq is a request to fetch discover information. +message DiscoveryReq {} + +//DiscoverResp holds the version oidc disovery info. +message DiscoveryResp { + string issuer = 1; + string authorization_endpoint = 2; + string token_endpoint = 3; + string jwks_uri = 4; + string userinfo_endpoint = 5; + string device_authorization_endpoint = 6; + string introspection_endpoint = 7; + repeated string grant_types_supported = 8; + repeated string response_types_supported = 9; + repeated string subject_types_supported = 10; + repeated string id_token_signing_alg_values_supported = 11; + repeated string code_challenge_methods_supported = 12; + repeated string scopes_supported = 13; + repeated string token_endpoint_auth_methods_supported = 14; + repeated string claims_supported = 15; +} + // RefreshTokenRef contains the metadata for a refresh token that is managed by the storage. message RefreshTokenRef { // ID of the refresh token. @@ -162,12 +263,16 @@ message VerifyPasswordResp { // Dex represents the dex gRPC service. service Dex { + // GetClient gets a client. + rpc GetClient(GetClientReq) returns (GetClientResp) {}; // CreateClient creates a client. rpc CreateClient(CreateClientReq) returns (CreateClientResp) {}; // UpdateClient updates an existing client rpc UpdateClient(UpdateClientReq) returns (UpdateClientResp) {}; // DeleteClient deletes the provided client. rpc DeleteClient(DeleteClientReq) returns (DeleteClientResp) {}; + // ListClients lists all client entries. + rpc ListClients(ListClientReq) returns (ListClientResp) {}; // CreatePassword creates a password. rpc CreatePassword(CreatePasswordReq) returns (CreatePasswordResp) {}; // UpdatePassword modifies existing password. @@ -176,8 +281,18 @@ service Dex { rpc DeletePassword(DeletePasswordReq) returns (DeletePasswordResp) {}; // ListPassword lists all password entries. rpc ListPasswords(ListPasswordReq) returns (ListPasswordResp) {}; + // CreateConnector creates a connector. + rpc CreateConnector(CreateConnectorReq) returns (CreateConnectorResp) {}; + // UpdateConnector modifies existing connector. + rpc UpdateConnector(UpdateConnectorReq) returns (UpdateConnectorResp) {}; + // DeleteConnector deletes the connector. + rpc DeleteConnector(DeleteConnectorReq) returns (DeleteConnectorResp) {}; + // ListConnectors lists all connector entries. + rpc ListConnectors(ListConnectorReq) returns (ListConnectorResp) {}; // GetVersion returns version information of the server. rpc GetVersion(VersionReq) returns (VersionResp) {}; + // GetDiscovery returns discovery information of the server. + rpc GetDiscovery(DiscoveryReq) returns (DiscoveryResp) {}; // ListRefresh lists all the refresh token entries for a particular user. rpc ListRefresh(ListRefreshReq) returns (ListRefreshResp) {}; // RevokeRefresh revokes the refresh token for the provided user-client pair. diff --git a/api/v2/api_grpc.pb.go b/api/v2/api_grpc.pb.go index 8b3b10bc52..3fe210e6ff 100644 --- a/api/v2/api_grpc.pb.go +++ b/api/v2/api_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v5.29.3 +// source: api/v2/api.proto package api @@ -11,19 +15,46 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + Dex_GetClient_FullMethodName = "/api.Dex/GetClient" + Dex_CreateClient_FullMethodName = "/api.Dex/CreateClient" + Dex_UpdateClient_FullMethodName = "/api.Dex/UpdateClient" + Dex_DeleteClient_FullMethodName = "/api.Dex/DeleteClient" + Dex_ListClients_FullMethodName = "/api.Dex/ListClients" + Dex_CreatePassword_FullMethodName = "/api.Dex/CreatePassword" + Dex_UpdatePassword_FullMethodName = "/api.Dex/UpdatePassword" + Dex_DeletePassword_FullMethodName = "/api.Dex/DeletePassword" + Dex_ListPasswords_FullMethodName = "/api.Dex/ListPasswords" + Dex_CreateConnector_FullMethodName = "/api.Dex/CreateConnector" + Dex_UpdateConnector_FullMethodName = "/api.Dex/UpdateConnector" + Dex_DeleteConnector_FullMethodName = "/api.Dex/DeleteConnector" + Dex_ListConnectors_FullMethodName = "/api.Dex/ListConnectors" + Dex_GetVersion_FullMethodName = "/api.Dex/GetVersion" + Dex_GetDiscovery_FullMethodName = "/api.Dex/GetDiscovery" + Dex_ListRefresh_FullMethodName = "/api.Dex/ListRefresh" + Dex_RevokeRefresh_FullMethodName = "/api.Dex/RevokeRefresh" + Dex_VerifyPassword_FullMethodName = "/api.Dex/VerifyPassword" +) // DexClient is the client API for Dex service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// Dex represents the dex gRPC service. type DexClient interface { + // GetClient gets a client. + GetClient(ctx context.Context, in *GetClientReq, opts ...grpc.CallOption) (*GetClientResp, error) // CreateClient creates a client. CreateClient(ctx context.Context, in *CreateClientReq, opts ...grpc.CallOption) (*CreateClientResp, error) // UpdateClient updates an existing client UpdateClient(ctx context.Context, in *UpdateClientReq, opts ...grpc.CallOption) (*UpdateClientResp, error) // DeleteClient deletes the provided client. DeleteClient(ctx context.Context, in *DeleteClientReq, opts ...grpc.CallOption) (*DeleteClientResp, error) + // ListClients lists all client entries. + ListClients(ctx context.Context, in *ListClientReq, opts ...grpc.CallOption) (*ListClientResp, error) // CreatePassword creates a password. CreatePassword(ctx context.Context, in *CreatePasswordReq, opts ...grpc.CallOption) (*CreatePasswordResp, error) // UpdatePassword modifies existing password. @@ -32,8 +63,18 @@ type DexClient interface { DeletePassword(ctx context.Context, in *DeletePasswordReq, opts ...grpc.CallOption) (*DeletePasswordResp, error) // ListPassword lists all password entries. ListPasswords(ctx context.Context, in *ListPasswordReq, opts ...grpc.CallOption) (*ListPasswordResp, error) + // CreateConnector creates a connector. + CreateConnector(ctx context.Context, in *CreateConnectorReq, opts ...grpc.CallOption) (*CreateConnectorResp, error) + // UpdateConnector modifies existing connector. + UpdateConnector(ctx context.Context, in *UpdateConnectorReq, opts ...grpc.CallOption) (*UpdateConnectorResp, error) + // DeleteConnector deletes the connector. + DeleteConnector(ctx context.Context, in *DeleteConnectorReq, opts ...grpc.CallOption) (*DeleteConnectorResp, error) + // ListConnectors lists all connector entries. + ListConnectors(ctx context.Context, in *ListConnectorReq, opts ...grpc.CallOption) (*ListConnectorResp, error) // GetVersion returns version information of the server. GetVersion(ctx context.Context, in *VersionReq, opts ...grpc.CallOption) (*VersionResp, error) + // GetDiscovery returns discovery information of the server. + GetDiscovery(ctx context.Context, in *DiscoveryReq, opts ...grpc.CallOption) (*DiscoveryResp, error) // ListRefresh lists all the refresh token entries for a particular user. ListRefresh(ctx context.Context, in *ListRefreshReq, opts ...grpc.CallOption) (*ListRefreshResp, error) // RevokeRefresh revokes the refresh token for the provided user-client pair. @@ -52,9 +93,20 @@ func NewDexClient(cc grpc.ClientConnInterface) DexClient { return &dexClient{cc} } +func (c *dexClient) GetClient(ctx context.Context, in *GetClientReq, opts ...grpc.CallOption) (*GetClientResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetClientResp) + err := c.cc.Invoke(ctx, Dex_GetClient_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *dexClient) CreateClient(ctx context.Context, in *CreateClientReq, opts ...grpc.CallOption) (*CreateClientResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(CreateClientResp) - err := c.cc.Invoke(ctx, "/api.Dex/CreateClient", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_CreateClient_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -62,8 +114,9 @@ func (c *dexClient) CreateClient(ctx context.Context, in *CreateClientReq, opts } func (c *dexClient) UpdateClient(ctx context.Context, in *UpdateClientReq, opts ...grpc.CallOption) (*UpdateClientResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(UpdateClientResp) - err := c.cc.Invoke(ctx, "/api.Dex/UpdateClient", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_UpdateClient_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -71,8 +124,19 @@ func (c *dexClient) UpdateClient(ctx context.Context, in *UpdateClientReq, opts } func (c *dexClient) DeleteClient(ctx context.Context, in *DeleteClientReq, opts ...grpc.CallOption) (*DeleteClientResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(DeleteClientResp) - err := c.cc.Invoke(ctx, "/api.Dex/DeleteClient", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_DeleteClient_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dexClient) ListClients(ctx context.Context, in *ListClientReq, opts ...grpc.CallOption) (*ListClientResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListClientResp) + err := c.cc.Invoke(ctx, Dex_ListClients_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -80,8 +144,9 @@ func (c *dexClient) DeleteClient(ctx context.Context, in *DeleteClientReq, opts } func (c *dexClient) CreatePassword(ctx context.Context, in *CreatePasswordReq, opts ...grpc.CallOption) (*CreatePasswordResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(CreatePasswordResp) - err := c.cc.Invoke(ctx, "/api.Dex/CreatePassword", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_CreatePassword_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -89,8 +154,9 @@ func (c *dexClient) CreatePassword(ctx context.Context, in *CreatePasswordReq, o } func (c *dexClient) UpdatePassword(ctx context.Context, in *UpdatePasswordReq, opts ...grpc.CallOption) (*UpdatePasswordResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(UpdatePasswordResp) - err := c.cc.Invoke(ctx, "/api.Dex/UpdatePassword", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_UpdatePassword_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -98,8 +164,9 @@ func (c *dexClient) UpdatePassword(ctx context.Context, in *UpdatePasswordReq, o } func (c *dexClient) DeletePassword(ctx context.Context, in *DeletePasswordReq, opts ...grpc.CallOption) (*DeletePasswordResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(DeletePasswordResp) - err := c.cc.Invoke(ctx, "/api.Dex/DeletePassword", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_DeletePassword_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -107,8 +174,49 @@ func (c *dexClient) DeletePassword(ctx context.Context, in *DeletePasswordReq, o } func (c *dexClient) ListPasswords(ctx context.Context, in *ListPasswordReq, opts ...grpc.CallOption) (*ListPasswordResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ListPasswordResp) - err := c.cc.Invoke(ctx, "/api.Dex/ListPasswords", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_ListPasswords_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dexClient) CreateConnector(ctx context.Context, in *CreateConnectorReq, opts ...grpc.CallOption) (*CreateConnectorResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreateConnectorResp) + err := c.cc.Invoke(ctx, Dex_CreateConnector_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dexClient) UpdateConnector(ctx context.Context, in *UpdateConnectorReq, opts ...grpc.CallOption) (*UpdateConnectorResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(UpdateConnectorResp) + err := c.cc.Invoke(ctx, Dex_UpdateConnector_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dexClient) DeleteConnector(ctx context.Context, in *DeleteConnectorReq, opts ...grpc.CallOption) (*DeleteConnectorResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(DeleteConnectorResp) + err := c.cc.Invoke(ctx, Dex_DeleteConnector_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dexClient) ListConnectors(ctx context.Context, in *ListConnectorReq, opts ...grpc.CallOption) (*ListConnectorResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListConnectorResp) + err := c.cc.Invoke(ctx, Dex_ListConnectors_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -116,8 +224,19 @@ func (c *dexClient) ListPasswords(ctx context.Context, in *ListPasswordReq, opts } func (c *dexClient) GetVersion(ctx context.Context, in *VersionReq, opts ...grpc.CallOption) (*VersionResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(VersionResp) - err := c.cc.Invoke(ctx, "/api.Dex/GetVersion", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_GetVersion_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dexClient) GetDiscovery(ctx context.Context, in *DiscoveryReq, opts ...grpc.CallOption) (*DiscoveryResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(DiscoveryResp) + err := c.cc.Invoke(ctx, Dex_GetDiscovery_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -125,8 +244,9 @@ func (c *dexClient) GetVersion(ctx context.Context, in *VersionReq, opts ...grpc } func (c *dexClient) ListRefresh(ctx context.Context, in *ListRefreshReq, opts ...grpc.CallOption) (*ListRefreshResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ListRefreshResp) - err := c.cc.Invoke(ctx, "/api.Dex/ListRefresh", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_ListRefresh_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -134,8 +254,9 @@ func (c *dexClient) ListRefresh(ctx context.Context, in *ListRefreshReq, opts .. } func (c *dexClient) RevokeRefresh(ctx context.Context, in *RevokeRefreshReq, opts ...grpc.CallOption) (*RevokeRefreshResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(RevokeRefreshResp) - err := c.cc.Invoke(ctx, "/api.Dex/RevokeRefresh", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_RevokeRefresh_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -143,8 +264,9 @@ func (c *dexClient) RevokeRefresh(ctx context.Context, in *RevokeRefreshReq, opt } func (c *dexClient) VerifyPassword(ctx context.Context, in *VerifyPasswordReq, opts ...grpc.CallOption) (*VerifyPasswordResp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(VerifyPasswordResp) - err := c.cc.Invoke(ctx, "/api.Dex/VerifyPassword", in, out, opts...) + err := c.cc.Invoke(ctx, Dex_VerifyPassword_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -153,14 +275,20 @@ func (c *dexClient) VerifyPassword(ctx context.Context, in *VerifyPasswordReq, o // DexServer is the server API for Dex service. // All implementations must embed UnimplementedDexServer -// for forward compatibility +// for forward compatibility. +// +// Dex represents the dex gRPC service. type DexServer interface { + // GetClient gets a client. + GetClient(context.Context, *GetClientReq) (*GetClientResp, error) // CreateClient creates a client. CreateClient(context.Context, *CreateClientReq) (*CreateClientResp, error) // UpdateClient updates an existing client UpdateClient(context.Context, *UpdateClientReq) (*UpdateClientResp, error) // DeleteClient deletes the provided client. DeleteClient(context.Context, *DeleteClientReq) (*DeleteClientResp, error) + // ListClients lists all client entries. + ListClients(context.Context, *ListClientReq) (*ListClientResp, error) // CreatePassword creates a password. CreatePassword(context.Context, *CreatePasswordReq) (*CreatePasswordResp, error) // UpdatePassword modifies existing password. @@ -169,8 +297,18 @@ type DexServer interface { DeletePassword(context.Context, *DeletePasswordReq) (*DeletePasswordResp, error) // ListPassword lists all password entries. ListPasswords(context.Context, *ListPasswordReq) (*ListPasswordResp, error) + // CreateConnector creates a connector. + CreateConnector(context.Context, *CreateConnectorReq) (*CreateConnectorResp, error) + // UpdateConnector modifies existing connector. + UpdateConnector(context.Context, *UpdateConnectorReq) (*UpdateConnectorResp, error) + // DeleteConnector deletes the connector. + DeleteConnector(context.Context, *DeleteConnectorReq) (*DeleteConnectorResp, error) + // ListConnectors lists all connector entries. + ListConnectors(context.Context, *ListConnectorReq) (*ListConnectorResp, error) // GetVersion returns version information of the server. GetVersion(context.Context, *VersionReq) (*VersionResp, error) + // GetDiscovery returns discovery information of the server. + GetDiscovery(context.Context, *DiscoveryReq) (*DiscoveryResp, error) // ListRefresh lists all the refresh token entries for a particular user. ListRefresh(context.Context, *ListRefreshReq) (*ListRefreshResp, error) // RevokeRefresh revokes the refresh token for the provided user-client pair. @@ -182,10 +320,16 @@ type DexServer interface { mustEmbedUnimplementedDexServer() } -// UnimplementedDexServer must be embedded to have forward compatible implementations. -type UnimplementedDexServer struct { -} +// UnimplementedDexServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedDexServer struct{} +func (UnimplementedDexServer) GetClient(context.Context, *GetClientReq) (*GetClientResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetClient not implemented") +} func (UnimplementedDexServer) CreateClient(context.Context, *CreateClientReq) (*CreateClientResp, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateClient not implemented") } @@ -195,6 +339,9 @@ func (UnimplementedDexServer) UpdateClient(context.Context, *UpdateClientReq) (* func (UnimplementedDexServer) DeleteClient(context.Context, *DeleteClientReq) (*DeleteClientResp, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteClient not implemented") } +func (UnimplementedDexServer) ListClients(context.Context, *ListClientReq) (*ListClientResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListClients not implemented") +} func (UnimplementedDexServer) CreatePassword(context.Context, *CreatePasswordReq) (*CreatePasswordResp, error) { return nil, status.Errorf(codes.Unimplemented, "method CreatePassword not implemented") } @@ -207,9 +354,24 @@ func (UnimplementedDexServer) DeletePassword(context.Context, *DeletePasswordReq func (UnimplementedDexServer) ListPasswords(context.Context, *ListPasswordReq) (*ListPasswordResp, error) { return nil, status.Errorf(codes.Unimplemented, "method ListPasswords not implemented") } +func (UnimplementedDexServer) CreateConnector(context.Context, *CreateConnectorReq) (*CreateConnectorResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateConnector not implemented") +} +func (UnimplementedDexServer) UpdateConnector(context.Context, *UpdateConnectorReq) (*UpdateConnectorResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateConnector not implemented") +} +func (UnimplementedDexServer) DeleteConnector(context.Context, *DeleteConnectorReq) (*DeleteConnectorResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteConnector not implemented") +} +func (UnimplementedDexServer) ListConnectors(context.Context, *ListConnectorReq) (*ListConnectorResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListConnectors not implemented") +} func (UnimplementedDexServer) GetVersion(context.Context, *VersionReq) (*VersionResp, error) { return nil, status.Errorf(codes.Unimplemented, "method GetVersion not implemented") } +func (UnimplementedDexServer) GetDiscovery(context.Context, *DiscoveryReq) (*DiscoveryResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetDiscovery not implemented") +} func (UnimplementedDexServer) ListRefresh(context.Context, *ListRefreshReq) (*ListRefreshResp, error) { return nil, status.Errorf(codes.Unimplemented, "method ListRefresh not implemented") } @@ -220,6 +382,7 @@ func (UnimplementedDexServer) VerifyPassword(context.Context, *VerifyPasswordReq return nil, status.Errorf(codes.Unimplemented, "method VerifyPassword not implemented") } func (UnimplementedDexServer) mustEmbedUnimplementedDexServer() {} +func (UnimplementedDexServer) testEmbeddedByValue() {} // UnsafeDexServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to DexServer will @@ -229,9 +392,34 @@ type UnsafeDexServer interface { } func RegisterDexServer(s grpc.ServiceRegistrar, srv DexServer) { + // If the following call pancis, it indicates UnimplementedDexServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Dex_ServiceDesc, srv) } +func _Dex_GetClient_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetClientReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DexServer).GetClient(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Dex_GetClient_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DexServer).GetClient(ctx, req.(*GetClientReq)) + } + return interceptor(ctx, in, info, handler) +} + func _Dex_CreateClient_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CreateClientReq) if err := dec(in); err != nil { @@ -242,7 +430,7 @@ func _Dex_CreateClient_Handler(srv interface{}, ctx context.Context, dec func(in } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/CreateClient", + FullMethod: Dex_CreateClient_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).CreateClient(ctx, req.(*CreateClientReq)) @@ -260,7 +448,7 @@ func _Dex_UpdateClient_Handler(srv interface{}, ctx context.Context, dec func(in } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/UpdateClient", + FullMethod: Dex_UpdateClient_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).UpdateClient(ctx, req.(*UpdateClientReq)) @@ -278,7 +466,7 @@ func _Dex_DeleteClient_Handler(srv interface{}, ctx context.Context, dec func(in } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/DeleteClient", + FullMethod: Dex_DeleteClient_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).DeleteClient(ctx, req.(*DeleteClientReq)) @@ -286,6 +474,24 @@ func _Dex_DeleteClient_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _Dex_ListClients_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListClientReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DexServer).ListClients(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Dex_ListClients_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DexServer).ListClients(ctx, req.(*ListClientReq)) + } + return interceptor(ctx, in, info, handler) +} + func _Dex_CreatePassword_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CreatePasswordReq) if err := dec(in); err != nil { @@ -296,7 +502,7 @@ func _Dex_CreatePassword_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/CreatePassword", + FullMethod: Dex_CreatePassword_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).CreatePassword(ctx, req.(*CreatePasswordReq)) @@ -314,7 +520,7 @@ func _Dex_UpdatePassword_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/UpdatePassword", + FullMethod: Dex_UpdatePassword_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).UpdatePassword(ctx, req.(*UpdatePasswordReq)) @@ -332,7 +538,7 @@ func _Dex_DeletePassword_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/DeletePassword", + FullMethod: Dex_DeletePassword_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).DeletePassword(ctx, req.(*DeletePasswordReq)) @@ -350,7 +556,7 @@ func _Dex_ListPasswords_Handler(srv interface{}, ctx context.Context, dec func(i } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/ListPasswords", + FullMethod: Dex_ListPasswords_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).ListPasswords(ctx, req.(*ListPasswordReq)) @@ -358,6 +564,78 @@ func _Dex_ListPasswords_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _Dex_CreateConnector_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateConnectorReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DexServer).CreateConnector(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Dex_CreateConnector_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DexServer).CreateConnector(ctx, req.(*CreateConnectorReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dex_UpdateConnector_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateConnectorReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DexServer).UpdateConnector(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Dex_UpdateConnector_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DexServer).UpdateConnector(ctx, req.(*UpdateConnectorReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dex_DeleteConnector_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteConnectorReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DexServer).DeleteConnector(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Dex_DeleteConnector_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DexServer).DeleteConnector(ctx, req.(*DeleteConnectorReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dex_ListConnectors_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListConnectorReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DexServer).ListConnectors(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Dex_ListConnectors_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DexServer).ListConnectors(ctx, req.(*ListConnectorReq)) + } + return interceptor(ctx, in, info, handler) +} + func _Dex_GetVersion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(VersionReq) if err := dec(in); err != nil { @@ -368,7 +646,7 @@ func _Dex_GetVersion_Handler(srv interface{}, ctx context.Context, dec func(inte } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/GetVersion", + FullMethod: Dex_GetVersion_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).GetVersion(ctx, req.(*VersionReq)) @@ -376,6 +654,24 @@ func _Dex_GetVersion_Handler(srv interface{}, ctx context.Context, dec func(inte return interceptor(ctx, in, info, handler) } +func _Dex_GetDiscovery_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DiscoveryReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DexServer).GetDiscovery(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Dex_GetDiscovery_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DexServer).GetDiscovery(ctx, req.(*DiscoveryReq)) + } + return interceptor(ctx, in, info, handler) +} + func _Dex_ListRefresh_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListRefreshReq) if err := dec(in); err != nil { @@ -386,7 +682,7 @@ func _Dex_ListRefresh_Handler(srv interface{}, ctx context.Context, dec func(int } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/ListRefresh", + FullMethod: Dex_ListRefresh_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).ListRefresh(ctx, req.(*ListRefreshReq)) @@ -404,7 +700,7 @@ func _Dex_RevokeRefresh_Handler(srv interface{}, ctx context.Context, dec func(i } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/RevokeRefresh", + FullMethod: Dex_RevokeRefresh_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).RevokeRefresh(ctx, req.(*RevokeRefreshReq)) @@ -422,7 +718,7 @@ func _Dex_VerifyPassword_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/api.Dex/VerifyPassword", + FullMethod: Dex_VerifyPassword_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DexServer).VerifyPassword(ctx, req.(*VerifyPasswordReq)) @@ -437,6 +733,10 @@ var Dex_ServiceDesc = grpc.ServiceDesc{ ServiceName: "api.Dex", HandlerType: (*DexServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "GetClient", + Handler: _Dex_GetClient_Handler, + }, { MethodName: "CreateClient", Handler: _Dex_CreateClient_Handler, @@ -449,6 +749,10 @@ var Dex_ServiceDesc = grpc.ServiceDesc{ MethodName: "DeleteClient", Handler: _Dex_DeleteClient_Handler, }, + { + MethodName: "ListClients", + Handler: _Dex_ListClients_Handler, + }, { MethodName: "CreatePassword", Handler: _Dex_CreatePassword_Handler, @@ -465,10 +769,30 @@ var Dex_ServiceDesc = grpc.ServiceDesc{ MethodName: "ListPasswords", Handler: _Dex_ListPasswords_Handler, }, + { + MethodName: "CreateConnector", + Handler: _Dex_CreateConnector_Handler, + }, + { + MethodName: "UpdateConnector", + Handler: _Dex_UpdateConnector_Handler, + }, + { + MethodName: "DeleteConnector", + Handler: _Dex_DeleteConnector_Handler, + }, + { + MethodName: "ListConnectors", + Handler: _Dex_ListConnectors_Handler, + }, { MethodName: "GetVersion", Handler: _Dex_GetVersion_Handler, }, + { + MethodName: "GetDiscovery", + Handler: _Dex_GetDiscovery_Handler, + }, { MethodName: "ListRefresh", Handler: _Dex_ListRefresh_Handler, diff --git a/api/v2/go.mod b/api/v2/go.mod index dc78ec4d96..8c4bd5ba8e 100644 --- a/api/v2/go.mod +++ b/api/v2/go.mod @@ -1,16 +1,15 @@ module github.com/dexidp/dex/api/v2 -go 1.17 +go 1.24.0 require ( - google.golang.org/grpc v1.47.0 - google.golang.org/protobuf v1.28.1 + google.golang.org/grpc v1.77.0 + google.golang.org/protobuf v1.36.10 ) require ( - github.com/golang/protobuf v1.5.2 // indirect - golang.org/x/net v0.0.0-20220607020251-c690dde0001d // indirect - golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect - golang.org/x/text v0.3.7 // indirect - google.golang.org/genproto v0.0.0-20220602131408-e326c6e8e9c8 // indirect + golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 // indirect + golang.org/x/sys v0.37.0 // indirect + golang.org/x/text v0.30.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect ) diff --git a/api/v2/go.sum b/api/v2/go.sum index 59d53d2d63..6d6408a5bb 100644 --- a/api/v2/go.sum +++ b/api/v2/go.sum @@ -1,142 +1,36 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20220607020251-c690dde0001d h1:4SFsTMi4UahlKoloni7L4eYzhFRifURQLw+yv0QDCx8= -golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/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-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20220602131408-e326c6e8e9c8 h1:qRu95HZ148xXw+XeZ3dvqe85PxH4X8+jIo0iRPKcEnM= -google.golang.org/genproto v0.0.0-20220602131408-e326c6e8e9c8/go.mod h1:yKyY4AMRwFiC8yMMNaMi+RkCnjZJt9LoWuvhXjMs+To= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -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.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= +golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= +golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= +golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= +golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= +google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= diff --git a/cmd/dex/config.go b/cmd/dex/config.go index 7bb7fbb780..aa49a18188 100644 --- a/cmd/dex/config.go +++ b/cmd/dex/config.go @@ -4,13 +4,15 @@ import ( "encoding/base64" "encoding/json" "fmt" + "log/slog" + "net/http" + "net/netip" "os" - "strconv" "strings" "golang.org/x/crypto/bcrypt" - "github.com/dexidp/dex/pkg/log" + "github.com/dexidp/dex/pkg/featureflags" "github.com/dexidp/dex/server" "github.com/dexidp/dex/storage" "github.com/dexidp/dex/storage/ent" @@ -64,10 +66,16 @@ func (c Config) Validate() error { {c.Web.HTTP == "" && c.Web.HTTPS == "", "must supply a HTTP/HTTPS address to listen on"}, {c.Web.HTTPS != "" && c.Web.TLSCert == "", "no cert specified for HTTPS"}, {c.Web.HTTPS != "" && c.Web.TLSKey == "", "no private key specified for HTTPS"}, + {c.Web.TLSMinVersion != "" && c.Web.TLSMinVersion != "1.2" && c.Web.TLSMinVersion != "1.3", "supported TLS versions are: 1.2, 1.3"}, + {c.Web.TLSMaxVersion != "" && c.Web.TLSMaxVersion != "1.2" && c.Web.TLSMaxVersion != "1.3", "supported TLS versions are: 1.2, 1.3"}, + {c.Web.TLSMaxVersion != "" && c.Web.TLSMinVersion != "" && c.Web.TLSMinVersion > c.Web.TLSMaxVersion, "TLSMinVersion greater than TLSMaxVersion"}, {c.GRPC.TLSCert != "" && c.GRPC.Addr == "", "no address specified for gRPC"}, {c.GRPC.TLSKey != "" && c.GRPC.Addr == "", "no address specified for gRPC"}, {(c.GRPC.TLSCert == "") != (c.GRPC.TLSKey == ""), "must specific both a gRPC TLS cert and key"}, {c.GRPC.TLSCert == "" && c.GRPC.TLSClientCA != "", "cannot specify gRPC TLS client CA without a gRPC TLS cert"}, + {c.GRPC.TLSMinVersion != "" && c.GRPC.TLSMinVersion != "1.2" && c.GRPC.TLSMinVersion != "1.3", "supported TLS versions are: 1.2, 1.3"}, + {c.GRPC.TLSMaxVersion != "" && c.GRPC.TLSMaxVersion != "1.2" && c.GRPC.TLSMaxVersion != "1.3", "supported TLS versions are: 1.2, 1.3"}, + {c.GRPC.TLSMaxVersion != "" && c.GRPC.TLSMinVersion != "" && c.GRPC.TLSMinVersion > c.GRPC.TLSMaxVersion, "TLSMinVersion greater than TLSMaxVersion"}, } var checkErrors []string @@ -129,6 +137,10 @@ func (p *password) UnmarshalJSON(b []byte) error { // OAuth2 describes enabled OAuth2 extensions. type OAuth2 struct { + // list of allowed grant types, + // defaults to all supported types + GrantTypes []string `json:"grantTypes"` + ResponseTypes []string `json:"responseTypes"` // If specified, do not prompt the user to approve client authorization. The // act of logging in implies authorization. @@ -141,11 +153,84 @@ type OAuth2 struct { // Web is the config format for the HTTP server. type Web struct { - HTTP string `json:"http"` - HTTPS string `json:"https"` - TLSCert string `json:"tlsCert"` - TLSKey string `json:"tlsKey"` - AllowedOrigins []string `json:"allowedOrigins"` + HTTP string `json:"http"` + HTTPS string `json:"https"` + Headers Headers `json:"headers"` + TLSCert string `json:"tlsCert"` + TLSKey string `json:"tlsKey"` + TLSMinVersion string `json:"tlsMinVersion"` + TLSMaxVersion string `json:"tlsMaxVersion"` + AllowedOrigins []string `json:"allowedOrigins"` + AllowedHeaders []string `json:"allowedHeaders"` + ClientRemoteIP ClientRemoteIP `json:"clientRemoteIP"` +} + +type ClientRemoteIP struct { + Header string `json:"header"` + TrustedProxies []string `json:"trustedProxies"` +} + +func (cr *ClientRemoteIP) ParseTrustedProxies() ([]netip.Prefix, error) { + if cr == nil { + return nil, nil + } + + trusted := make([]netip.Prefix, 0, len(cr.TrustedProxies)) + for _, cidr := range cr.TrustedProxies { + ipNet, err := netip.ParsePrefix(cidr) + if err != nil { + return nil, fmt.Errorf("failed to parse CIDR %q: %v", cidr, err) + } + trusted = append(trusted, ipNet) + } + + return trusted, nil +} + +type Headers struct { + // Set the Content-Security-Policy header to HTTP responses. + // Unset if blank. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy + ContentSecurityPolicy string `json:"Content-Security-Policy"` + // Set the X-Frame-Options header to HTTP responses. + // Unset if blank. Accepted values are deny and sameorigin. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options + XFrameOptions string `json:"X-Frame-Options"` + // Set the X-Content-Type-Options header to HTTP responses. + // Unset if blank. Accepted value is nosniff. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options + XContentTypeOptions string `json:"X-Content-Type-Options"` + // Set the X-XSS-Protection header to all responses. + // Unset if blank. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection + XXSSProtection string `json:"X-XSS-Protection"` + // Set the Strict-Transport-Security header to HTTP responses. + // Unset if blank. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security + StrictTransportSecurity string `json:"Strict-Transport-Security"` +} + +func (h *Headers) ToHTTPHeader() http.Header { + if h == nil { + return make(map[string][]string) + } + header := make(map[string][]string) + if h.ContentSecurityPolicy != "" { + header["Content-Security-Policy"] = []string{h.ContentSecurityPolicy} + } + if h.XFrameOptions != "" { + header["X-Frame-Options"] = []string{h.XFrameOptions} + } + if h.XContentTypeOptions != "" { + header["X-Content-Type-Options"] = []string{h.XContentTypeOptions} + } + if h.XXSSProtection != "" { + header["X-XSS-Protection"] = []string{h.XXSSProtection} + } + if h.StrictTransportSecurity != "" { + header["Strict-Transport-Security"] = []string{h.StrictTransportSecurity} + } + return header } // Telemetry is the config format for telemetry including the HTTP server config. @@ -158,11 +243,13 @@ type Telemetry struct { // GRPC is the config for the gRPC API. type GRPC struct { // The port to listen on. - Addr string `json:"addr"` - TLSCert string `json:"tlsCert"` - TLSKey string `json:"tlsKey"` - TLSClientCA string `json:"tlsClientCA"` - Reflection bool `json:"reflection"` + Addr string `json:"addr"` + TLSCert string `json:"tlsCert"` + TLSKey string `json:"tlsKey"` + TLSClientCA string `json:"tlsClientCA"` + TLSMinVersion string `json:"tlsMinVersion"` + TLSMaxVersion string `json:"tlsMaxVersion"` + Reflection bool `json:"reflection"` } // Storage holds app's storage configuration. @@ -173,7 +260,7 @@ type Storage struct { // StorageConfig is a configuration that can create a storage. type StorageConfig interface { - Open(logger log.Logger) (storage.Storage, error) + Open(logger *slog.Logger) (storage.Storage, error) } var ( @@ -190,11 +277,30 @@ var ( func getORMBasedSQLStorage(normal, entBased StorageConfig) func() StorageConfig { return func() StorageConfig { - switch os.Getenv("DEX_ENT_ENABLED") { - case "true", "yes": + if featureflags.EntEnabled.Enabled() { return entBased - default: - return normal + } + return normal + } +} + +// Recursively expand environment variables in the map to avoid +// issues with JSON special characters and escapes +func expandEnvInMap(m map[string]interface{}) { + for k, v := range m { + switch vt := v.(type) { + case string: + m[k] = os.ExpandEnv(vt) + case map[string]interface{}: + expandEnvInMap(vt) + case []interface{}: + for i, item := range vt { + if itemMap, ok := item.(map[string]interface{}); ok { + expandEnvInMap(itemMap) + } else if itemString, ok := item.(string); ok { + vt[i] = os.ExpandEnv(itemString) + } + } } } } @@ -208,19 +314,6 @@ var storages = map[string]func() StorageConfig{ "mysql": getORMBasedSQLStorage(&sql.MySQL{}, &ent.MySQL{}), } -// isExpandEnvEnabled returns if os.ExpandEnv should be used for each storage and connector config. -// Disabling this feature avoids surprises e.g. if the LDAP bind password contains a dollar character. -// Returns false if the env variable "DEX_EXPAND_ENV" is a falsy string, e.g. "false". -// Returns true if the env variable is unset or a truthy string, e.g. "true", or can't be parsed as bool. -func isExpandEnvEnabled() bool { - enabled, err := strconv.ParseBool(os.Getenv("DEX_EXPAND_ENV")) - if err != nil { - // Unset, empty string or can't be parsed as bool: Default = true. - return true - } - return enabled -} - // UnmarshalJSON allows Storage to implement the unmarshaler interface to // dynamically determine the type of the storage config. func (s *Storage) UnmarshalJSON(b []byte) error { @@ -239,10 +332,25 @@ func (s *Storage) UnmarshalJSON(b []byte) error { storageConfig := f() if len(store.Config) != 0 { data := []byte(store.Config) - if isExpandEnvEnabled() { - // Caution, we're expanding in the raw JSON/YAML source. This may not be what the admin expects. - data = []byte(os.ExpandEnv(string(store.Config))) + if featureflags.ExpandEnv.Enabled() { + var rawMap map[string]interface{} + if err := json.Unmarshal(store.Config, &rawMap); err != nil { + return fmt.Errorf("unmarshal config for env expansion: %v", err) + } + + // Recursively expand environment variables in the map to avoid + // issues with JSON special characters and escapes + expandEnvInMap(rawMap) + + // Marshal the expanded map back to JSON + expandedData, err := json.Marshal(rawMap) + if err != nil { + return fmt.Errorf("marshal expanded config: %v", err) + } + + data = expandedData } + if err := json.Unmarshal(data, storageConfig); err != nil { return fmt.Errorf("parse storage config: %v", err) } @@ -285,14 +393,30 @@ func (c *Connector) UnmarshalJSON(b []byte) error { connConfig := f() if len(conn.Config) != 0 { data := []byte(conn.Config) - if isExpandEnvEnabled() { - // Caution, we're expanding in the raw JSON/YAML source. This may not be what the admin expects. - data = []byte(os.ExpandEnv(string(conn.Config))) + if featureflags.ExpandEnv.Enabled() { + var rawMap map[string]interface{} + if err := json.Unmarshal(conn.Config, &rawMap); err != nil { + return fmt.Errorf("unmarshal config for env expansion: %v", err) + } + + // Recursively expand environment variables in the map to avoid + // issues with JSON special characters and escapes + expandEnvInMap(rawMap) + + // Marshal the expanded map back to JSON + expandedData, err := json.Marshal(rawMap) + if err != nil { + return fmt.Errorf("marshal expanded config: %v", err) + } + + data = expandedData } + if err := json.Unmarshal(data, connConfig); err != nil { return fmt.Errorf("parse connector config: %v", err) } } + *c = Connector{ Type: conn.Type, Name: conn.Name, @@ -338,7 +462,7 @@ type Expiry struct { // Logger holds configuration required to customize logging for dex. type Logger struct { // Level sets logging level severity. - Level string `json:"level"` + Level slog.Level `json:"level"` // Format specifies the format to be used for logging. Format string `json:"format"` diff --git a/cmd/dex/config_test.go b/cmd/dex/config_test.go index 8ee02d5aa2..68abe1f793 100644 --- a/cmd/dex/config_test.go +++ b/cmd/dex/config_test.go @@ -1,6 +1,7 @@ package main import ( + "log/slog" "os" "testing" @@ -37,6 +38,7 @@ func TestValidConfiguration(t *testing.T) { }, }, } + if err := configuration.Validate(); err != nil { t.Fatalf("this configuration should have been valid: %v", err) } @@ -71,7 +73,11 @@ storage: connMaxLifetime: 30 connectionTimeout: 3 web: - http: 127.0.0.1:5556 + https: 127.0.0.1:5556 + tlsMinVersion: 1.3 + tlsMaxVersion: 1.2 + headers: + Strict-Transport-Security: "max-age=31536000; includeSubDomains" frontend: dir: ./web @@ -87,6 +93,9 @@ staticClients: oauth2: alwaysShowLoginScreen: true + grantTypes: + - refresh_token + - "urn:ietf:params:oauth:grant-type:token-exchange" connectors: - type: mockCallback @@ -123,6 +132,10 @@ expiry: logger: level: "debug" format: "json" + +additionalFeatures: [ + "ConnectorsCRUD" +] `) want := Config{ @@ -141,7 +154,12 @@ logger: }, }, Web: Web{ - HTTP: "127.0.0.1:5556", + HTTPS: "127.0.0.1:5556", + TLSMinVersion: "1.3", + TLSMaxVersion: "1.2", + Headers: Headers{ + StrictTransportSecurity: "max-age=31536000; includeSubDomains", + }, }, Frontend: server.WebConfig{ Dir: "./web", @@ -161,6 +179,10 @@ logger: }, OAuth2: OAuth2{ AlwaysShowLoginScreen: true, + GrantTypes: []string{ + "refresh_token", + "urn:ietf:params:oauth:grant-type:token-exchange", + }, }, StaticConnectors: []Connector{ { @@ -203,7 +225,7 @@ logger: DeviceRequests: "10m", }, Logger: Logger{ - Level: "debug", + Level: slog.LevelDebug, Format: "json", }, } @@ -212,6 +234,7 @@ logger: if err := yaml.Unmarshal(rawConfig, &c); err != nil { t.Fatalf("failed to decode config: %v", err) } + if diff := pretty.Compare(c, want); diff != "" { t.Errorf("got!=want: %s", diff) } @@ -250,7 +273,8 @@ func checkUnmarshalConfigWithEnv(t *testing.T, dexExpandEnv string, wantExpandEn os.Setenv("DEX_FOO_USER_PASSWORD", "$2a$10$33EMT0cVYVlPy6WAMCLsceLYjWhuHpbz5yuZxu/GAFj03J9Lytjuy") // For os.ExpandEnv ($VAR -> value_of_VAR): os.Setenv("DEX_FOO_POSTGRES_HOST", "10.0.0.1") - os.Setenv("DEX_FOO_OIDC_CLIENT_SECRET", "bar") + os.Setenv("DEX_FOO_POSTGRES_PASSWORD", `psql"test\pass`) + os.Setenv("DEX_FOO_OIDC_CLIENT_SECRET", `abc"def\ghi`) if dexExpandEnv != "UNSET" { os.Setenv("DEX_EXPAND_ENV", dexExpandEnv) } else { @@ -265,6 +289,7 @@ storage: # Env variables are expanded in raw YAML source. # Single quotes work fine, as long as the env variable doesn't contain any. host: '$DEX_FOO_POSTGRES_HOST' + password: '$DEX_FOO_POSTGRES_PASSWORD' port: 65432 maxOpenConns: 5 maxIdleConns: 3 @@ -327,10 +352,12 @@ logger: // This is not a valid hostname. It's only used to check whether os.ExpandEnv was applied or not. wantPostgresHost := "$DEX_FOO_POSTGRES_HOST" + wantPostgresPassword := "$DEX_FOO_POSTGRES_PASSWORD" wantOidcClientSecret := "$DEX_FOO_OIDC_CLIENT_SECRET" if wantExpandEnv { wantPostgresHost = "10.0.0.1" - wantOidcClientSecret = "bar" + wantPostgresPassword = `psql"test\pass` + wantOidcClientSecret = `abc"def\ghi` } want := Config{ @@ -340,6 +367,7 @@ logger: Config: &sql.Postgres{ NetworkDB: sql.NetworkDB{ Host: wantPostgresHost, + Password: wantPostgresPassword, Port: 65432, MaxOpenConns: 5, MaxIdleConns: 3, @@ -410,7 +438,7 @@ logger: AuthRequests: "25h", }, Logger: Logger{ - Level: "debug", + Level: slog.LevelDebug, Format: "json", }, } @@ -419,6 +447,7 @@ logger: if err := yaml.Unmarshal(rawConfig, &c); err != nil { t.Fatalf("failed to decode config: %v", err) } + if diff := pretty.Compare(c, want); diff != "" { t.Errorf("got!=want: %s", diff) } diff --git a/cmd/dex/logger.go b/cmd/dex/logger.go new file mode 100644 index 0000000000..c1fe6b4a88 --- /dev/null +++ b/cmd/dex/logger.go @@ -0,0 +1,67 @@ +package main + +import ( + "context" + "fmt" + "log/slog" + "os" + "strings" + + "github.com/dexidp/dex/server" +) + +var logFormats = []string{"json", "text"} + +func newLogger(level slog.Level, format string) (*slog.Logger, error) { + var handler slog.Handler + switch strings.ToLower(format) { + case "", "text": + handler = slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{ + Level: level, + }) + case "json": + handler = slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{ + Level: level, + }) + default: + return nil, fmt.Errorf("log format is not one of the supported values (%s): %s", strings.Join(logFormats, ", "), format) + } + + return slog.New(newRequestContextHandler(handler)), nil +} + +var _ slog.Handler = requestContextHandler{} + +type requestContextHandler struct { + handler slog.Handler +} + +func newRequestContextHandler(handler slog.Handler) slog.Handler { + return requestContextHandler{ + handler: handler, + } +} + +func (h requestContextHandler) Enabled(ctx context.Context, level slog.Level) bool { + return h.handler.Enabled(ctx, level) +} + +func (h requestContextHandler) Handle(ctx context.Context, record slog.Record) error { + if v, ok := ctx.Value(server.RequestKeyRemoteIP).(string); ok { + record.AddAttrs(slog.String(string(server.RequestKeyRemoteIP), v)) + } + + if v, ok := ctx.Value(server.RequestKeyRequestID).(string); ok { + record.AddAttrs(slog.String(string(server.RequestKeyRequestID), v)) + } + + return h.handler.Handle(ctx, record) +} + +func (h requestContextHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + return requestContextHandler{h.handler.WithAttrs(attrs)} +} + +func (h requestContextHandler) WithGroup(name string) slog.Handler { + return requestContextHandler{h.handler.WithGroup(name)} +} diff --git a/cmd/dex/serve.go b/cmd/dex/serve.go index c8fb95eb16..ac715e606f 100644 --- a/cmd/dex/serve.go +++ b/cmd/dex/serve.go @@ -6,32 +6,36 @@ import ( "crypto/x509" "errors" "fmt" + "log/slog" "net" "net/http" "net/http/pprof" "os" + "os/signal" + "path/filepath" "runtime" "strings" + "sync/atomic" "syscall" "time" gosundheit "github.com/AppsFlyer/go-sundheit" "github.com/AppsFlyer/go-sundheit/checks" gosundheithttp "github.com/AppsFlyer/go-sundheit/http" + "github.com/fsnotify/fsnotify" "github.com/ghodss/yaml" grpcprometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "github.com/oklog/run" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/collectors" "github.com/prometheus/client_golang/prometheus/promhttp" - "github.com/sirupsen/logrus" "github.com/spf13/cobra" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/reflection" "github.com/dexidp/dex/api/v2" - "github.com/dexidp/dex/pkg/log" + "github.com/dexidp/dex/pkg/featureflags" "github.com/dexidp/dex/server" "github.com/dexidp/dex/storage" ) @@ -47,6 +51,15 @@ type serveOptions struct { grpcAddr string } +var buildInfo = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "build_info", + Namespace: "dex", + Help: "A metric with a constant '1' value labeled by version from which Dex was built.", + }, + []string{"version", "go_version", "platform"}, +) + func commandServe() *cobra.Command { options := serveOptions{} @@ -94,24 +107,30 @@ func runServe(options serveOptions) error { return fmt.Errorf("invalid config: %v", err) } - logger.Infof( - "Dex Version: %s, Go Version: %s, Go OS/ARCH: %s %s", - version, - runtime.Version(), - runtime.GOOS, - runtime.GOARCH, + logger.Info( + "Version info", + "dex_version", version, + slog.Group("go", + "version", runtime.Version(), + "os", runtime.GOOS, + "arch", runtime.GOARCH, + ), ) - if c.Logger.Level != "" { - logger.Infof("config using log level: %s", c.Logger.Level) + if c.Logger.Level != slog.LevelInfo { + logger.Info("config using log level", "level", c.Logger.Level) } if err := c.Validate(); err != nil { return err } - logger.Infof("config issuer: %s", c.Issuer) + logger.Info("config issuer", "issuer", c.Issuer) prometheusRegistry := prometheus.NewRegistry() + + prometheusRegistry.MustRegister(buildInfo) + recordBuildInfo() + err = prometheusRegistry.Register(collectors.NewGoCollector()) if err != nil { return fmt.Errorf("failed to register Go runtime metrics: %v", err) @@ -141,34 +160,33 @@ func runServe(options serveOptions) error { tls.TLS_RSA_WITH_AES_256_GCM_SHA384, } + allowedTLSVersions := map[string]int{ + "1.2": tls.VersionTLS12, + "1.3": tls.VersionTLS13, + } + if c.GRPC.TLSCert != "" { - // Parse certificates from certificate file and key file for server. - cert, err := tls.LoadX509KeyPair(c.GRPC.TLSCert, c.GRPC.TLSKey) - if err != nil { - return fmt.Errorf("invalid config: error parsing gRPC certificate file: %v", err) + tlsMinVersion := tls.VersionTLS12 + if c.GRPC.TLSMinVersion != "" { + tlsMinVersion = allowedTLSVersions[c.GRPC.TLSMinVersion] } - - tlsConfig := tls.Config{ - Certificates: []tls.Certificate{cert}, - MinVersion: tls.VersionTLS12, + tlsMaxVersion := 0 // default for max is whatever Go defaults to + if c.GRPC.TLSMaxVersion != "" { + tlsMaxVersion = allowedTLSVersions[c.GRPC.TLSMaxVersion] + } + baseTLSConfig := &tls.Config{ + MinVersion: uint16(tlsMinVersion), + MaxVersion: uint16(tlsMaxVersion), CipherSuites: allowedTLSCiphers, PreferServerCipherSuites: true, } - if c.GRPC.TLSClientCA != "" { - // Parse certificates from client CA file to a new CertPool. - cPool := x509.NewCertPool() - clientCert, err := os.ReadFile(c.GRPC.TLSClientCA) - if err != nil { - return fmt.Errorf("invalid config: reading from client CA file: %v", err) - } - if !cPool.AppendCertsFromPEM(clientCert) { - return errors.New("invalid config: failed to parse client CA") - } - - tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert - tlsConfig.ClientCAs = cPool + tlsConfig, err := newTLSReloader(logger, c.GRPC.TLSCert, c.GRPC.TLSKey, c.GRPC.TLSClientCA, baseTLSConfig) + if err != nil { + return fmt.Errorf("invalid config: get gRPC TLS: %v", err) + } + if c.GRPC.TLSClientCA != "" { // Only add metrics if client auth is enabled grpcOptions = append(grpcOptions, grpc.StreamInterceptor(grpcMetrics.StreamServerInterceptor()), @@ -176,7 +194,7 @@ func runServe(options serveOptions) error { ) } - grpcOptions = append(grpcOptions, grpc.Creds(credentials.NewTLS(&tlsConfig))) + grpcOptions = append(grpcOptions, grpc.Creds(credentials.NewTLS(tlsConfig))) } s, err := c.Storage.Config.Open(logger) @@ -185,7 +203,7 @@ func runServe(options serveOptions) error { } defer s.Close() - logger.Infof("config storage: %s", c.Storage.Type) + logger.Info("config storage", "storage_type", c.Storage.Type) if len(c.StaticClients) > 0 { for i, client := range c.StaticClients { @@ -210,7 +228,7 @@ func runServe(options serveOptions) error { } c.StaticClients[i].Secret = os.Getenv(client.SecretEnv) } - logger.Infof("config static client: %s", client.Name) + logger.Info("config static client", "client_name", client.Name) } s = storage.WithStaticClients(s, c.StaticClients) } @@ -230,7 +248,7 @@ func runServe(options serveOptions) error { if c.Config == nil { return fmt.Errorf("invalid config: no config field for connector %q", c.ID) } - logger.Infof("config connector: %s", c.ID) + logger.Info("config connector", "connector_id", c.ID) // convert to a storage connector object conn, err := ToStorageConnector(c) @@ -246,22 +264,25 @@ func runServe(options serveOptions) error { Name: "Email", Type: server.LocalConnector, }) - logger.Infof("config connector: local passwords enabled") + logger.Info("config connector: local passwords enabled") } s = storage.WithStaticConnectors(s, storageConnectors) if len(c.OAuth2.ResponseTypes) > 0 { - logger.Infof("config response types accepted: %s", c.OAuth2.ResponseTypes) + logger.Info("config response types accepted", "response_types", c.OAuth2.ResponseTypes) } if c.OAuth2.SkipApprovalScreen { - logger.Infof("config skipping approval screen") + logger.Info("config skipping approval screen") } if c.OAuth2.PasswordConnector != "" { - logger.Infof("config using password grant connector: %s", c.OAuth2.PasswordConnector) + logger.Info("config using password grant connector", "password_connector", c.OAuth2.PasswordConnector) } if len(c.Web.AllowedOrigins) > 0 { - logger.Infof("config allowed origins: %s", c.Web.AllowedOrigins) + logger.Info("config allowed origins", "origins", c.Web.AllowedOrigins) + } + if featureflags.ContinueOnConnectorFailure.Enabled() { + logger.Info("continue on connector failure feature flag enabled") } // explicitly convert to UTC. @@ -270,25 +291,29 @@ func runServe(options serveOptions) error { healthChecker := gosundheit.New() serverConfig := server.Config{ - SupportedResponseTypes: c.OAuth2.ResponseTypes, - SkipApprovalScreen: c.OAuth2.SkipApprovalScreen, - AlwaysShowLoginScreen: c.OAuth2.AlwaysShowLoginScreen, - PasswordConnector: c.OAuth2.PasswordConnector, - AllowedOrigins: c.Web.AllowedOrigins, - Issuer: c.Issuer, - Storage: s, - Web: c.Frontend, - Logger: logger, - Now: now, - PrometheusRegistry: prometheusRegistry, - HealthChecker: healthChecker, + AllowedGrantTypes: c.OAuth2.GrantTypes, + SupportedResponseTypes: c.OAuth2.ResponseTypes, + SkipApprovalScreen: c.OAuth2.SkipApprovalScreen, + AlwaysShowLoginScreen: c.OAuth2.AlwaysShowLoginScreen, + PasswordConnector: c.OAuth2.PasswordConnector, + Headers: c.Web.Headers.ToHTTPHeader(), + AllowedOrigins: c.Web.AllowedOrigins, + AllowedHeaders: c.Web.AllowedHeaders, + Issuer: c.Issuer, + Storage: s, + Web: c.Frontend, + Logger: logger, + Now: now, + PrometheusRegistry: prometheusRegistry, + HealthChecker: healthChecker, + ContinueOnConnectorFailure: featureflags.ContinueOnConnectorFailure.Enabled(), } if c.Expiry.SigningKeys != "" { signingKeys, err := time.ParseDuration(c.Expiry.SigningKeys) if err != nil { return fmt.Errorf("invalid config value %q for signing keys expiry: %v", c.Expiry.SigningKeys, err) } - logger.Infof("config signing keys expire after: %v", signingKeys) + logger.Info("config signing keys", "expire_after", signingKeys) serverConfig.RotateKeysAfter = signingKeys } if c.Expiry.IDTokens != "" { @@ -296,7 +321,7 @@ func runServe(options serveOptions) error { if err != nil { return fmt.Errorf("invalid config value %q for id token expiry: %v", c.Expiry.IDTokens, err) } - logger.Infof("config id tokens valid for: %v", idTokens) + logger.Info("config id tokens", "valid_for", idTokens) serverConfig.IDTokensValidFor = idTokens } if c.Expiry.AuthRequests != "" { @@ -304,7 +329,7 @@ func runServe(options serveOptions) error { if err != nil { return fmt.Errorf("invalid config value %q for auth request expiry: %v", c.Expiry.AuthRequests, err) } - logger.Infof("config auth requests valid for: %v", authRequests) + logger.Info("config auth requests", "valid_for", authRequests) serverConfig.AuthRequestsValidFor = authRequests } if c.Expiry.DeviceRequests != "" { @@ -312,7 +337,7 @@ func runServe(options serveOptions) error { if err != nil { return fmt.Errorf("invalid config value %q for device request expiry: %v", c.Expiry.AuthRequests, err) } - logger.Infof("config device requests valid for: %v", deviceRequests) + logger.Info("config device requests", "valid_for", deviceRequests) serverConfig.DeviceRequestsValidFor = deviceRequests } refreshTokenPolicy, err := server.NewRefreshTokenPolicy( @@ -327,6 +352,13 @@ func runServe(options serveOptions) error { } serverConfig.RefreshTokenPolicy = refreshTokenPolicy + + serverConfig.RealIPHeader = c.Web.ClientRemoteIP.Header + serverConfig.TrustedRealIPCIDRs, err = c.Web.ClientRemoteIP.ParseTrustedProxies() + if err != nil { + return fmt.Errorf("failed to parse client remote IP settings: %v", err) + } + serv, err := server.NewServer(context.Background(), serverConfig) if err != nil { return fmt.Errorf("failed to initialize server: %v", err) @@ -362,7 +394,7 @@ func runServe(options serveOptions) error { if c.Telemetry.HTTP != "" { const name = "telemetry" - logger.Infof("listening (%s) on %s", name, c.Telemetry.HTTP) + logger.Info("listening on", "server", name, "address", c.Telemetry.HTTP) l, err := net.Listen("tcp", c.Telemetry.HTTP) if err != nil { @@ -384,9 +416,9 @@ func runServe(options serveOptions) error { ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() - logger.Debugf("starting graceful shutdown (%s)", name) + logger.Debug("starting graceful shutdown", "server", name) if err := server.Shutdown(ctx); err != nil { - logger.Errorf("graceful shutdown (%s): %v", name, err) + logger.Error("graceful shutdown", "server", name, "err", err) } }) } @@ -395,7 +427,7 @@ func runServe(options serveOptions) error { if c.Web.HTTP != "" { const name = "http" - logger.Infof("listening (%s) on %s", name, c.Web.HTTP) + logger.Info("listening on", "server", name, "address", c.Web.HTTP) l, err := net.Listen("tcp", c.Web.HTTP) if err != nil { @@ -413,9 +445,9 @@ func runServe(options serveOptions) error { ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() - logger.Debugf("starting graceful shutdown (%s)", name) + logger.Debug("starting graceful shutdown", "server", name) if err := server.Shutdown(ctx); err != nil { - logger.Errorf("graceful shutdown (%s): %v", name, err) + logger.Error("graceful shutdown", "server", name, "err", err) } }) } @@ -424,39 +456,56 @@ func runServe(options serveOptions) error { if c.Web.HTTPS != "" { const name = "https" - logger.Infof("listening (%s) on %s", name, c.Web.HTTPS) + logger.Info("listening on", "server", name, "address", c.Web.HTTPS) l, err := net.Listen("tcp", c.Web.HTTPS) if err != nil { return fmt.Errorf("listening (%s) on %s: %v", name, c.Web.HTTPS, err) } + tlsMinVersion := tls.VersionTLS12 + if c.Web.TLSMinVersion != "" { + tlsMinVersion = allowedTLSVersions[c.Web.TLSMinVersion] + } + tlsMaxVersion := 0 // default for max is whatever Go defaults to + if c.Web.TLSMaxVersion != "" { + tlsMaxVersion = allowedTLSVersions[c.Web.TLSMaxVersion] + } + + baseTLSConfig := &tls.Config{ + MinVersion: uint16(tlsMinVersion), + MaxVersion: uint16(tlsMaxVersion), + CipherSuites: allowedTLSCiphers, + PreferServerCipherSuites: true, + } + + tlsConfig, err := newTLSReloader(logger, c.Web.TLSCert, c.Web.TLSKey, "", baseTLSConfig) + if err != nil { + return fmt.Errorf("invalid config: get HTTP TLS: %v", err) + } + server := &http.Server{ - Handler: serv, - TLSConfig: &tls.Config{ - CipherSuites: allowedTLSCiphers, - PreferServerCipherSuites: true, - MinVersion: tls.VersionTLS12, - }, + Handler: serv, + TLSConfig: tlsConfig, } defer server.Close() group.Add(func() error { - return server.ServeTLS(l, c.Web.TLSCert, c.Web.TLSKey) + return server.ServeTLS(l, "", "") }, func(err error) { ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() - logger.Debugf("starting graceful shutdown (%s)", name) + logger.Debug("starting graceful shutdown", "server", name) if err := server.Shutdown(ctx); err != nil { - logger.Errorf("graceful shutdown (%s): %v", name, err) + logger.Error("graceful shutdown", "server", name, "err", err) } }) } // Set up grpc server if c.GRPC.Addr != "" { - logger.Infof("listening (grpc) on %s", c.GRPC.Addr) + logger.Info("listening on", "server", "grpc", "address", c.GRPC.Addr) grpcListener, err := net.Listen("tcp", c.GRPC.Addr) if err != nil { @@ -464,7 +513,7 @@ func runServe(options serveOptions) error { } grpcSrv := grpc.NewServer(grpcOptions...) - api.RegisterDexServer(grpcSrv, server.NewAPI(serverConfig.Storage, logger, version)) + api.RegisterDexServer(grpcSrv, server.NewAPI(serverConfig.Storage, logger, version, serv)) grpcMetrics.InitializeMetrics(grpcSrv) if c.GRPC.Reflection { @@ -475,7 +524,7 @@ func runServe(options serveOptions) error { group.Add(func() error { return grpcSrv.Serve(grpcListener) }, func(err error) { - logger.Debugf("starting graceful shutdown (grpc)") + logger.Debug("starting graceful shutdown", "server", "grpc") grpcSrv.GracefulStop() }) } @@ -485,55 +534,11 @@ func runServe(options serveOptions) error { if _, ok := err.(run.SignalError); !ok { return fmt.Errorf("run groups: %w", err) } - logger.Infof("%v, shutdown now", err) + logger.Info("shutdown now", "err", err) } return nil } -var ( - logLevels = []string{"debug", "info", "error"} - logFormats = []string{"json", "text"} -) - -type utcFormatter struct { - f logrus.Formatter -} - -func (f *utcFormatter) Format(e *logrus.Entry) ([]byte, error) { - e.Time = e.Time.UTC() - return f.f.Format(e) -} - -func newLogger(level string, format string) (log.Logger, error) { - var logLevel logrus.Level - switch strings.ToLower(level) { - case "debug": - logLevel = logrus.DebugLevel - case "", "info": - logLevel = logrus.InfoLevel - case "error": - logLevel = logrus.ErrorLevel - default: - return nil, fmt.Errorf("log level is not one of the supported values (%s): %s", strings.Join(logLevels, ", "), level) - } - - var formatter utcFormatter - switch strings.ToLower(format) { - case "", "text": - formatter.f = &logrus.TextFormatter{DisableColors: true} - case "json": - formatter.f = &logrus.JSONFormatter{} - default: - return nil, fmt.Errorf("log format is not one of the supported values (%s): %s", strings.Join(logFormats, ", "), format) - } - - return &logrus.Logger{ - Out: os.Stderr, - Formatter: &formatter, - Level: logLevel, - }, nil -} - func applyConfigOverrides(options serveOptions, config *Config) { if options.webHTTPAddr != "" { config.Web.HTTP = options.webHTTPAddr @@ -554,6 +559,17 @@ func applyConfigOverrides(options serveOptions, config *Config) { if config.Frontend.Dir == "" { config.Frontend.Dir = os.Getenv("DEX_FRONTEND_DIR") } + + if len(config.OAuth2.GrantTypes) == 0 { + config.OAuth2.GrantTypes = []string{ + "authorization_code", + "implicit", + "password", + "refresh_token", + "urn:ietf:params:oauth:grant-type:device_code", + "urn:ietf:params:oauth:grant-type:token-exchange", + } + } } func pprofHandler(router *http.ServeMux) { @@ -563,3 +579,118 @@ func pprofHandler(router *http.ServeMux) { router.HandleFunc("/debug/pprof/symbol", pprof.Symbol) router.HandleFunc("/debug/pprof/trace", pprof.Trace) } + +// newTLSReloader returns a [tls.Config] with GetCertificate or GetConfigForClient set +// to reload certificates from the given paths on SIGHUP or on file creates (atomic update via rename). +func newTLSReloader(logger *slog.Logger, certFile, keyFile, caFile string, baseConfig *tls.Config) (*tls.Config, error) { + // trigger reload on channel + sigc := make(chan os.Signal, 1) + signal.Notify(sigc, syscall.SIGHUP) + + // files to watch + watchFiles := map[string]struct{}{ + certFile: {}, + keyFile: {}, + } + if caFile != "" { + watchFiles[caFile] = struct{}{} + } + watchDirs := make(map[string]struct{}) // dedupe dirs + for f := range watchFiles { + dir := filepath.Dir(f) + if !strings.HasPrefix(f, dir) { + // normalize name to have ./ prefix if only a local path was provided + // can't pass "" to watcher.Add + watchFiles[dir+string(filepath.Separator)+f] = struct{}{} + } + watchDirs[dir] = struct{}{} + } + // trigger reload on file change + watcher, err := fsnotify.NewWatcher() + if err != nil { + return nil, fmt.Errorf("create watcher for TLS reloader: %v", err) + } + // recommended by fsnotify: watch the dir to handle renames + // https://pkg.go.dev/github.com/fsnotify/fsnotify#hdr-Watching_files + for dir := range watchDirs { + logger.Debug("watching dir", "dir", dir) + err := watcher.Add(dir) + if err != nil { + return nil, fmt.Errorf("watch dir for TLS reloader: %v", err) + } + } + + // load once outside the goroutine so we can return an error on misconfig + initialConfig, err := loadTLSConfig(certFile, keyFile, caFile, baseConfig) + if err != nil { + return nil, fmt.Errorf("load TLS config: %v", err) + } + + // stored version of current tls config + ptr := &atomic.Pointer[tls.Config]{} + ptr.Store(initialConfig) + + // start background worker to reload certs + go func() { + loop: + for { + select { + case sig := <-sigc: + logger.Debug("reloading cert from signal", "signal", sig) + case evt := <-watcher.Events: + if _, ok := watchFiles[evt.Name]; !ok || !evt.Has(fsnotify.Create) { + continue loop + } + logger.Debug("reloading cert from fsnotify", "event", evt.Name, "operation", evt.Op.String()) + case err := <-watcher.Errors: + logger.Error("TLS reloader watch", "err", err) + } + + loaded, err := loadTLSConfig(certFile, keyFile, caFile, baseConfig) + if err != nil { + logger.Error("reload TLS config", "err", err) + } + ptr.Store(loaded) + } + }() + + // https://pkg.go.dev/crypto/tls#baseConfig + // Server configurations must set one of Certificates, GetCertificate or GetConfigForClient. + if caFile != "" { + // grpc will use this via tls.Server for mTLS + initialConfig.GetConfigForClient = func(chi *tls.ClientHelloInfo) (*tls.Config, error) { return ptr.Load(), nil } + } else { + // net/http only uses Certificates or GetCertificate + initialConfig.GetCertificate = func(chi *tls.ClientHelloInfo) (*tls.Certificate, error) { return &ptr.Load().Certificates[0], nil } + } + return initialConfig, nil +} + +// loadTLSConfig loads the given file paths into a [tls.Config] +func loadTLSConfig(certFile, keyFile, caFile string, baseConfig *tls.Config) (*tls.Config, error) { + cert, err := tls.LoadX509KeyPair(certFile, keyFile) + if err != nil { + return nil, fmt.Errorf("loading TLS keypair: %v", err) + } + loadedConfig := baseConfig.Clone() // copy + loadedConfig.Certificates = []tls.Certificate{cert} + if caFile != "" { + cPool := x509.NewCertPool() + clientCert, err := os.ReadFile(caFile) + if err != nil { + return nil, fmt.Errorf("reading from client CA file: %v", err) + } + if !cPool.AppendCertsFromPEM(clientCert) { + return nil, errors.New("failed to parse client CA") + } + + loadedConfig.ClientAuth = tls.RequireAndVerifyClientCert + loadedConfig.ClientCAs = cPool + } + return loadedConfig, nil +} + +// recordBuildInfo publishes information about Dex version and runtime info through an info metric (gauge). +func recordBuildInfo() { + buildInfo.WithLabelValues(version, runtime.Version(), fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)).Set(1) +} diff --git a/cmd/dex/serve_test.go b/cmd/dex/serve_test.go new file mode 100644 index 0000000000..9e214480d3 --- /dev/null +++ b/cmd/dex/serve_test.go @@ -0,0 +1,29 @@ +package main + +import ( + "log/slog" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewLogger(t *testing.T) { + t.Run("JSON", func(t *testing.T) { + logger, err := newLogger(slog.LevelInfo, "json") + require.NoError(t, err) + require.NotEqual(t, (*slog.Logger)(nil), logger) + }) + + t.Run("Text", func(t *testing.T) { + logger, err := newLogger(slog.LevelError, "text") + require.NoError(t, err) + require.NotEqual(t, (*slog.Logger)(nil), logger) + }) + + t.Run("Unknown", func(t *testing.T) { + logger, err := newLogger(slog.LevelError, "gofmt") + require.Error(t, err) + require.Equal(t, "log format is not one of the supported values (json, text): gofmt", err.Error()) + require.Equal(t, (*slog.Logger)(nil), logger) + }) +} diff --git a/cmd/docker-entrypoint/main.go b/cmd/docker-entrypoint/main.go index 0c507d1712..14d837e5ee 100644 --- a/cmd/docker-entrypoint/main.go +++ b/cmd/docker-entrypoint/main.go @@ -17,21 +17,18 @@ func main() { // Note that this docker-entrypoint program is args[0], and it is provided with the true process // args. args := os.Args[1:] + if len(args) == 0 { + fmt.Println("error: no args passed to entrypoint") + os.Exit(1) + } - if err := run(args, realExec, realWhich); err != nil { + if err := run(args, realExec, realWhich, realGomplate); err != nil { fmt.Println("error:", err.Error()) os.Exit(1) } } -func realExec(fork bool, args ...string) error { - if fork { - if output, err := exec.Command(args[0], args[1:]...).CombinedOutput(); err != nil { - return fmt.Errorf("cannot fork/exec command %s: %w (output: %q)", args, err, string(output)) - } - return nil - } - +func realExec(args ...string) error { argv0, err := exec.LookPath(args[0]) if err != nil { return fmt.Errorf("cannot lookup path for command %s: %w", args[0], err) @@ -52,34 +49,49 @@ func realWhich(path string) string { return fullPath } -func run(args []string, execFunc func(bool, ...string) error, whichFunc func(string) string) error { +func realGomplate(path string) (string, error) { + tmpFile, err := os.CreateTemp("/tmp", "dex.config.yaml-*") + if err != nil { + return "", fmt.Errorf("cannot create temp file: %w", err) + } + + cmd := exec.Command("gomplate", "-f", path, "-o", tmpFile.Name()) + // TODO(nabokihms): Workaround to run gomplate from a non-root directory in distroless images + // gomplate tries to access CWD on start, see: https://github.com/hairyhenderson/gomplate/pull/2202 + cmd.Dir = "/etc/dex" + + output, err := cmd.CombinedOutput() + if err != nil { + return "", fmt.Errorf("error executing gomplate: %w, (output: %q)", err, string(output)) + } + + return tmpFile.Name(), nil +} + +func run(args []string, execFunc func(...string) error, whichFunc func(string) string, gomplateFunc func(string) (string, error)) error { if args[0] != "dex" && args[0] != whichFunc("dex") { - return execFunc(false, args...) + return execFunc(args...) } if args[1] != "serve" { - return execFunc(false, args...) + return execFunc(args...) } newArgs := []string{} for _, tplCandidate := range args { if hasSuffixes(tplCandidate, ".tpl", ".tmpl", ".yaml") { - tmpFile, err := os.CreateTemp("/tmp", "dex.config.yaml-*") + fileName, err := gomplateFunc(tplCandidate) if err != nil { - return fmt.Errorf("cannot create temp file: %w", err) - } - - if err := execFunc(true, "gomplate", "-f", tplCandidate, "-o", tmpFile.Name()); err != nil { return err } - newArgs = append(newArgs, tmpFile.Name()) + newArgs = append(newArgs, fileName) } else { newArgs = append(newArgs, tplCandidate) } } - return execFunc(false, newArgs...) + return execFunc(newArgs...) } func hasSuffixes(s string, suffixes ...string) bool { diff --git a/cmd/docker-entrypoint/main_test.go b/cmd/docker-entrypoint/main_test.go index c8aef16979..49da3b5f02 100644 --- a/cmd/docker-entrypoint/main_test.go +++ b/cmd/docker-entrypoint/main_test.go @@ -6,7 +6,7 @@ import ( ) type execArgs struct { - fork bool + gomplate bool argPrefixes []string } @@ -16,98 +16,89 @@ func TestRun(t *testing.T) { args []string execReturns error whichReturns string - wantExecArgs []execArgs + wantExecArgs execArgs wantErr error }{ { name: "executable not dex", args: []string{"tuna", "fish"}, - wantExecArgs: []execArgs{{fork: false, argPrefixes: []string{"tuna", "fish"}}}, + wantExecArgs: execArgs{gomplate: false, argPrefixes: []string{"tuna", "fish"}}, }, { name: "executable is full path to dex", args: []string{"/usr/local/bin/dex", "marshmallow", "zelda"}, whichReturns: "/usr/local/bin/dex", - wantExecArgs: []execArgs{{fork: false, argPrefixes: []string{"/usr/local/bin/dex", "marshmallow", "zelda"}}}, + wantExecArgs: execArgs{gomplate: false, argPrefixes: []string{"/usr/local/bin/dex", "marshmallow", "zelda"}}, }, { name: "command is not serve", args: []string{"dex", "marshmallow", "zelda"}, - wantExecArgs: []execArgs{{fork: false, argPrefixes: []string{"dex", "marshmallow", "zelda"}}}, + wantExecArgs: execArgs{gomplate: false, argPrefixes: []string{"dex", "marshmallow", "zelda"}}, }, { name: "no templates", args: []string{"dex", "serve", "config.yaml.not-a-template"}, - wantExecArgs: []execArgs{{fork: false, argPrefixes: []string{"dex", "serve", "config.yaml.not-a-template"}}}, + wantExecArgs: execArgs{gomplate: false, argPrefixes: []string{"dex", "serve", "config.yaml.not-a-template"}}, }, { name: "no templates", args: []string{"dex", "serve", "config.yaml.not-a-template"}, - wantExecArgs: []execArgs{{fork: false, argPrefixes: []string{"dex", "serve", "config.yaml.not-a-template"}}}, + wantExecArgs: execArgs{gomplate: false, argPrefixes: []string{"dex", "serve", "config.yaml.not-a-template"}}, }, { - name: ".tpl template", - args: []string{"dex", "serve", "config.tpl"}, - wantExecArgs: []execArgs{ - {fork: true, argPrefixes: []string{"gomplate", "-f", "config.tpl", "-o", "/tmp/dex.config.yaml-"}}, - {fork: false, argPrefixes: []string{"dex", "serve", "/tmp/dex.config.yaml-"}}, - }, + name: ".tpl template", + args: []string{"dex", "serve", "config.tpl"}, + wantExecArgs: execArgs{gomplate: true, argPrefixes: []string{"dex", "serve", "/tmp/dex.config.yaml-"}}, }, { - name: ".tmpl template", - args: []string{"dex", "serve", "config.tmpl"}, - wantExecArgs: []execArgs{ - {fork: true, argPrefixes: []string{"gomplate", "-f", "config.tmpl", "-o", "/tmp/dex.config.yaml-"}}, - {fork: false, argPrefixes: []string{"dex", "serve", "/tmp/dex.config.yaml-"}}, - }, + name: ".tmpl template", + args: []string{"dex", "serve", "config.tmpl"}, + wantExecArgs: execArgs{gomplate: true, argPrefixes: []string{"dex", "serve", "/tmp/dex.config.yaml-"}}, }, { - name: ".yaml template", - args: []string{"dex", "serve", "some/path/config.yaml"}, - wantExecArgs: []execArgs{ - {fork: true, argPrefixes: []string{"gomplate", "-f", "some/path/config.yaml", "-o", "/tmp/dex.config.yaml-"}}, - {fork: false, argPrefixes: []string{"dex", "serve", "/tmp/dex.config.yaml-"}}, - }, + name: ".yaml template", + args: []string{"dex", "serve", "some/path/config.yaml"}, + wantExecArgs: execArgs{gomplate: true, argPrefixes: []string{"dex", "serve", "/tmp/dex.config.yaml-"}}, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - var gotExecForks []bool - var gotExecArgs [][]string - fakeExec := func(fork bool, args ...string) error { - gotExecForks = append(gotExecForks, fork) - gotExecArgs = append(gotExecArgs, args) + var gotExecArgs []string + var runsGomplate bool + + fakeExec := func(args ...string) error { + gotExecArgs = append(args, gotExecArgs...) return test.execReturns } fakeWhich := func(_ string) string { return test.whichReturns } - gotErr := run(test.args, fakeExec, fakeWhich) + fakeGomplate := func(file string) (string, error) { + runsGomplate = true + return "/tmp/dex.config.yaml-", nil + } + + gotErr := run(test.args, fakeExec, fakeWhich, fakeGomplate) if (test.wantErr == nil) != (gotErr == nil) { t.Errorf("wanted error %s, got %s", test.wantErr, gotErr) } - if !execArgsMatch(test.wantExecArgs, gotExecForks, gotExecArgs) { - t.Errorf("wanted exec args %+v, got %+v %+v", test.wantExecArgs, gotExecForks, gotExecArgs) + + if !execArgsMatch(test.wantExecArgs, runsGomplate, gotExecArgs) { + t.Errorf("wanted exec args %+v (running gomplate: %+v), got %+v (running gomplate: %+v)", + test.wantExecArgs.argPrefixes, test.wantExecArgs.gomplate, gotExecArgs, runsGomplate) } }) } } -func execArgsMatch(wantExecArgs []execArgs, gotForks []bool, gotExecArgs [][]string) bool { - if len(wantExecArgs) != len(gotForks) { +func execArgsMatch(wantExecArgs execArgs, gomplate bool, gotExecArgs []string) bool { + if wantExecArgs.gomplate != gomplate { return false } - - for i := range wantExecArgs { - if wantExecArgs[i].fork != gotForks[i] { + for i := range wantExecArgs.argPrefixes { + if !strings.HasPrefix(gotExecArgs[i], wantExecArgs.argPrefixes[i]) { return false } - for j := range wantExecArgs[i].argPrefixes { - if !strings.HasPrefix(gotExecArgs[i][j], wantExecArgs[i].argPrefixes[j]) { - return false - } - } } - return true } diff --git a/config.yaml.dist b/config.yaml.dist index ba7bad68e0..b7e1410ffc 100644 --- a/config.yaml.dist +++ b/config.yaml.dist @@ -55,6 +55,8 @@ web: # https: 127.0.0.1:5554 # tlsCert: /etc/dex/tls.crt # tlsKey: /etc/dex/tls.key + # tlsMinVersion: 1.2 + # tlsMaxVersion: 1.3 # Dex UI configuration # frontend: @@ -118,7 +120,7 @@ web: # name: 'Example App' # secret: ZXhhbXBsZS1hcHAtc2VjcmV0 -# Connectors are used to authenticate users agains upstream identity providers. +# Connectors are used to authenticate users against upstream identity providers. # # See the documentation (https://dexidp.io/docs/connectors/) for further information. # connectors: [] diff --git a/connector/atlassiancrowd/atlassiancrowd.go b/connector/atlassiancrowd/atlassiancrowd.go index e2ca94b0de..d36832846e 100644 --- a/connector/atlassiancrowd/atlassiancrowd.go +++ b/connector/atlassiancrowd/atlassiancrowd.go @@ -7,6 +7,7 @@ import ( "encoding/json" "fmt" "io" + "log/slog" "net" "net/http" "strings" @@ -14,7 +15,6 @@ import ( "github.com/dexidp/dex/connector" "github.com/dexidp/dex/pkg/groups" - "github.com/dexidp/dex/pkg/log" ) // Config holds configuration options for Atlassian Crowd connector. @@ -24,18 +24,17 @@ import ( // // An example config: // -// type: atlassian-crowd -// config: -// baseURL: https://crowd.example.com/context -// clientID: applogin -// clientSecret: appP4$$w0rd -// # users can be restricted by a list of groups -// groups: -// - admin -// # Prompt for username field -// usernamePrompt: Login -// preferredUsernameField: name -// +// type: atlassian-crowd +// config: +// baseURL: https://crowd.example.com/context +// clientID: applogin +// clientSecret: appP4$$w0rd +// # users can be restricted by a list of groups +// groups: +// - admin +// # Prompt for username field +// usernamePrompt: Login +// preferredUsernameField: name type Config struct { BaseURL string `json:"baseURL"` ClientID string `json:"clientID"` @@ -81,16 +80,16 @@ type crowdAuthenticationError struct { } // Open returns a strategy for logging in through Atlassian Crowd -func (c *Config) Open(_ string, logger log.Logger) (connector.Connector, error) { +func (c *Config) Open(id string, logger *slog.Logger) (connector.Connector, error) { if c.BaseURL == "" { return nil, fmt.Errorf("crowd: no baseURL provided for crowd connector") } - return &crowdConnector{Config: *c, logger: logger}, nil + return &crowdConnector{Config: *c, logger: logger.With(slog.Group("connector", "type", "atlassiancrowd", "id", id))}, nil } type crowdConnector struct { Config - logger log.Logger + logger *slog.Logger } var ( @@ -376,7 +375,7 @@ func (c *crowdConnector) identityFromCrowdUser(user crowdUser) connector.Identit identity.PreferredUsername = user.Email default: if c.PreferredUsernameField != "" { - c.logger.Warnf("preferred_username left empty. Invalid crowd field mapped to preferred_username: %s", c.PreferredUsernameField) + c.logger.Warn("preferred_username left empty. Invalid crowd field mapped to preferred_username", "field", c.PreferredUsernameField) } } @@ -437,12 +436,12 @@ func (c *crowdConnector) validateCrowdResponse(resp *http.Response) ([]byte, err } if resp.StatusCode == http.StatusForbidden && strings.Contains(string(body), "The server understood the request but refuses to authorize it.") { - c.logger.Debugf("crowd response validation failed: %s", string(body)) + c.logger.Debug("crowd response validation failed", "response", string(body)) return nil, fmt.Errorf("dex is forbidden from making requests to the Atlassian Crowd application by URL %q", c.BaseURL) } if resp.StatusCode == http.StatusUnauthorized && string(body) == "Application failed to authenticate" { - c.logger.Debugf("crowd response validation failed: %s", string(body)) + c.logger.Debug("crowd response validation failed", "response", string(body)) return nil, fmt.Errorf("dex failed to authenticate Crowd Application with ID %q", c.ClientID) } return body, nil diff --git a/connector/atlassiancrowd/atlassiancrowd_test.go b/connector/atlassiancrowd/atlassiancrowd_test.go index 36789a3919..17d0422ac8 100644 --- a/connector/atlassiancrowd/atlassiancrowd_test.go +++ b/connector/atlassiancrowd/atlassiancrowd_test.go @@ -6,13 +6,11 @@ import ( "crypto/tls" "encoding/json" "fmt" - "io" + "log/slog" "net/http" "net/http/httptest" "reflect" "testing" - - "github.com/sirupsen/logrus" ) func TestUserGroups(t *testing.T) { @@ -115,7 +113,7 @@ func TestIdentityFromCrowdUser(t *testing.T) { expectEquals(t, user.Name, "testuser") expectEquals(t, user.Email, "testuser@example.com") - // Test unconfigured behaviour + // Test unconfigured behavior i := c.identityFromCrowdUser(user) expectEquals(t, i.UserID, "12345") expectEquals(t, i.Username, "testuser") @@ -151,11 +149,7 @@ type TestServerResponse struct { func newTestCrowdConnector(baseURL string) crowdConnector { connector := crowdConnector{} connector.BaseURL = baseURL - connector.logger = &logrus.Logger{ - Out: io.Discard, - Level: logrus.DebugLevel, - Formatter: &logrus.TextFormatter{DisableColors: true}, - } + connector.logger = slog.New(slog.DiscardHandler) return connector } diff --git a/connector/authproxy/authproxy.go b/connector/authproxy/authproxy.go index 8715412146..f3d87fcb56 100644 --- a/connector/authproxy/authproxy.go +++ b/connector/authproxy/authproxy.go @@ -5,12 +5,12 @@ package authproxy import ( "fmt" + "log/slog" "net/http" "net/url" "strings" "github.com/dexidp/dex/connector" - "github.com/dexidp/dex/pkg/log" ) // Config holds the configuration parameters for a connector which returns an @@ -19,33 +19,67 @@ import ( // Headers retrieved to fetch user's email and group can be configured // with userHeader and groupHeader. type Config struct { - UserHeader string `json:"userHeader"` - GroupHeader string `json:"groupHeader"` - Groups []string `json:"staticGroups"` + UserIDHeader string `json:"userIDHeader"` + UserHeader string `json:"userHeader"` + UserNameHeader string `json:"userNameHeader"` + EmailHeader string `json:"emailHeader"` + GroupHeader string `json:"groupHeader"` + GroupHeaderSeparator string `json:"groupHeaderSeparator"` + Groups []string `json:"staticGroups"` } // Open returns an authentication strategy which requires no user interaction. -func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) { +func (c *Config) Open(id string, logger *slog.Logger) (connector.Connector, error) { + userIDHeader := c.UserIDHeader + if userIDHeader == "" { + userIDHeader = "X-Remote-User-Id" + } userHeader := c.UserHeader if userHeader == "" { userHeader = "X-Remote-User" } + userNameHeader := c.UserNameHeader + if userNameHeader == "" { + userNameHeader = "X-Remote-User-Name" + } + emailHeader := c.EmailHeader + if emailHeader == "" { + emailHeader = "X-Remote-User-Email" + } groupHeader := c.GroupHeader if groupHeader == "" { groupHeader = "X-Remote-Group" } + groupHeaderSeparator := c.GroupHeaderSeparator + if groupHeaderSeparator == "" { + groupHeaderSeparator = "," + } - return &callback{userHeader: userHeader, groupHeader: groupHeader, logger: logger, pathSuffix: "/" + id, groups: c.Groups}, nil + return &callback{ + userIDHeader: userIDHeader, + userHeader: userHeader, + userNameHeader: userNameHeader, + emailHeader: emailHeader, + groupHeader: groupHeader, + groupHeaderSeparator: groupHeaderSeparator, + groups: c.Groups, + logger: logger.With(slog.Group("connector", "type", "authproxy", "id", id)), + pathSuffix: "/" + id, + }, nil } // Callback is a connector which returns an identity with the HTTP header // X-Remote-User as verified email. type callback struct { - userHeader string - groupHeader string - groups []string - logger log.Logger - pathSuffix string + userIDHeader string + userNameHeader string + userHeader string + emailHeader string + groupHeader string + groupHeaderSeparator string + groups []string + logger *slog.Logger + pathSuffix string } // LoginURL returns the URL to redirect the user to login with. @@ -67,19 +101,33 @@ func (m *callback) HandleCallback(s connector.Scopes, r *http.Request) (connecto if remoteUser == "" { return connector.Identity{}, fmt.Errorf("required HTTP header %s is not set", m.userHeader) } + remoteUserName := r.Header.Get(m.userNameHeader) + if remoteUserName == "" { + remoteUserName = remoteUser + } + remoteUserID := r.Header.Get(m.userIDHeader) + if remoteUserID == "" { + remoteUserID = remoteUser + } + remoteUserEmail := r.Header.Get(m.emailHeader) + if remoteUserEmail == "" { + remoteUserEmail = remoteUser + } groups := m.groups headerGroup := r.Header.Get(m.groupHeader) if headerGroup != "" { - splitheaderGroup := strings.Split(headerGroup, ",") + splitheaderGroup := strings.Split(headerGroup, m.groupHeaderSeparator) for i, v := range splitheaderGroup { splitheaderGroup[i] = strings.TrimSpace(v) } groups = append(splitheaderGroup, groups...) } return connector.Identity{ - UserID: remoteUser, // TODO: figure out if this is a bad ID value. - Email: remoteUser, - EmailVerified: true, - Groups: groups, + UserID: remoteUserID, + Username: remoteUser, + PreferredUsername: remoteUserName, + Email: remoteUserEmail, + EmailVerified: true, + Groups: groups, }, nil } diff --git a/connector/authproxy/authproxy_test.go b/connector/authproxy/authproxy_test.go index 5d42530e07..fbdd2a5d91 100644 --- a/connector/authproxy/authproxy_test.go +++ b/connector/authproxy/authproxy_test.go @@ -1,55 +1,82 @@ package authproxy import ( - "io" + "log/slog" "net/http" "reflect" "testing" - "github.com/sirupsen/logrus" - "github.com/dexidp/dex/connector" ) const ( - testEmail = "testuser@example.com" - testGroup1 = "group1" - testGroup2 = "group2" - testGroup3 = "group 3" - testGroup4 = "group 4" - testStaticGroup1 = "static1" - testStaticGroup2 = "static 2" + testEmail = "testuser@example.com" + testGroup1 = "group1" + testGroup2 = "group2" + testGroup3 = "group 3" + testGroup4 = "group 4" + testStaticGroup1 = "static1" + testStaticGroup2 = "static 2" + testUsername = "Test User" + testPreferredUsername = "testuser" + testUserID = "1234567890" ) -var logger = &logrus.Logger{Out: io.Discard, Formatter: &logrus.TextFormatter{}} +var logger = slog.New(slog.DiscardHandler) func TestUser(t *testing.T) { - config := Config{ - UserHeader: "X-Remote-User", + config := Config{} + + conn, _ := config.Open("test", logger) + callback := conn.(*callback) + + req, err := http.NewRequest("GET", "/", nil) + expectNil(t, err) + req.Header = map[string][]string{ + "X-Remote-User": {testUsername}, } - conn := callback{userHeader: config.UserHeader, logger: logger, pathSuffix: "/test"} + + ident, err := callback.HandleCallback(connector.Scopes{OfflineAccess: true, Groups: true}, req) + expectNil(t, err) + + // If not specified, the userID and email should fall back to the remote user + expectEquals(t, ident.UserID, testUsername) + expectEquals(t, ident.PreferredUsername, testUsername) + expectEquals(t, ident.Username, testUsername) + expectEquals(t, ident.Email, testUsername) + expectEquals(t, len(ident.Groups), 0) +} + +func TestExtraHeaders(t *testing.T) { + config := Config{} + + conn, _ := config.Open("test", logger) + callback := conn.(*callback) req, err := http.NewRequest("GET", "/", nil) expectNil(t, err) req.Header = map[string][]string{ - "X-Remote-User": {testEmail}, + "X-Remote-User-Id": {testUserID}, + "X-Remote-User": {testUsername}, + "X-Remote-User-Name": {testPreferredUsername}, + "X-Remote-User-Email": {testEmail}, } - ident, err := conn.HandleCallback(connector.Scopes{OfflineAccess: true, Groups: true}, req) + ident, err := callback.HandleCallback(connector.Scopes{OfflineAccess: true, Groups: true}, req) expectNil(t, err) - expectEquals(t, ident.UserID, testEmail) + expectEquals(t, ident.UserID, testUserID) + expectEquals(t, ident.PreferredUsername, testPreferredUsername) + expectEquals(t, ident.Username, testUsername) expectEquals(t, ident.Email, testEmail) expectEquals(t, len(ident.Groups), 0) } func TestSingleGroup(t *testing.T) { - config := Config{ - UserHeader: "X-Remote-User", - GroupHeader: "X-Remote-Group", - } + config := Config{} - conn := callback{userHeader: config.UserHeader, groupHeader: config.GroupHeader, logger: logger, pathSuffix: "/test"} + conn, _ := config.Open("test", logger) + callback := conn.(*callback) req, err := http.NewRequest("GET", "/", nil) expectNil(t, err) @@ -58,7 +85,7 @@ func TestSingleGroup(t *testing.T) { "X-Remote-Group": {testGroup1}, } - ident, err := conn.HandleCallback(connector.Scopes{OfflineAccess: true, Groups: true}, req) + ident, err := callback.HandleCallback(connector.Scopes{OfflineAccess: true, Groups: true}, req) expectNil(t, err) expectEquals(t, ident.UserID, testEmail) @@ -67,21 +94,45 @@ func TestSingleGroup(t *testing.T) { } func TestMultipleGroup(t *testing.T) { + config := Config{} + + conn, _ := config.Open("test", logger) + callback := conn.(*callback) + + req, err := http.NewRequest("GET", "/", nil) + expectNil(t, err) + req.Header = map[string][]string{ + "X-Remote-User": {testEmail}, + "X-Remote-Group": {testGroup1 + ", " + testGroup2 + ", " + testGroup3 + ", " + testGroup4}, + } + + ident, err := callback.HandleCallback(connector.Scopes{OfflineAccess: true, Groups: true}, req) + expectNil(t, err) + + expectEquals(t, ident.UserID, testEmail) + expectEquals(t, len(ident.Groups), 4) + expectEquals(t, ident.Groups[0], testGroup1) + expectEquals(t, ident.Groups[1], testGroup2) + expectEquals(t, ident.Groups[2], testGroup3) + expectEquals(t, ident.Groups[3], testGroup4) +} + +func TestMultipleGroupWithCustomSeparator(t *testing.T) { config := Config{ - UserHeader: "X-Remote-User", - GroupHeader: "X-Remote-Group", + GroupHeaderSeparator: ";", } - conn := callback{userHeader: config.UserHeader, groupHeader: config.GroupHeader, logger: logger, pathSuffix: "/test"} + conn, _ := config.Open("test", logger) + callback := conn.(*callback) req, err := http.NewRequest("GET", "/", nil) expectNil(t, err) req.Header = map[string][]string{ "X-Remote-User": {testEmail}, - "X-Remote-Group": {testGroup1 + ", " + testGroup2 + ", " + testGroup3 + ", " + testGroup4}, + "X-Remote-Group": {testGroup1 + ";" + testGroup2 + ";" + testGroup3 + ";" + testGroup4}, } - ident, err := conn.HandleCallback(connector.Scopes{OfflineAccess: true, Groups: true}, req) + ident, err := callback.HandleCallback(connector.Scopes{OfflineAccess: true, Groups: true}, req) expectNil(t, err) expectEquals(t, ident.UserID, testEmail) @@ -94,12 +145,11 @@ func TestMultipleGroup(t *testing.T) { func TestStaticGroup(t *testing.T) { config := Config{ - UserHeader: "X-Remote-User", - GroupHeader: "X-Remote-Group", - Groups: []string{"static1", "static 2"}, + Groups: []string{"static1", "static 2"}, } - conn := callback{userHeader: config.UserHeader, groupHeader: config.GroupHeader, groups: config.Groups, logger: logger, pathSuffix: "/test"} + conn, _ := config.Open("test", logger) + callback := conn.(*callback) req, err := http.NewRequest("GET", "/", nil) expectNil(t, err) @@ -108,7 +158,7 @@ func TestStaticGroup(t *testing.T) { "X-Remote-Group": {testGroup1 + ", " + testGroup2 + ", " + testGroup3 + ", " + testGroup4}, } - ident, err := conn.HandleCallback(connector.Scopes{OfflineAccess: true, Groups: true}, req) + ident, err := callback.HandleCallback(connector.Scopes{OfflineAccess: true, Groups: true}, req) expectNil(t, err) expectEquals(t, ident.UserID, testEmail) diff --git a/connector/bitbucketcloud/bitbucketcloud.go b/connector/bitbucketcloud/bitbucketcloud.go index 27eafb5299..5f802e3414 100644 --- a/connector/bitbucketcloud/bitbucketcloud.go +++ b/connector/bitbucketcloud/bitbucketcloud.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "io" + "log/slog" "net/http" "sync" "time" @@ -16,7 +17,6 @@ import ( "github.com/dexidp/dex/connector" "github.com/dexidp/dex/pkg/groups" - "github.com/dexidp/dex/pkg/log" ) const ( @@ -42,7 +42,7 @@ type Config struct { } // Open returns a strategy for logging in through Bitbucket. -func (c *Config) Open(_ string, logger log.Logger) (connector.Connector, error) { +func (c *Config) Open(id string, logger *slog.Logger) (connector.Connector, error) { b := bitbucketConnector{ redirectURI: c.RedirectURI, teams: c.Teams, @@ -51,7 +51,7 @@ func (c *Config) Open(_ string, logger log.Logger) (connector.Connector, error) includeTeamGroups: c.IncludeTeamGroups, apiURL: apiURL, legacyAPIURL: legacyAPIURL, - logger: logger, + logger: logger.With(slog.Group("connector", "type", "bitbucketcloud", "id", id)), } return &b, nil @@ -73,7 +73,7 @@ type bitbucketConnector struct { teams []string clientID string clientSecret string - logger log.Logger + logger *slog.Logger apiURL string legacyAPIURL string diff --git a/connector/connector.go b/connector/connector.go index aab994b468..d812390f0c 100644 --- a/connector/connector.go +++ b/connector/connector.go @@ -70,7 +70,8 @@ type CallbackConnector interface { } // SAMLConnector represents SAML connectors which implement the HTTP POST binding. -// RelayState is handled by the server. +// +// RelayState is handled by the server. // // See: https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf // "3.5 HTTP POST Binding" @@ -98,3 +99,7 @@ type RefreshConnector interface { // changes since the token was last refreshed. Refresh(ctx context.Context, s Scopes, identity Identity) (Identity, error) } + +type TokenIdentityConnector interface { + TokenIdentity(ctx context.Context, subjectTokenType, subjectToken string) (Identity, error) +} diff --git a/connector/gitea/gitea.go b/connector/gitea/gitea.go index 6b02099414..62523185d5 100644 --- a/connector/gitea/gitea.go +++ b/connector/gitea/gitea.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "io" + "log/slog" "net/http" "strconv" "sync" @@ -15,7 +16,6 @@ import ( "golang.org/x/oauth2" "github.com/dexidp/dex/connector" - "github.com/dexidp/dex/pkg/log" ) // Config holds configuration options for gitea logins. @@ -51,7 +51,7 @@ type giteaUser struct { } // Open returns a strategy for logging in through Gitea -func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) { +func (c *Config) Open(id string, logger *slog.Logger) (connector.Connector, error) { if c.BaseURL == "" { c.BaseURL = "https://gitea.com" } @@ -61,7 +61,7 @@ func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) orgs: c.Orgs, clientID: c.ClientID, clientSecret: c.ClientSecret, - logger: logger, + logger: logger.With(slog.Group("connector", "type", "gitea", "id", id)), loadAllGroups: c.LoadAllGroups, useLoginAsID: c.UseLoginAsID, }, nil @@ -84,7 +84,7 @@ type giteaConnector struct { orgs []Org clientID string clientSecret string - logger log.Logger + logger *slog.Logger httpClient *http.Client // if set to true and no orgs are configured then connector loads all user claims (all orgs and team) loadAllGroups bool diff --git a/connector/github/github.go b/connector/github/github.go index ef8d418fa8..18a56628af 100644 --- a/connector/github/github.go +++ b/connector/github/github.go @@ -3,26 +3,22 @@ package github import ( "context" - "crypto/tls" - "crypto/x509" "encoding/json" "errors" "fmt" "io" - "net" + "log/slog" "net/http" - "os" "regexp" "strconv" "strings" - "time" "golang.org/x/oauth2" "golang.org/x/oauth2/github" "github.com/dexidp/dex/connector" groups_pkg "github.com/dexidp/dex/pkg/groups" - "github.com/dexidp/dex/pkg/log" + "github.com/dexidp/dex/pkg/httpclient" ) const ( @@ -43,16 +39,17 @@ var ( // Config holds configuration options for github logins. type Config struct { - ClientID string `json:"clientID"` - ClientSecret string `json:"clientSecret"` - RedirectURI string `json:"redirectURI"` - Org string `json:"org"` - Orgs []Org `json:"orgs"` - HostName string `json:"hostName"` - RootCA string `json:"rootCA"` - TeamNameField string `json:"teamNameField"` - LoadAllGroups bool `json:"loadAllGroups"` - UseLoginAsID bool `json:"useLoginAsID"` + ClientID string `json:"clientID"` + ClientSecret string `json:"clientSecret"` + RedirectURI string `json:"redirectURI"` + Org string `json:"org"` + Orgs []Org `json:"orgs"` + HostName string `json:"hostName"` + RootCA string `json:"rootCA"` + TeamNameField string `json:"teamNameField"` + LoadAllGroups bool `json:"loadAllGroups"` + UseLoginAsID bool `json:"useLoginAsID"` + PreferredEmailDomain string `json:"preferredEmailDomain"` } // Org holds org-team filters, in which teams are optional. @@ -69,7 +66,7 @@ type Org struct { } // Open returns a strategy for logging in through GitHub. -func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) { +func (c *Config) Open(id string, logger *slog.Logger) (connector.Connector, error) { if c.Org != "" { // Return error if both 'org' and 'orgs' fields are used. if len(c.Orgs) > 0 { @@ -79,14 +76,15 @@ func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) } g := githubConnector{ - redirectURI: c.RedirectURI, - org: c.Org, - orgs: c.Orgs, - clientID: c.ClientID, - clientSecret: c.ClientSecret, - apiURL: apiURL, - logger: logger, - useLoginAsID: c.UseLoginAsID, + redirectURI: c.RedirectURI, + org: c.Org, + orgs: c.Orgs, + clientID: c.ClientID, + clientSecret: c.ClientSecret, + apiURL: apiURL, + logger: logger.With(slog.Group("connector", "type", "github", "id", id)), + useLoginAsID: c.UseLoginAsID, + preferredEmailDomain: c.PreferredEmailDomain, } if c.HostName != "" { @@ -106,7 +104,7 @@ func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) g.rootCA = c.RootCA var err error - if g.httpClient, err = newHTTPClient(g.rootCA); err != nil { + if g.httpClient, err = httpclient.NewHTTPClient([]string{g.rootCA}, false); err != nil { return nil, fmt.Errorf("failed to create HTTP client: %v", err) } } @@ -119,6 +117,12 @@ func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) return nil, fmt.Errorf("invalid connector config: unsupported team name field value `%s`", c.TeamNameField) } + if c.PreferredEmailDomain != "" { + if strings.HasSuffix(c.PreferredEmailDomain, "*") { + return nil, errors.New("invalid PreferredEmailDomain: glob pattern cannot end with \"*\"") + } + } + return &g, nil } @@ -138,7 +142,7 @@ type githubConnector struct { orgs []Org clientID string clientSecret string - logger log.Logger + logger *slog.Logger // apiURL defaults to "https://api.github.com" apiURL string // hostName of the GitHub enterprise account. @@ -153,6 +157,8 @@ type githubConnector struct { loadAllGroups bool // if set to true will use the user's handle rather than their numeric id as the ID useLoginAsID bool + // the domain to be preferred among the user's emails. e.g. "github.com" + preferredEmailDomain string } // groupsRequired returns whether dex requires GitHub's 'read:org' scope. Dex @@ -208,34 +214,6 @@ func (e *oauth2Error) Error() string { return e.error + ": " + e.errorDescription } -// newHTTPClient returns a new HTTP client that trusts the custom declared rootCA cert. -func newHTTPClient(rootCA string) (*http.Client, error) { - tlsConfig := tls.Config{RootCAs: x509.NewCertPool()} - rootCABytes, err := os.ReadFile(rootCA) - if err != nil { - return nil, fmt.Errorf("failed to read root-ca: %v", err) - } - if !tlsConfig.RootCAs.AppendCertsFromPEM(rootCABytes) { - return nil, fmt.Errorf("no certs found in root CA file %q", rootCA) - } - - return &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: &tlsConfig, - Proxy: http.ProxyFromEnvironment, - DialContext: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - DualStack: true, - }).DialContext, - MaxIdleConns: 100, - IdleConnTimeout: 90 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, - }, - }, nil -} - func (c *githubConnector) HandleCallback(s connector.Scopes, r *http.Request) (identity connector.Identity, err error) { q := r.URL.Query() if errType := q.Get("error"); errType != "" { @@ -356,9 +334,11 @@ func formatTeamName(org string, team string) string { // groupsForOrgs enforces org and team constraints on user authorization // Cases in which user is authorized: -// N orgs, no teams: user is member of at least 1 org -// N orgs, M teams per org: user is member of any team from at least 1 org -// N-1 orgs, M teams per org, 1 org with no teams: user is member of any team +// +// N orgs, no teams: user is member of at least 1 org +// N orgs, M teams per org: user is member of any team from at least 1 org +// N-1 orgs, M teams per org, 1 org with no teams: user is member of any team +// // from at least 1 org, or member of org with no teams func (c *githubConnector) groupsForOrgs(ctx context.Context, client *http.Client, userName string) ([]string, error) { groups := make([]string, 0) @@ -382,7 +362,7 @@ func (c *githubConnector) groupsForOrgs(ctx context.Context, client *http.Client if len(org.Teams) == 0 { inOrgNoTeams = true } else if teams = groups_pkg.Filter(teams, org.Teams); len(teams) == 0 { - c.logger.Infof("github: user %q in org %q but no teams", userName, org.Name) + c.logger.Info("user in org but no teams", "user", userName, "org", org.Name) } for _, teamName := range teams { @@ -551,9 +531,10 @@ func (c *githubConnector) user(ctx context.Context, client *http.Client) (user, return u, err } - // Only public user emails are returned by 'GET /user'. u.Email will be empty - // if a users' email is private. We must retrieve private emails explicitly. - if u.Email == "" { + // Only public user emails are returned by 'GET /user'. + // If a user has no public email, we must retrieve private emails explicitly. + // If preferredEmailDomain is set, we always need to retrieve all emails. + if u.Email == "" || c.preferredEmailDomain != "" { var err error if u.Email, err = c.userEmail(ctx, client); err != nil { return u, err @@ -578,7 +559,13 @@ type userEmail struct { // The HTTP client is expected to be constructed by the golang.org/x/oauth2 package, // which inserts a bearer token as part of the request. func (c *githubConnector) userEmail(ctx context.Context, client *http.Client) (string, error) { + var ( + primaryEmail userEmail + preferredEmails []userEmail + ) + apiURL := c.apiURL + "/user/emails" + for { // https://developer.github.com/v3/users/emails/#list-email-addresses-for-a-user var ( @@ -605,7 +592,17 @@ func (c *githubConnector) userEmail(ctx context.Context, client *http.Client) (s } if email.Verified && email.Primary { - return email.Email, nil + primaryEmail = email + } + + if c.preferredEmailDomain != "" { + _, domainPart, ok := strings.Cut(email.Email, "@") + if !ok { + return "", errors.New("github: invalid format email is detected") + } + if email.Verified && c.isPreferredEmailDomain(domainPart) { + preferredEmails = append(preferredEmails, email) + } } } @@ -614,7 +611,36 @@ func (c *githubConnector) userEmail(ctx context.Context, client *http.Client) (s } } - return "", errors.New("github: user has no verified, primary email") + if len(preferredEmails) > 0 { + return preferredEmails[0].Email, nil + } + + if primaryEmail.Email != "" { + return primaryEmail.Email, nil + } + + return "", errors.New("github: user has no verified, primary email or preferred-domain email") +} + +// isPreferredEmailDomain checks the domain is matching with preferredEmailDomain. +func (c *githubConnector) isPreferredEmailDomain(domain string) bool { + if domain == c.preferredEmailDomain { + return true + } + + preferredDomainParts := strings.Split(c.preferredEmailDomain, ".") + domainParts := strings.Split(domain, ".") + + if len(preferredDomainParts) != len(domainParts) { + return false + } + + for i, v := range preferredDomainParts { + if domainParts[i] != v && v != "*" { + return false + } + } + return true } // userInOrg queries the GitHub API for a users' org membership. @@ -642,7 +668,7 @@ func (c *githubConnector) userInOrg(ctx context.Context, client *http.Client, us switch resp.StatusCode { case http.StatusNoContent: case http.StatusFound, http.StatusNotFound: - c.logger.Infof("github: user %q not in org %q or application not authorized to read org data", userName, orgName) + c.logger.Info("user not in org or application not authorized to read org data", "user", userName, "org", orgName) default: err = fmt.Errorf("github: unexpected return status: %q", resp.Status) } diff --git a/connector/github/github_test.go b/connector/github/github_test.go index 76d7463cf6..a2222cc1bf 100644 --- a/connector/github/github_test.go +++ b/connector/github/github_test.go @@ -4,7 +4,9 @@ import ( "context" "crypto/tls" "encoding/json" + "errors" "fmt" + "log/slog" "net/http" "net/http/httptest" "net/url" @@ -198,6 +200,291 @@ func TestLoginUsedAsIDWhenConfigured(t *testing.T) { expectEquals(t, identity.Username, "Joe Bloggs") } +func TestPreferredEmailDomainConfigured(t *testing.T) { + ctx := context.Background() + s := newTestServer(map[string]testResponse{ + "/user": {data: user{Login: "some-login", ID: 12345678, Name: "Joe Bloggs"}}, + "/user/emails": { + data: []userEmail{ + { + Email: "some@email.com", + Verified: true, + Primary: true, + }, + { + Email: "another@email.com", + Verified: true, + Primary: false, + }, + { + Email: "some@preferred-domain.com", + Verified: true, + Primary: false, + }, + { + Email: "another@preferred-domain.com", + Verified: true, + Primary: false, + }, + }, + }, + }) + defer s.Close() + + hostURL, err := url.Parse(s.URL) + expectNil(t, err) + + client := newClient() + c := githubConnector{apiURL: s.URL, hostName: hostURL.Host, httpClient: client, preferredEmailDomain: "preferred-domain.com"} + + u, err := c.user(ctx, client) + expectNil(t, err) + expectEquals(t, u.Email, "some@preferred-domain.com") +} + +func TestPreferredEmailDomainConfiguredWithGlob(t *testing.T) { + ctx := context.Background() + s := newTestServer(map[string]testResponse{ + "/user": {data: user{Login: "some-login", ID: 12345678, Name: "Joe Bloggs"}}, + "/user/emails": { + data: []userEmail{ + { + Email: "some@email.com", + Verified: true, + Primary: true, + }, + { + Email: "another@email.com", + Verified: true, + Primary: false, + }, + { + Email: "some@another.preferred-domain.com", + Verified: true, + Primary: false, + }, + { + Email: "some@sub-domain.preferred-domain.co", + Verified: true, + Primary: false, + }, + }, + }, + }) + defer s.Close() + + hostURL, err := url.Parse(s.URL) + expectNil(t, err) + + client := newClient() + c := githubConnector{apiURL: s.URL, hostName: hostURL.Host, httpClient: client, preferredEmailDomain: "*.preferred-domain.co"} + + u, err := c.user(ctx, client) + expectNil(t, err) + expectEquals(t, u.Email, "some@sub-domain.preferred-domain.co") +} + +func TestPreferredEmailDomainConfigured_UserHasNoPreferredDomainEmail(t *testing.T) { + ctx := context.Background() + s := newTestServer(map[string]testResponse{ + "/user": {data: user{Login: "some-login", ID: 12345678, Name: "Joe Bloggs"}}, + "/user/emails": { + data: []userEmail{ + { + Email: "some@email.com", + Verified: true, + Primary: true, + }, + { + Email: "another@email.com", + Verified: true, + Primary: false, + }, + }, + }, + }) + defer s.Close() + + hostURL, err := url.Parse(s.URL) + expectNil(t, err) + + client := newClient() + c := githubConnector{apiURL: s.URL, hostName: hostURL.Host, httpClient: client, preferredEmailDomain: "preferred-domain.com"} + + u, err := c.user(ctx, client) + expectNil(t, err) + expectEquals(t, u.Email, "some@email.com") +} + +func TestPreferredEmailDomainNotConfigured(t *testing.T) { + ctx := context.Background() + s := newTestServer(map[string]testResponse{ + "/user": {data: user{Login: "some-login", ID: 12345678, Name: "Joe Bloggs"}}, + "/user/emails": { + data: []userEmail{ + { + Email: "some@email.com", + Verified: true, + Primary: true, + }, + { + Email: "another@email.com", + Verified: true, + Primary: false, + }, + { + Email: "some@preferred-domain.com", + Verified: true, + Primary: false, + }, + }, + }, + }) + defer s.Close() + + hostURL, err := url.Parse(s.URL) + expectNil(t, err) + + client := newClient() + c := githubConnector{apiURL: s.URL, hostName: hostURL.Host, httpClient: client} + + u, err := c.user(ctx, client) + expectNil(t, err) + expectEquals(t, u.Email, "some@email.com") +} + +func TestPreferredEmailDomainConfigured_Error_BothPrimaryAndPreferredDomainEmailNotFound(t *testing.T) { + ctx := context.Background() + s := newTestServer(map[string]testResponse{ + "/user": {data: user{Login: "some-login", ID: 12345678, Name: "Joe Bloggs"}}, + "/user/emails": { + data: []userEmail{ + { + Email: "some@email.com", + Verified: true, + Primary: false, + }, + { + Email: "another@email.com", + Verified: true, + Primary: false, + }, + { + Email: "some@preferred-domain.com", + Verified: true, + Primary: false, + }, + }, + }, + }) + defer s.Close() + + hostURL, err := url.Parse(s.URL) + expectNil(t, err) + + client := newClient() + c := githubConnector{apiURL: s.URL, hostName: hostURL.Host, httpClient: client, preferredEmailDomain: "foo.bar"} + + _, err = c.user(ctx, client) + expectNotNil(t, err, "Email not found error") + expectEquals(t, err.Error(), "github: user has no verified, primary email or preferred-domain email") +} + +func Test_isPreferredEmailDomain(t *testing.T) { + client := newClient() + tests := []struct { + preferredEmailDomain string + email string + expected bool + }{ + { + preferredEmailDomain: "example.com", + email: "test@example.com", + expected: true, + }, + { + preferredEmailDomain: "example.com", + email: "test@another.com", + expected: false, + }, + { + preferredEmailDomain: "*.example.com", + email: "test@my.example.com", + expected: true, + }, + { + preferredEmailDomain: "*.example.com", + email: "test@my.another.com", + expected: false, + }, + { + preferredEmailDomain: "*.example.com", + email: "test@my.domain.example.com", + expected: false, + }, + { + preferredEmailDomain: "*.example.com", + email: "test@sub.domain.com", + expected: false, + }, + { + preferredEmailDomain: "*.*.example.com", + email: "test@sub.my.example.com", + expected: true, + }, + { + preferredEmailDomain: "*.*.example.com", + email: "test@a.my.google.com", + expected: false, + }, + } + for _, test := range tests { + t.Run(test.preferredEmailDomain, func(t *testing.T) { + c := githubConnector{apiURL: "apiURL", hostName: "github.com", httpClient: client, preferredEmailDomain: test.preferredEmailDomain} + _, domainPart, _ := strings.Cut(test.email, "@") + res := c.isPreferredEmailDomain(domainPart) + + expectEquals(t, res, test.expected) + }) + } +} + +func Test_Open_PreferredDomainConfig(t *testing.T) { + log := slog.New(slog.DiscardHandler) + tests := []struct { + preferredEmailDomain string + email string + expected error + }{ + { + preferredEmailDomain: "example.com", + expected: nil, + }, + { + preferredEmailDomain: "*.example.com", + expected: nil, + }, + { + preferredEmailDomain: "*.*.example.com", + expected: nil, + }, + { + preferredEmailDomain: "example.*", + expected: errors.New("invalid PreferredEmailDomain: glob pattern cannot end with \"*\""), + }, + } + for _, test := range tests { + t.Run(test.preferredEmailDomain, func(t *testing.T) { + c := Config{ + PreferredEmailDomain: test.preferredEmailDomain, + } + _, err := c.Open("id", log) + + expectEquals(t, err, test.expected) + }) + } +} + func newTestServer(responses map[string]testResponse) *httptest.Server { var s *httptest.Server s = httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -231,6 +518,12 @@ func expectNil(t *testing.T, a interface{}) { } } +func expectNotNil(t *testing.T, a interface{}, msg string) { + if a == nil { + t.Errorf("Expected %+v to not to be nil", msg) + } +} + func expectEquals(t *testing.T, a interface{}, b interface{}) { if !reflect.DeepEqual(a, b) { t.Errorf("Expected %+v to equal %+v", a, b) diff --git a/connector/gitlab/gitlab.go b/connector/gitlab/gitlab.go index f35ac35753..7aa4439842 100644 --- a/connector/gitlab/gitlab.go +++ b/connector/gitlab/gitlab.go @@ -1,4 +1,4 @@ -// Package gitlab provides authentication strategies using Gitlab. +// Package gitlab provides authentication strategies using GitLab. package gitlab import ( @@ -7,6 +7,7 @@ import ( "errors" "fmt" "io" + "log/slog" "net/http" "strconv" "time" @@ -15,7 +16,6 @@ import ( "github.com/dexidp/dex/connector" "github.com/dexidp/dex/pkg/groups" - "github.com/dexidp/dex/pkg/log" ) const ( @@ -28,12 +28,13 @@ const ( // Config holds configuration options for gitlab logins. type Config struct { - BaseURL string `json:"baseURL"` - ClientID string `json:"clientID"` - ClientSecret string `json:"clientSecret"` - RedirectURI string `json:"redirectURI"` - Groups []string `json:"groups"` - UseLoginAsID bool `json:"useLoginAsID"` + BaseURL string `json:"baseURL"` + ClientID string `json:"clientID"` + ClientSecret string `json:"clientSecret"` + RedirectURI string `json:"redirectURI"` + Groups []string `json:"groups"` + UseLoginAsID bool `json:"useLoginAsID"` + GetGroupsPermission bool `json:"getGroupsPermission"` } type gitlabUser struct { @@ -46,18 +47,19 @@ type gitlabUser struct { } // Open returns a strategy for logging in through GitLab. -func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) { +func (c *Config) Open(id string, logger *slog.Logger) (connector.Connector, error) { if c.BaseURL == "" { c.BaseURL = "https://gitlab.com" } return &gitlabConnector{ - baseURL: c.BaseURL, - redirectURI: c.RedirectURI, - clientID: c.ClientID, - clientSecret: c.ClientSecret, - logger: logger, - groups: c.Groups, - useLoginAsID: c.UseLoginAsID, + baseURL: c.BaseURL, + redirectURI: c.RedirectURI, + clientID: c.ClientID, + clientSecret: c.ClientSecret, + logger: logger.With(slog.Group("connector", "type", "gitlab", "id", id)), + groups: c.Groups, + useLoginAsID: c.UseLoginAsID, + getGroupsPermission: c.GetGroupsPermission, }, nil } @@ -78,10 +80,13 @@ type gitlabConnector struct { groups []string clientID string clientSecret string - logger log.Logger + logger *slog.Logger httpClient *http.Client // if set to true will use the user's handle rather than their numeric id as the ID useLoginAsID bool + + // if set to true permissions will be added to list of groups + getGroupsPermission bool } func (c *gitlabConnector) oauth2Config(scopes connector.Scopes) *oauth2.Config { @@ -256,7 +261,10 @@ func (c *gitlabConnector) user(ctx context.Context, client *http.Client) (gitlab } type userInfo struct { - Groups []string + Groups []string `json:"groups"` + OwnerPermission []string `json:"https://gitlab.org/claims/groups/owner"` + MaintainerPermission []string `json:"https://gitlab.org/claims/groups/maintainer"` + DeveloperPermission []string `json:"https://gitlab.org/claims/groups/developer"` } // userGroups queries the GitLab API for group membership. @@ -287,9 +295,62 @@ func (c *gitlabConnector) userGroups(ctx context.Context, client *http.Client) ( return nil, fmt.Errorf("failed to decode response: %v", err) } + if c.getGroupsPermission { + groups := c.setGroupsPermission(u) + return groups, nil + } + return u.Groups, nil } +func (c *gitlabConnector) setGroupsPermission(u userInfo) []string { + groups := u.Groups + +L1: + for _, g := range groups { + for _, op := range u.OwnerPermission { + if g == op { + groups = append(groups, fmt.Sprintf("%s:owner", g)) + continue L1 + } + if len(g) > len(op) { + if g[0:len(op)] == op && string(g[len(op)]) == "/" { + groups = append(groups, fmt.Sprintf("%s:owner", g)) + continue L1 + } + } + } + + for _, mp := range u.MaintainerPermission { + if g == mp { + groups = append(groups, fmt.Sprintf("%s:maintainer", g)) + continue L1 + } + if len(g) > len(mp) { + if g[0:len(mp)] == mp && string(g[len(mp)]) == "/" { + groups = append(groups, fmt.Sprintf("%s:maintainer", g)) + continue L1 + } + } + } + + for _, dp := range u.DeveloperPermission { + if g == dp { + groups = append(groups, fmt.Sprintf("%s:developer", g)) + continue L1 + } + if len(g) > len(dp) { + if g[0:len(dp)] == dp && string(g[len(dp)]) == "/" { + groups = append(groups, fmt.Sprintf("%s:developer", g)) + continue L1 + } + } + } + } + + return groups +} + func (c *gitlabConnector) getGroups(ctx context.Context, client *http.Client, groupScope bool, userLogin string) ([]string, error) { gitlabGroups, err := c.userGroups(ctx, client) if err != nil { diff --git a/connector/gitlab/gitlab_test.go b/connector/gitlab/gitlab_test.go index d828b8bd16..b67b30c045 100644 --- a/connector/gitlab/gitlab_test.go +++ b/connector/gitlab/gitlab_test.go @@ -249,6 +249,47 @@ func TestRefreshWithEmptyConnectorData(t *testing.T) { expectEquals(t, emptyIdentity, identity) } +func TestGroupsWithPermission(t *testing.T) { + s := newTestServer(map[string]interface{}{ + "/api/v4/user": gitlabUser{Email: "some@email.com", ID: 12345678, Name: "Joe Bloggs", Username: "joebloggs"}, + "/oauth/token": map[string]interface{}{ + "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9", + "expires_in": "30", + }, + "/oauth/userinfo": userInfo{ + Groups: []string{"ops", "dev", "ops-test", "ops/project", "dev/project1", "dev/project2"}, + OwnerPermission: []string{"ops"}, + DeveloperPermission: []string{"dev"}, + MaintainerPermission: []string{"dev/project1"}, + }, + }) + defer s.Close() + + hostURL, err := url.Parse(s.URL) + expectNil(t, err) + + req, err := http.NewRequest("GET", hostURL.String(), nil) + expectNil(t, err) + + c := gitlabConnector{baseURL: s.URL, httpClient: newClient(), getGroupsPermission: true} + identity, err := c.HandleCallback(connector.Scopes{Groups: true}, req) + expectNil(t, err) + + expectEquals(t, identity.Groups, []string{ + "ops", + "dev", + "ops-test", + "ops/project", + "dev/project1", + "dev/project2", + "ops:owner", + "dev:developer", + "ops/project:owner", + "dev/project1:maintainer", + "dev/project2:developer", + }) +} + func newTestServer(responses map[string]interface{}) *httptest.Server { return httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { response := responses[r.RequestURI] diff --git a/connector/google/google.go b/connector/google/google.go index 72cc6a18a5..e17ec5bd7f 100644 --- a/connector/google/google.go +++ b/connector/google/google.go @@ -5,23 +5,28 @@ import ( "context" "errors" "fmt" + "log/slog" "net/http" "os" + "strings" "time" + "cloud.google.com/go/compute/metadata" "github.com/coreos/go-oidc/v3/oidc" + "golang.org/x/exp/slices" "golang.org/x/oauth2" "golang.org/x/oauth2/google" admin "google.golang.org/api/admin/directory/v1" + "google.golang.org/api/impersonate" "google.golang.org/api/option" "github.com/dexidp/dex/connector" pkg_groups "github.com/dexidp/dex/pkg/groups" - "github.com/dexidp/dex/pkg/log" ) const ( - issuerURL = "https://accounts.google.com" + issuerURL = "https://accounts.google.com" + wildcardDomainToAdminEmail = "*" ) // Config holds configuration options for Google logins. @@ -45,17 +50,33 @@ type Config struct { // check groups with the admin directory api ServiceAccountFilePath string `json:"serviceAccountFilePath"` + // Deprecated: Use DomainToAdminEmail + AdminEmail string + // Required if ServiceAccountFilePath - // The email of a GSuite super user which the service account will impersonate + // The map workspace domain to email of a GSuite super user which the service account will impersonate // when listing groups - AdminEmail string + DomainToAdminEmail map[string]string // If this field is true, fetch direct group membership and transitive group membership FetchTransitiveGroupMembership bool `json:"fetchTransitiveGroupMembership"` + + // Optional value for the prompt parameter, defaults to consent when offline_access + // scope is requested + PromptType *string `json:"promptType"` } // Open returns a connector which can be used to login users through Google. -func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, err error) { +func (c *Config) Open(id string, logger *slog.Logger) (conn connector.Connector, err error) { + logger = logger.With(slog.Group("connector", "type", "google", "id", id)) + if c.AdminEmail != "" { + logger.Warn(`use "domainToAdminEmail.*" option instead of "adminEmail"`, "deprecated", true) + if c.DomainToAdminEmail == nil { + c.DomainToAdminEmail = make(map[string]string) + } + + c.DomainToAdminEmail[wildcardDomainToAdminEmail] = c.AdminEmail + } ctx, cancel := context.WithCancel(context.Background()) provider, err := oidc.NewProvider(ctx, issuerURL) @@ -71,10 +92,30 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e scopes = append(scopes, "profile", "email") } - srv, err := createDirectoryService(c.ServiceAccountFilePath, c.AdminEmail, logger) - if err != nil { + adminSrv := make(map[string]*admin.Service) + + // We know impersonation is required when using a service account credential + // TODO: or is it? + if len(c.DomainToAdminEmail) == 0 && c.ServiceAccountFilePath != "" { cancel() - return nil, fmt.Errorf("could not create directory service: %v", err) + return nil, fmt.Errorf("directory service requires the domainToAdminEmail option to be configured") + } + + if (len(c.DomainToAdminEmail) > 0) || slices.Contains(scopes, "groups") { + for domain, adminEmail := range c.DomainToAdminEmail { + srv, err := createDirectoryService(c.ServiceAccountFilePath, adminEmail, logger) + if err != nil { + cancel() + return nil, fmt.Errorf("could not create directory service: %v", err) + } + + adminSrv[domain] = srv + } + } + + promptType := "consent" + if c.PromptType != nil { + promptType = *c.PromptType } clientID := c.ClientID @@ -95,9 +136,10 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e hostedDomains: c.HostedDomains, groups: c.Groups, serviceAccountFilePath: c.ServiceAccountFilePath, - adminEmail: c.AdminEmail, + domainToAdminEmail: c.DomainToAdminEmail, fetchTransitiveGroupMembership: c.FetchTransitiveGroupMembership, - adminSrv: srv, + adminSrv: adminSrv, + promptType: promptType, }, nil } @@ -111,13 +153,14 @@ type googleConnector struct { oauth2Config *oauth2.Config verifier *oidc.IDTokenVerifier cancel context.CancelFunc - logger log.Logger + logger *slog.Logger hostedDomains []string groups []string serviceAccountFilePath string - adminEmail string + domainToAdminEmail map[string]string fetchTransitiveGroupMembership bool - adminSrv *admin.Service + adminSrv map[string]*admin.Service + promptType string } func (c *googleConnector) Close() error { @@ -140,8 +183,9 @@ func (c *googleConnector) LoginURL(s connector.Scopes, callbackURL, state string } if s.OfflineAccess { - opts = append(opts, oauth2.AccessTypeOffline, oauth2.SetAuthURLParam("prompt", "consent")) + opts = append(opts, oauth2.AccessTypeOffline, oauth2.SetAuthURLParam("prompt", c.promptType)) } + return c.oauth2Config.AuthCodeURL(state, opts...), nil } @@ -218,8 +262,9 @@ func (c *googleConnector) createIdentity(ctx context.Context, identity connector } var groups []string - if s.Groups && c.adminSrv != nil { - groups, err = c.getGroups(claims.Email, c.fetchTransitiveGroupMembership) + if s.Groups && len(c.adminSrv) > 0 { + checkedGroups := make(map[string]struct{}) + groups, err = c.getGroups(claims.Email, c.fetchTransitiveGroupMembership, checkedGroups) if err != nil { return identity, fmt.Errorf("google: could not retrieve groups: %v", err) } @@ -245,30 +290,43 @@ func (c *googleConnector) createIdentity(ctx context.Context, identity connector // getGroups creates a connection to the admin directory service and lists // all groups the user is a member of -func (c *googleConnector) getGroups(email string, fetchTransitiveGroupMembership bool) ([]string, error) { +func (c *googleConnector) getGroups(email string, fetchTransitiveGroupMembership bool, checkedGroups map[string]struct{}) ([]string, error) { var userGroups []string var err error groupsList := &admin.Groups{} + domain := c.extractDomainFromEmail(email) + adminSrv, err := c.findAdminService(domain) + if err != nil { + return nil, err + } + for { - groupsList, err = c.adminSrv.Groups.List(). + groupsList, err = adminSrv.Groups.List(). UserKey(email).PageToken(groupsList.NextPageToken).Do() if err != nil { return nil, fmt.Errorf("could not list groups: %v", err) } for _, group := range groupsList.Groups { + if _, exists := checkedGroups[group.Email]; exists { + continue + } + + checkedGroups[group.Email] = struct{}{} // TODO (joelspeed): Make desired group key configurable userGroups = append(userGroups, group.Email) - // getGroups takes a user's email/alias as well as a group's email/alias - if fetchTransitiveGroupMembership { - transitiveGroups, err := c.getGroups(group.Email, fetchTransitiveGroupMembership) - if err != nil { - return nil, fmt.Errorf("could not list transitive groups: %v", err) - } + if !fetchTransitiveGroupMembership { + continue + } - userGroups = append(userGroups, transitiveGroups...) + // getGroups takes a user's email/alias as well as a group's email/alias + transitiveGroups, err := c.getGroups(group.Email, fetchTransitiveGroupMembership, checkedGroups) + if err != nil { + return nil, fmt.Errorf("could not list transitive groups: %v", err) } + + userGroups = append(userGroups, transitiveGroups...) } if groupsList.NextPageToken == "" { @@ -276,51 +334,124 @@ func (c *googleConnector) getGroups(email string, fetchTransitiveGroupMembership } } - return uniqueGroups(userGroups), nil + return userGroups, nil +} + +func (c *googleConnector) findAdminService(domain string) (*admin.Service, error) { + adminSrv, ok := c.adminSrv[domain] + if !ok { + adminSrv, ok = c.adminSrv[wildcardDomainToAdminEmail] + c.logger.Debug("using wildcard admin email to fetch groups", "admin_email", c.domainToAdminEmail[wildcardDomainToAdminEmail]) + } + + if !ok { + return nil, fmt.Errorf("unable to find super admin email, domainToAdminEmail for domain: %s not set, %s is also empty", domain, wildcardDomainToAdminEmail) + } + + return adminSrv, nil +} + +// extracts the domain name from an email input. If the email is valid, it returns the domain name after the "@" symbol. +// However, in the case of a broken or invalid email, it returns a wildcard symbol. +func (c *googleConnector) extractDomainFromEmail(email string) string { + at := strings.LastIndex(email, "@") + if at >= 0 { + _, domain := email[:at], email[at+1:] + + return domain + } + + return wildcardDomainToAdminEmail +} + +// getCredentialsFromFilePath reads and returns the service account credentials from the file at the provided path. +// If an error occurs during the read, it is returned. +func getCredentialsFromFilePath(serviceAccountFilePath string) ([]byte, error) { + jsonCredentials, err := os.ReadFile(serviceAccountFilePath) + if err != nil { + return nil, fmt.Errorf("error reading credentials from file: %v", err) + } + return jsonCredentials, nil +} + +// getCredentialsFromDefault retrieves the application's default credentials. +// If the default credential is empty, it attempts to create a new service with metadata credentials. +// If successful, it returns the service and nil error. +// If unsuccessful, it returns the error and a nil service. +func getCredentialsFromDefault(ctx context.Context, email string, logger *slog.Logger) ([]byte, *admin.Service, error) { + credential, err := google.FindDefaultCredentials(ctx) + if err != nil { + return nil, nil, fmt.Errorf("failed to fetch application default credentials: %w", err) + } + + if credential.JSON == nil { + logger.Info("JSON is empty, using flow for GCE") + service, err := createServiceWithMetadataServer(ctx, email, logger) + if err != nil { + return nil, nil, err + } + return nil, service, nil + } + + return credential.JSON, nil, nil +} + +// createServiceWithMetadataServer creates a new service using metadata server. +// If an error occurs during the process, it is returned along with a nil service. +func createServiceWithMetadataServer(ctx context.Context, adminEmail string, logger *slog.Logger) (*admin.Service, error) { + serviceAccountEmail, err := metadata.EmailWithContext(ctx, "default") + logger.Info("discovered serviceAccountEmail", "email", serviceAccountEmail) + + if err != nil { + return nil, fmt.Errorf("unable to get service account email from metadata server: %v", err) + } + + config := impersonate.CredentialsConfig{ + TargetPrincipal: serviceAccountEmail, + Scopes: []string{admin.AdminDirectoryGroupReadonlyScope}, + Lifetime: 0, + Subject: adminEmail, + } + + tokenSource, err := impersonate.CredentialsTokenSource(ctx, config) + if err != nil { + return nil, fmt.Errorf("unable to impersonate with %s, error: %v", adminEmail, err) + } + + return admin.NewService(ctx, option.WithHTTPClient(oauth2.NewClient(ctx, tokenSource))) } // createDirectoryService sets up super user impersonation and creates an admin client for calling // the google admin api. If no serviceAccountFilePath is defined, the application default credential // is used. -func createDirectoryService(serviceAccountFilePath, email string, logger log.Logger) (*admin.Service, error) { - if email == "" { - return nil, fmt.Errorf("directory service requires adminEmail") - } - +func createDirectoryService(serviceAccountFilePath, email string, logger *slog.Logger) (service *admin.Service, err error) { var jsonCredentials []byte - var err error ctx := context.Background() if serviceAccountFilePath == "" { logger.Warn("the application default credential is used since the service account file path is not used") - credential, err := google.FindDefaultCredentials(ctx) + jsonCredentials, service, err = getCredentialsFromDefault(ctx, email, logger) if err != nil { - return nil, fmt.Errorf("failed to fetch application default credentials: %w", err) + return + } + if service != nil { + return } - jsonCredentials = credential.JSON } else { - jsonCredentials, err = os.ReadFile(serviceAccountFilePath) + jsonCredentials, err = getCredentialsFromFilePath(serviceAccountFilePath) if err != nil { - return nil, fmt.Errorf("error reading credentials from file: %v", err) + return } } config, err := google.JWTConfigFromJSON(jsonCredentials, admin.AdminDirectoryGroupReadonlyScope) if err != nil { - return nil, fmt.Errorf("unable to parse credentials to config: %v", err) + return nil, fmt.Errorf("unable to parse client secret file to config: %v", err) } - config.Subject = email - return admin.NewService(ctx, option.WithHTTPClient(config.Client(ctx))) -} -// uniqueGroups returns the unique groups of a slice -func uniqueGroups(groups []string) []string { - keys := make(map[string]struct{}) - unique := []string{} - for _, group := range groups { - if _, exists := keys[group]; !exists { - keys[group] = struct{}{} - unique = append(unique, group) - } + // Only attempt impersonation when there is a user configured + if email != "" { + config.Subject = email } - return unique + + return admin.NewService(ctx, option.WithHTTPClient(config.Client(ctx))) } diff --git a/connector/google/google_test.go b/connector/google/google_test.go index 5cecbec994..8cc7973969 100644 --- a/connector/google/google_test.go +++ b/connector/google/google_test.go @@ -1,31 +1,57 @@ package google import ( + "context" "encoding/json" "fmt" + "log/slog" "net/http" "net/http/httptest" + "net/url" "os" + "strings" "testing" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" + admin "google.golang.org/api/admin/directory/v1" + "google.golang.org/api/option" + + "github.com/dexidp/dex/connector" +) + +var ( + // groups_0 + // ┌───────┤ + // groups_2 groups_1 + // │ ├────────┐ + // └── user_1 user_2 + testGroups = map[string][]*admin.Group{ + "user_1@dexidp.com": {{Email: "groups_2@dexidp.com"}, {Email: "groups_1@dexidp.com"}}, + "user_2@dexidp.com": {{Email: "groups_1@dexidp.com"}}, + "groups_1@dexidp.com": {{Email: "groups_0@dexidp.com"}}, + "groups_2@dexidp.com": {{Email: "groups_0@dexidp.com"}}, + "groups_0@dexidp.com": {}, + } + callCounter = make(map[string]int) ) -func testSetup(t *testing.T) *httptest.Server { +func testSetup() *httptest.Server { mux := http.NewServeMux() - // TODO: mock calls - // mux.HandleFunc("/admin/directory/v1/groups", func(w http.ResponseWriter, r *http.Request) { - // w.Header().Add("Content-Type", "application/json") - // json.NewEncoder(w).Encode(&admin.Groups{ - // Groups: []*admin.Group{}, - // }) - // }) + + mux.HandleFunc("/admin/directory/v1/groups/", func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Content-Type", "application/json") + userKey := r.URL.Query().Get("userKey") + if groups, ok := testGroups[userKey]; ok { + json.NewEncoder(w).Encode(admin.Groups{Groups: groups}) + callCounter[userKey]++ + } + }) + return httptest.NewServer(mux) } -func newConnector(config *Config, serverURL string) (*googleConnector, error) { - log := logrus.New() +func newConnector(config *Config) (*googleConnector, error) { + log := slog.New(slog.DiscardHandler) conn, err := config.Open("id", log) if err != nil { return nil, err @@ -56,7 +82,7 @@ func tempServiceAccountKey() (string, error) { } func TestOpen(t *testing.T) { - ts := testSetup(t) + ts := testSetup() defer ts.Close() type testCase struct { @@ -64,7 +90,7 @@ func TestOpen(t *testing.T) { expectedErr string // string to set in GOOGLE_APPLICATION_CREDENTIALS. As local development environments can - // already contain ADC, test cases will be built uppon this setting this env variable + // already contain ADC, test cases will be built upon this setting this env variable adc string } @@ -74,12 +100,13 @@ func TestOpen(t *testing.T) { for name, reference := range map[string]testCase{ "missing_admin_email": { config: &Config{ - ClientID: "testClient", - ClientSecret: "testSecret", - RedirectURI: ts.URL + "/callback", - Scopes: []string{"openid", "groups"}, + ClientID: "testClient", + ClientSecret: "testSecret", + RedirectURI: ts.URL + "/callback", + Scopes: []string{"openid", "groups"}, + ServiceAccountFilePath: serviceAccountFilePath, }, - expectedErr: "requires adminEmail", + expectedErr: "requires the domainToAdminEmail", }, "service_account_key_not_found": { config: &Config{ @@ -87,7 +114,7 @@ func TestOpen(t *testing.T) { ClientSecret: "testSecret", RedirectURI: ts.URL + "/callback", Scopes: []string{"openid", "groups"}, - AdminEmail: "foo@bar.com", + DomainToAdminEmail: map[string]string{"*": "foo@bar.com"}, ServiceAccountFilePath: "not_found.json", }, expectedErr: "error reading credentials", @@ -98,18 +125,18 @@ func TestOpen(t *testing.T) { ClientSecret: "testSecret", RedirectURI: ts.URL + "/callback", Scopes: []string{"openid", "groups"}, - AdminEmail: "foo@bar.com", + DomainToAdminEmail: map[string]string{"bar.com": "foo@bar.com"}, ServiceAccountFilePath: serviceAccountFilePath, }, expectedErr: "", }, "adc": { config: &Config{ - ClientID: "testClient", - ClientSecret: "testSecret", - RedirectURI: ts.URL + "/callback", - Scopes: []string{"openid", "groups"}, - AdminEmail: "foo@bar.com", + ClientID: "testClient", + ClientSecret: "testSecret", + RedirectURI: ts.URL + "/callback", + Scopes: []string{"openid", "groups"}, + DomainToAdminEmail: map[string]string{"*": "foo@bar.com"}, }, adc: serviceAccountFilePath, expectedErr: "", @@ -120,7 +147,7 @@ func TestOpen(t *testing.T) { ClientSecret: "testSecret", RedirectURI: ts.URL + "/callback", Scopes: []string{"openid", "groups"}, - AdminEmail: "foo@bar.com", + DomainToAdminEmail: map[string]string{"*": "foo@bar.com"}, ServiceAccountFilePath: serviceAccountFilePath, }, adc: "/dev/null", @@ -132,7 +159,7 @@ func TestOpen(t *testing.T) { assert := assert.New(t) os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", reference.adc) - conn, err := newConnector(reference.config, ts.URL) + conn, err := newConnector(reference.config) if reference.expectedErr == "" { assert.Nil(err) @@ -143,3 +170,282 @@ func TestOpen(t *testing.T) { }) } } + +func TestGetGroups(t *testing.T) { + ts := testSetup() + defer ts.Close() + + serviceAccountFilePath, err := tempServiceAccountKey() + assert.Nil(t, err) + + os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", serviceAccountFilePath) + conn, err := newConnector(&Config{ + ClientID: "testClient", + ClientSecret: "testSecret", + RedirectURI: ts.URL + "/callback", + Scopes: []string{"openid", "groups"}, + DomainToAdminEmail: map[string]string{"*": "admin@dexidp.com"}, + }) + assert.Nil(t, err) + + conn.adminSrv[wildcardDomainToAdminEmail], err = admin.NewService(context.Background(), option.WithoutAuthentication(), option.WithEndpoint(ts.URL)) + assert.Nil(t, err) + type testCase struct { + userKey string + fetchTransitiveGroupMembership bool + shouldErr bool + expectedGroups []string + } + + for name, testCase := range map[string]testCase{ + "user1_non_transitive_lookup": { + userKey: "user_1@dexidp.com", + fetchTransitiveGroupMembership: false, + shouldErr: false, + expectedGroups: []string{"groups_1@dexidp.com", "groups_2@dexidp.com"}, + }, + "user1_transitive_lookup": { + userKey: "user_1@dexidp.com", + fetchTransitiveGroupMembership: true, + shouldErr: false, + expectedGroups: []string{"groups_0@dexidp.com", "groups_1@dexidp.com", "groups_2@dexidp.com"}, + }, + "user2_non_transitive_lookup": { + userKey: "user_2@dexidp.com", + fetchTransitiveGroupMembership: false, + shouldErr: false, + expectedGroups: []string{"groups_1@dexidp.com"}, + }, + "user2_transitive_lookup": { + userKey: "user_2@dexidp.com", + fetchTransitiveGroupMembership: true, + shouldErr: false, + expectedGroups: []string{"groups_0@dexidp.com", "groups_1@dexidp.com"}, + }, + } { + testCase := testCase + callCounter = map[string]int{} + t.Run(name, func(t *testing.T) { + assert := assert.New(t) + lookup := make(map[string]struct{}) + + groups, err := conn.getGroups(testCase.userKey, testCase.fetchTransitiveGroupMembership, lookup) + if testCase.shouldErr { + assert.NotNil(err) + } else { + assert.Nil(err) + } + assert.ElementsMatch(testCase.expectedGroups, groups) + t.Logf("[%s] Amount of API calls per userKey: %+v\n", t.Name(), callCounter) + }) + } +} + +func TestDomainToAdminEmailConfig(t *testing.T) { + ts := testSetup() + defer ts.Close() + + serviceAccountFilePath, err := tempServiceAccountKey() + assert.Nil(t, err) + + os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", serviceAccountFilePath) + conn, err := newConnector(&Config{ + ClientID: "testClient", + ClientSecret: "testSecret", + RedirectURI: ts.URL + "/callback", + Scopes: []string{"openid", "groups"}, + DomainToAdminEmail: map[string]string{"dexidp.com": "admin@dexidp.com"}, + }) + assert.Nil(t, err) + + conn.adminSrv["dexidp.com"], err = admin.NewService(context.Background(), option.WithoutAuthentication(), option.WithEndpoint(ts.URL)) + assert.Nil(t, err) + type testCase struct { + userKey string + expectedErr string + } + + for name, testCase := range map[string]testCase{ + "correct_user_request": { + userKey: "user_1@dexidp.com", + expectedErr: "", + }, + "wrong_user_request": { + userKey: "user_1@foo.bar", + expectedErr: "unable to find super admin email", + }, + "wrong_connector_response": { + userKey: "user_1_foo.bar", + expectedErr: "unable to find super admin email", + }, + } { + testCase := testCase + callCounter = map[string]int{} + t.Run(name, func(t *testing.T) { + assert := assert.New(t) + lookup := make(map[string]struct{}) + + _, err := conn.getGroups(testCase.userKey, true, lookup) + if testCase.expectedErr != "" { + assert.ErrorContains(err, testCase.expectedErr) + } else { + assert.Nil(err) + } + t.Logf("[%s] Amount of API calls per userKey: %+v\n", t.Name(), callCounter) + }) + } +} + +var gceMetadataFlags = map[string]bool{ + "failOnEmailRequest": false, +} + +func mockGCEMetadataServer() *httptest.Server { + mux := http.NewServeMux() + + mux.HandleFunc("/computeMetadata/v1/instance/service-accounts/default/email", func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Content-Type", "application/json") + if gceMetadataFlags["failOnEmailRequest"] { + w.WriteHeader(http.StatusBadRequest) + } + json.NewEncoder(w).Encode("my-service-account@example-project.iam.gserviceaccount.com") + }) + mux.HandleFunc("/computeMetadata/v1/instance/service-accounts/default/token", func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Content-Type", "application/json") + json.NewEncoder(w).Encode(struct { + AccessToken string `json:"access_token"` + ExpiresInSec int `json:"expires_in"` + TokenType string `json:"token_type"` + }{ + AccessToken: "my-example.token", + ExpiresInSec: 3600, + TokenType: "Bearer", + }) + }) + + return httptest.NewServer(mux) +} + +func TestGCEWorkloadIdentity(t *testing.T) { + ts := testSetup() + defer ts.Close() + + metadataServer := mockGCEMetadataServer() + defer metadataServer.Close() + metadataServerHost := strings.Replace(metadataServer.URL, "http://", "", 1) + + os.Setenv("GCE_METADATA_HOST", metadataServerHost) + os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", "") + os.Setenv("HOME", "/tmp") + + gceMetadataFlags["failOnEmailRequest"] = true + _, err := newConnector(&Config{ + ClientID: "testClient", + ClientSecret: "testSecret", + RedirectURI: ts.URL + "/callback", + Scopes: []string{"openid", "groups"}, + DomainToAdminEmail: map[string]string{"dexidp.com": "admin@dexidp.com"}, + }) + assert.Error(t, err) + + gceMetadataFlags["failOnEmailRequest"] = false + conn, err := newConnector(&Config{ + ClientID: "testClient", + ClientSecret: "testSecret", + RedirectURI: ts.URL + "/callback", + Scopes: []string{"openid", "groups"}, + DomainToAdminEmail: map[string]string{"dexidp.com": "admin@dexidp.com"}, + }) + assert.Nil(t, err) + + conn.adminSrv["dexidp.com"], err = admin.NewService(context.Background(), option.WithoutAuthentication(), option.WithEndpoint(ts.URL)) + assert.Nil(t, err) + type testCase struct { + userKey string + expectedErr string + } + + for name, testCase := range map[string]testCase{ + "correct_user_request": { + userKey: "user_1@dexidp.com", + expectedErr: "", + }, + "wrong_user_request": { + userKey: "user_1@foo.bar", + expectedErr: "unable to find super admin email", + }, + "wrong_connector_response": { + userKey: "user_1_foo.bar", + expectedErr: "unable to find super admin email", + }, + } { + t.Run(name, func(t *testing.T) { + assert := assert.New(t) + lookup := make(map[string]struct{}) + + _, err := conn.getGroups(testCase.userKey, true, lookup) + if testCase.expectedErr != "" { + assert.ErrorContains(err, testCase.expectedErr) + } else { + assert.Nil(err) + } + }) + } +} + +func TestPromptTypeConfig(t *testing.T) { + promptTypeLogin := "login" + cases := []struct { + name string + promptType *string + expectedPromptTypeValue string + }{ + { + name: "prompt type is nil", + promptType: nil, + expectedPromptTypeValue: "consent", + }, + { + name: "prompt type is empty", + promptType: new(string), + expectedPromptTypeValue: "", + }, + { + name: "prompt type is set", + promptType: &promptTypeLogin, + expectedPromptTypeValue: "login", + }, + } + + ts := testSetup() + defer ts.Close() + + serviceAccountFilePath, err := tempServiceAccountKey() + assert.Nil(t, err) + + os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", serviceAccountFilePath) + + for _, test := range cases { + t.Run(test.name, func(t *testing.T) { + conn, err := newConnector(&Config{ + ClientID: "testClient", + ClientSecret: "testSecret", + RedirectURI: ts.URL + "/callback", + Scopes: []string{"openid", "groups", "offline_access"}, + DomainToAdminEmail: map[string]string{"dexidp.com": "admin@dexidp.com"}, + PromptType: test.promptType, + }) + + assert.Nil(t, err) + assert.Equal(t, test.expectedPromptTypeValue, conn.promptType) + + loginURL, err := conn.LoginURL(connector.Scopes{OfflineAccess: true}, ts.URL+"/callback", "state") + assert.Nil(t, err) + + urlp, err := url.Parse(loginURL) + assert.Nil(t, err) + + assert.Equal(t, test.expectedPromptTypeValue, urlp.Query().Get("prompt")) + }) + } +} diff --git a/connector/keystone/keystone.go b/connector/keystone/keystone.go index db97b5a71f..cdfdb55894 100644 --- a/connector/keystone/keystone.go +++ b/connector/keystone/keystone.go @@ -7,18 +7,21 @@ import ( "encoding/json" "fmt" "io" + "log/slog" "net/http" + "github.com/google/uuid" + "github.com/dexidp/dex/connector" - "github.com/dexidp/dex/pkg/log" ) type conn struct { - Domain string + Domain domainKeystone Host string AdminUsername string AdminPassword string - Logger log.Logger + client *http.Client + Logger *slog.Logger } type userKeystone struct { @@ -28,13 +31,14 @@ type userKeystone struct { } type domainKeystone struct { - ID string `json:"id"` - Name string `json:"name"` + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` } // Config holds the configuration parameters for Keystone connector. // Keystone should expose API v3 // An example config: +// // connectors: // type: keystone // id: keystone @@ -69,13 +73,9 @@ type password struct { } type user struct { - Name string `json:"name"` - Domain domain `json:"domain"` - Password string `json:"password"` -} - -type domain struct { - ID string `json:"id"` + Name string `json:"name"` + Domain domainKeystone `json:"domain"` + Password string `json:"password"` } type token struct { @@ -109,13 +109,28 @@ var ( ) // Open returns an authentication strategy using Keystone. -func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) { +func (c *Config) Open(id string, logger *slog.Logger) (connector.Connector, error) { + _, err := uuid.Parse(c.Domain) + var domain domainKeystone + // check if the supplied domain is a UUID or the special "default" value + // which is treated as an ID and not a name + if err == nil || c.Domain == "default" { + domain = domainKeystone{ + ID: c.Domain, + } + } else { + domain = domainKeystone{ + Name: c.Domain, + } + } + return &conn{ - c.Domain, - c.Host, - c.AdminUsername, - c.AdminPassword, - logger, + Domain: domain, + Host: c.Host, + AdminUsername: c.AdminUsername, + AdminPassword: c.AdminPassword, + Logger: logger.With(slog.Group("connector", "type", "keystone", "id", id)), + client: http.DefaultClient, }, nil } @@ -192,7 +207,6 @@ func (p *conn) Refresh( } func (p *conn) getTokenResponse(ctx context.Context, username, pass string) (response *http.Response, err error) { - client := &http.Client{} jsonData := loginRequestData{ auth: auth{ Identity: identity{ @@ -200,7 +214,7 @@ func (p *conn) getTokenResponse(ctx context.Context, username, pass string) (res Password: password{ User: user{ Name: username, - Domain: domain{ID: p.Domain}, + Domain: p.Domain, Password: pass, }, }, @@ -221,7 +235,7 @@ func (p *conn) getTokenResponse(ctx context.Context, username, pass string) (res req.Header.Set("Content-Type", "application/json") req = req.WithContext(ctx) - return client.Do(req) + return p.client.Do(req) } func (p *conn) getAdminToken(ctx context.Context) (string, error) { @@ -243,7 +257,6 @@ func (p *conn) checkIfUserExists(ctx context.Context, userID string, token strin func (p *conn) getUser(ctx context.Context, userID string, token string) (*userResponse, error) { // https://developer.openstack.org/api-ref/identity/v3/#show-user-details userURL := p.Host + "/v3/users/" + userID - client := &http.Client{} req, err := http.NewRequest("GET", userURL, nil) if err != nil { return nil, err @@ -251,7 +264,7 @@ func (p *conn) getUser(ctx context.Context, userID string, token string) (*userR req.Header.Set("X-Auth-Token", token) req = req.WithContext(ctx) - resp, err := client.Do(req) + resp, err := p.client.Do(req) if err != nil { return nil, err } @@ -276,7 +289,6 @@ func (p *conn) getUser(ctx context.Context, userID string, token string) (*userR } func (p *conn) getUserGroups(ctx context.Context, userID string, token string) ([]string, error) { - client := &http.Client{} // https://developer.openstack.org/api-ref/identity/v3/#list-groups-to-which-a-user-belongs groupsURL := p.Host + "/v3/users/" + userID + "/groups" req, err := http.NewRequest("GET", groupsURL, nil) @@ -285,9 +297,9 @@ func (p *conn) getUserGroups(ctx context.Context, userID string, token string) ( } req.Header.Set("X-Auth-Token", token) req = req.WithContext(ctx) - resp, err := client.Do(req) + resp, err := p.client.Do(req) if err != nil { - p.Logger.Errorf("keystone: error while fetching user %q groups\n", userID) + p.Logger.Error("error while fetching user groups", "user_id", userID, "err", err) return nil, err } diff --git a/connector/keystone/keystone_test.go b/connector/keystone/keystone_test.go index fc6c01e229..9b0590df12 100644 --- a/connector/keystone/keystone_test.go +++ b/connector/keystone/keystone_test.go @@ -17,11 +17,13 @@ import ( const ( invalidPass = "WRONG_PASS" - testUser = "test_user" - testPass = "test_pass" - testEmail = "test@example.com" - testGroup = "test_group" - testDomain = "default" + testUser = "test_user" + testPass = "test_pass" + testEmail = "test@example.com" + testGroup = "test_group" + testDomainAltName = "altdomain" + testDomainID = "default" + testDomainName = "Default" ) var ( @@ -32,8 +34,26 @@ var ( authTokenURL = "" usersURL = "" groupsURL = "" + domainsURL = "" ) +type userReq struct { + Name string `json:"name"` + Email string `json:"email"` + Enabled bool `json:"enabled"` + Password string `json:"password"` + Roles []string `json:"roles"` + DomainID string `json:"domain_id,omitempty"` +} + +type domainResponse struct { + Domain domainKeystone `json:"domain"` +} + +type domainsResponse struct { + Domains []domainKeystone `json:"domains"` +} + type groupResponse struct { Group struct { ID string `json:"id"` @@ -42,8 +62,6 @@ type groupResponse struct { func getAdminToken(t *testing.T, adminName, adminPass string) (token, id string) { t.Helper() - client := &http.Client{} - jsonData := loginRequestData{ auth: auth{ Identity: identity{ @@ -51,7 +69,7 @@ func getAdminToken(t *testing.T, adminName, adminPass string) (token, id string) Password: password{ User: user{ Name: adminName, - Domain: domain{ID: testDomain}, + Domain: domainKeystone{ID: testDomainID}, Password: adminPass, }, }, @@ -70,7 +88,7 @@ func getAdminToken(t *testing.T, adminName, adminPass string) (token, id string) } req.Header.Set("Content-Type", "application/json") - resp, err := client.Do(req) + resp, err := http.DefaultClient.Do(req) if err != nil { t.Fatal(err) } @@ -91,17 +109,91 @@ func getAdminToken(t *testing.T, adminName, adminPass string) (token, id string) return token, tokenResp.Token.User.ID } -func createUser(t *testing.T, token, userName, userEmail, userPass string) string { +func getOrCreateDomain(t *testing.T, token, domainName string) string { + t.Helper() + + domainSearchURL := domainsURL + "?name=" + domainName + reqGet, err := http.NewRequest("GET", domainSearchURL, nil) + if err != nil { + t.Fatal(err) + } + + reqGet.Header.Set("X-Auth-Token", token) + reqGet.Header.Add("Content-Type", "application/json") + respGet, err := http.DefaultClient.Do(reqGet) + if err != nil { + t.Fatal(err) + } + + dataGet, err := io.ReadAll(respGet.Body) + if err != nil { + t.Fatal(err) + } + defer respGet.Body.Close() + + domainsResp := new(domainsResponse) + err = json.Unmarshal(dataGet, &domainsResp) + if err != nil { + t.Fatal(err) + } + + if len(domainsResp.Domains) >= 1 { + return domainsResp.Domains[0].ID + } + + createDomainData := map[string]interface{}{ + "domain": map[string]interface{}{ + "name": domainName, + "enabled": true, + }, + } + + body, err := json.Marshal(createDomainData) + if err != nil { + t.Fatal(err) + } + + req, err := http.NewRequest("POST", domainsURL, bytes.NewBuffer(body)) + if err != nil { + t.Fatal(err) + } + req.Header.Set("X-Auth-Token", token) + req.Header.Add("Content-Type", "application/json") + resp, err := http.DefaultClient.Do(req) + if err != nil { + t.Fatal(err) + } + + if resp.StatusCode != 201 { + t.Fatalf("failed to create domain %s", domainName) + } + + data, err := io.ReadAll(resp.Body) + if err != nil { + t.Fatal(err) + } + defer resp.Body.Close() + + domainResp := new(domainResponse) + err = json.Unmarshal(data, &domainResp) + if err != nil { + t.Fatal(err) + } + + return domainResp.Domain.ID +} + +func createUser(t *testing.T, token, domainID, userName, userEmail, userPass string) string { t.Helper() - client := &http.Client{} createUserData := map[string]interface{}{ - "user": map[string]interface{}{ - "name": userName, - "email": userEmail, - "enabled": true, - "password": userPass, - "roles": []string{"admin"}, + "user": userReq{ + DomainID: domainID, + Name: userName, + Email: userEmail, + Enabled: true, + Password: userPass, + Roles: []string{"admin"}, }, } @@ -116,7 +208,7 @@ func createUser(t *testing.T, token, userName, userEmail, userPass string) strin } req.Header.Set("X-Auth-Token", token) req.Header.Add("Content-Type", "application/json") - resp, err := client.Do(req) + resp, err := http.DefaultClient.Do(req) if err != nil { t.Fatal(err) } @@ -139,7 +231,6 @@ func createUser(t *testing.T, token, userName, userEmail, userPass string) strin // delete group or user func deleteResource(t *testing.T, token, id, uri string) { t.Helper() - client := &http.Client{} deleteURI := uri + id req, err := http.NewRequest("DELETE", deleteURI, nil) @@ -148,7 +239,7 @@ func deleteResource(t *testing.T, token, id, uri string) { } req.Header.Set("X-Auth-Token", token) - resp, err := client.Do(req) + resp, err := http.DefaultClient.Do(req) if err != nil { t.Fatalf("error: %v", err) } @@ -157,7 +248,6 @@ func deleteResource(t *testing.T, token, id, uri string) { func createGroup(t *testing.T, token, description, name string) string { t.Helper() - client := &http.Client{} createGroupData := map[string]interface{}{ "group": map[string]interface{}{ @@ -177,7 +267,7 @@ func createGroup(t *testing.T, token, description, name string) string { } req.Header.Set("X-Auth-Token", token) req.Header.Add("Content-Type", "application/json") - resp, err := client.Do(req) + resp, err := http.DefaultClient.Do(req) if err != nil { t.Fatal(err) } @@ -200,14 +290,13 @@ func createGroup(t *testing.T, token, description, name string) string { func addUserToGroup(t *testing.T, token, groupID, userID string) error { t.Helper() uri := groupsURL + groupID + "/users/" + userID - client := &http.Client{} req, err := http.NewRequest("PUT", uri, nil) if err != nil { return err } req.Header.Set("X-Auth-Token", token) - resp, err := client.Do(req) + resp, err := http.DefaultClient.Do(req) if err != nil { t.Fatalf("error: %v", err) } @@ -219,7 +308,8 @@ func addUserToGroup(t *testing.T, token, groupID, userID string) error { func TestIncorrectCredentialsLogin(t *testing.T) { setupVariables(t) c := conn{ - Host: keystoneURL, Domain: testDomain, + client: http.DefaultClient, + Host: keystoneURL, Domain: domainKeystone{ID: testDomainID}, AdminUsername: adminUser, AdminPassword: adminPass, } s := connector.Scopes{OfflineAccess: true, Groups: true} @@ -243,10 +333,11 @@ func TestValidUserLogin(t *testing.T) { token, _ := getAdminToken(t, adminUser, adminPass) type tUser struct { - username string - domain string - email string - password string + createDomain bool + domain domainKeystone + username string + email string + password string } type expect struct { @@ -263,10 +354,11 @@ func TestValidUserLogin(t *testing.T) { { name: "test with email address", input: tUser{ - username: testUser, - domain: testDomain, - email: testEmail, - password: testPass, + createDomain: false, + domain: domainKeystone{ID: testDomainID}, + username: testUser, + email: testEmail, + password: testPass, }, expected: expect{ username: testUser, @@ -277,10 +369,11 @@ func TestValidUserLogin(t *testing.T) { { name: "test without email address", input: tUser{ - username: testUser, - domain: testDomain, - email: "", - password: testPass, + createDomain: false, + domain: domainKeystone{ID: testDomainID}, + username: testUser, + email: "", + password: testPass, }, expected: expect{ username: testUser, @@ -288,21 +381,77 @@ func TestValidUserLogin(t *testing.T) { verifiedEmail: false, }, }, + { + name: "test with default domain Name", + input: tUser{ + createDomain: false, + domain: domainKeystone{Name: testDomainName}, + username: testUser, + email: testEmail, + password: testPass, + }, + expected: expect{ + username: testUser, + email: testEmail, + verifiedEmail: true, + }, + }, + { + name: "test with custom domain Name", + input: tUser{ + createDomain: true, + domain: domainKeystone{Name: testDomainAltName}, + username: testUser, + email: testEmail, + password: testPass, + }, + expected: expect{ + username: testUser, + email: testEmail, + verifiedEmail: true, + }, + }, + { + name: "test with custom domain ID", + input: tUser{ + createDomain: true, + domain: domainKeystone{}, + username: testUser, + email: testEmail, + password: testPass, + }, + expected: expect{ + username: testUser, + email: testEmail, + verifiedEmail: true, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - userID := createUser(t, token, tt.input.username, tt.input.email, tt.input.password) + domainID := "" + if tt.input.createDomain == true { + domainID = getOrCreateDomain(t, token, testDomainAltName) + t.Logf("getOrCreateDomain ID: %s\n", domainID) + + // if there was nothing set then use the dynamically generated domain ID + if tt.input.domain.ID == "" && tt.input.domain.Name == "" { + tt.input.domain.ID = domainID + } + } + userID := createUser(t, token, domainID, tt.input.username, tt.input.email, tt.input.password) defer deleteResource(t, token, userID, usersURL) c := conn{ - Host: keystoneURL, Domain: tt.input.domain, + client: http.DefaultClient, + Host: keystoneURL, Domain: tt.input.domain, AdminUsername: adminUser, AdminPassword: adminPass, } s := connector.Scopes{OfflineAccess: true, Groups: true} identity, validPW, err := c.Login(context.Background(), s, tt.input.username, tt.input.password) if err != nil { - t.Fatal(err.Error()) + t.Fatalf("Login failed for user %s: %v", tt.input.username, err.Error()) } t.Log(identity) if identity.Username != tt.expected.username { @@ -333,7 +482,8 @@ func TestUseRefreshToken(t *testing.T) { defer deleteResource(t, token, groupID, groupsURL) c := conn{ - Host: keystoneURL, Domain: testDomain, + client: http.DefaultClient, + Host: keystoneURL, Domain: domainKeystone{ID: testDomainID}, AdminUsername: adminUser, AdminPassword: adminPass, } s := connector.Scopes{OfflineAccess: true, Groups: true} @@ -355,10 +505,11 @@ func TestUseRefreshToken(t *testing.T) { func TestUseRefreshTokenUserDeleted(t *testing.T) { setupVariables(t) token, _ := getAdminToken(t, adminUser, adminPass) - userID := createUser(t, token, testUser, testEmail, testPass) + userID := createUser(t, token, "", testUser, testEmail, testPass) c := conn{ - Host: keystoneURL, Domain: testDomain, + client: http.DefaultClient, + Host: keystoneURL, Domain: domainKeystone{ID: testDomainID}, AdminUsername: adminUser, AdminPassword: adminPass, } s := connector.Scopes{OfflineAccess: true, Groups: true} @@ -384,11 +535,12 @@ func TestUseRefreshTokenUserDeleted(t *testing.T) { func TestUseRefreshTokenGroupsChanged(t *testing.T) { setupVariables(t) token, _ := getAdminToken(t, adminUser, adminPass) - userID := createUser(t, token, testUser, testEmail, testPass) + userID := createUser(t, token, "", testUser, testEmail, testPass) defer deleteResource(t, token, userID, usersURL) c := conn{ - Host: keystoneURL, Domain: testDomain, + client: http.DefaultClient, + Host: keystoneURL, Domain: domainKeystone{ID: testDomainID}, AdminUsername: adminUser, AdminPassword: adminPass, } s := connector.Scopes{OfflineAccess: true, Groups: true} @@ -420,11 +572,12 @@ func TestUseRefreshTokenGroupsChanged(t *testing.T) { func TestNoGroupsInScope(t *testing.T) { setupVariables(t) token, _ := getAdminToken(t, adminUser, adminPass) - userID := createUser(t, token, testUser, testEmail, testPass) + userID := createUser(t, token, "", testUser, testEmail, testPass) defer deleteResource(t, token, userID, usersURL) c := conn{ - Host: keystoneURL, Domain: testDomain, + client: http.DefaultClient, + Host: keystoneURL, Domain: domainKeystone{ID: testDomainID}, AdminUsername: adminUser, AdminPassword: adminPass, } s := connector.Scopes{OfflineAccess: true, Groups: false} @@ -474,6 +627,7 @@ func setupVariables(t *testing.T) { authTokenURL = keystoneURL + "/v3/auth/tokens/" usersURL = keystoneAdminURL + "/v3/users/" groupsURL = keystoneAdminURL + "/v3/groups/" + domainsURL = keystoneAdminURL + "/v3/domains/" } func expectEquals(t *testing.T, a interface{}, b interface{}) { diff --git a/connector/ldap/ldap.go b/connector/ldap/ldap.go index 543402718c..9fe386c6e5 100644 --- a/connector/ldap/ldap.go +++ b/connector/ldap/ldap.go @@ -7,13 +7,15 @@ import ( "crypto/x509" "encoding/json" "fmt" + "log/slog" "net" + "net/url" "os" + "strings" "github.com/go-ldap/ldap/v3" "github.com/dexidp/dex/connector" - "github.com/dexidp/dex/pkg/log" ) // Config holds the configuration parameters for the LDAP connector. The LDAP @@ -60,6 +62,8 @@ import ( type UserMatcher struct { UserAttr string `json:"userAttr"` GroupAttr string `json:"groupAttr"` + // Look for parent groups + RecursionGroupAttr string `json:"recursionGroupAttr"` } // Config holds configuration options for LDAP logins. @@ -142,6 +146,8 @@ type Config struct { UserAttr string `json:"userAttr"` GroupAttr string `json:"groupAttr"` + RecursionGroupAttr string `json:"recursionGroupAttr"` + // Array of the field pairs used to match a user to a group. // See the "UserMatcher" struct for the exact field names // @@ -187,22 +193,24 @@ func parseScope(s string) (int, bool) { // Function exists here to allow backward compatibility between old and new // group to user matching implementations. // See "Config.GroupSearch.UserMatchers" comments for the details -func userMatchers(c *Config, logger log.Logger) []UserMatcher { +func userMatchers(c *Config, logger *slog.Logger) []UserMatcher { if len(c.GroupSearch.UserMatchers) > 0 && c.GroupSearch.UserMatchers[0].UserAttr != "" { return c.GroupSearch.UserMatchers } - log.Deprecated(logger, `LDAP: use groupSearch.userMatchers option instead of "userAttr/groupAttr" fields.`) + logger.Warn(`use "groupSearch.userMatchers" option instead of "userAttr/groupAttr" fields`, "deprecated", true) return []UserMatcher{ { - UserAttr: c.GroupSearch.UserAttr, - GroupAttr: c.GroupSearch.GroupAttr, + UserAttr: c.GroupSearch.UserAttr, + GroupAttr: c.GroupSearch.GroupAttr, + RecursionGroupAttr: c.GroupSearch.RecursionGroupAttr, }, } } // Open returns an authentication strategy using LDAP. -func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) { +func (c *Config) Open(id string, logger *slog.Logger) (connector.Connector, error) { + logger = logger.With(slog.Group("connector", "type", "ldap", "id", id)) conn, err := c.OpenConnector(logger) if err != nil { return nil, err @@ -216,7 +224,7 @@ type refreshData struct { } // OpenConnector is the same as Open but returns a type with all implemented connector interfaces. -func (c *Config) OpenConnector(logger log.Logger) (interface { +func (c *Config) OpenConnector(logger *slog.Logger) (interface { connector.Connector connector.PasswordConnector connector.RefreshConnector @@ -225,7 +233,7 @@ func (c *Config) OpenConnector(logger log.Logger) (interface { return c.openConnector(logger) } -func (c *Config) openConnector(logger log.Logger) (*ldapConnector, error) { +func (c *Config) openConnector(logger *slog.Logger) (*ldapConnector, error) { requiredFields := []struct { name string val string @@ -299,7 +307,7 @@ type ldapConnector struct { tlsConfig *tls.Config - logger log.Logger + logger *slog.Logger } var ( @@ -316,11 +324,14 @@ func (c *ldapConnector) do(_ context.Context, f func(c *ldap.Conn) error) error conn *ldap.Conn err error ) + switch { case c.InsecureNoSSL: - conn, err = ldap.Dial("tcp", c.Host) + u := url.URL{Scheme: "ldap", Host: c.Host} + conn, err = ldap.DialURL(u.String()) case c.StartTLS: - conn, err = ldap.Dial("tcp", c.Host) + u := url.URL{Scheme: "ldap", Host: c.Host} + conn, err = ldap.DialURL(u.String()) if err != nil { return fmt.Errorf("failed to connect: %v", err) } @@ -328,7 +339,8 @@ func (c *ldapConnector) do(_ context.Context, f func(c *ldap.Conn) error) error return fmt.Errorf("start TLS failed: %v", err) } default: - conn, err = ldap.DialTLS("tcp", c.Host, c.tlsConfig) + u := url.URL{Scheme: "ldaps", Host: c.Host} + conn, err = ldap.DialURL(u.String(), ldap.DialWithTLSConfig(c.tlsConfig)) } if err != nil { return fmt.Errorf("failed to connect: %v", err) @@ -347,21 +359,23 @@ func (c *ldapConnector) do(_ context.Context, f func(c *ldap.Conn) error) error return f(conn) } -func getAttrs(e ldap.Entry, name string) []string { +func (c *ldapConnector) getAttrs(e ldap.Entry, name string) []string { for _, a := range e.Attributes { if a.Name != name { continue } return a.Values } - if name == "DN" { + if strings.ToLower(name) == "dn" { return []string{e.DN} } + + c.logger.Debug("attribute is not fround in entry", "attribute", name) return nil } -func getAttr(e ldap.Entry, name string) string { - if a := getAttrs(e, name); len(a) > 0 { +func (c *ldapConnector) getAttr(e ldap.Entry, name string) string { + if a := c.getAttrs(e, name); len(a) > 0 { return a[0] } return "" @@ -373,25 +387,25 @@ func (c *ldapConnector) identityFromEntry(user ldap.Entry) (ident connector.Iden missing := []string{} // Fill the identity struct using the attributes from the user entry. - if ident.UserID = getAttr(user, c.UserSearch.IDAttr); ident.UserID == "" { + if ident.UserID = c.getAttr(user, c.UserSearch.IDAttr); ident.UserID == "" { missing = append(missing, c.UserSearch.IDAttr) } if c.UserSearch.NameAttr != "" { - if ident.Username = getAttr(user, c.UserSearch.NameAttr); ident.Username == "" { + if ident.Username = c.getAttr(user, c.UserSearch.NameAttr); ident.Username == "" { missing = append(missing, c.UserSearch.NameAttr) } } if c.UserSearch.PreferredUsernameAttrAttr != "" { - if ident.PreferredUsername = getAttr(user, c.UserSearch.PreferredUsernameAttrAttr); ident.PreferredUsername == "" { + if ident.PreferredUsername = c.getAttr(user, c.UserSearch.PreferredUsernameAttrAttr); ident.PreferredUsername == "" { missing = append(missing, c.UserSearch.PreferredUsernameAttrAttr) } } if c.UserSearch.EmailSuffix != "" { ident.Email = ident.Username + "@" + c.UserSearch.EmailSuffix - } else if ident.Email = getAttr(user, c.UserSearch.EmailAttr); ident.Email == "" { + } else if ident.Email = c.getAttr(user, c.UserSearch.EmailAttr); ident.Email == "" { missing = append(missing, c.UserSearch.EmailAttr) } // TODO(ericchiang): Let this value be set from an attribute. @@ -435,8 +449,8 @@ func (c *ldapConnector) userEntry(conn *ldap.Conn, username string) (user ldap.E req.Attributes = append(req.Attributes, c.UserSearch.PreferredUsernameAttrAttr) } - c.logger.Infof("performing ldap search %s %s %s", - req.BaseDN, scopeString(req.Scope), req.Filter) + c.logger.Info("performing ldap search", + "base_dn", req.BaseDN, "scope", scopeString(req.Scope), "filter", req.Filter) resp, err := conn.Search(req) if err != nil { return ldap.Entry{}, false, fmt.Errorf("ldap: search with filter %q failed: %v", req.Filter, err) @@ -444,11 +458,11 @@ func (c *ldapConnector) userEntry(conn *ldap.Conn, username string) (user ldap.E switch n := len(resp.Entries); n { case 0: - c.logger.Errorf("ldap: no results returned for filter: %q", filter) + c.logger.Error("no results returned for filter", "filter", filter) return ldap.Entry{}, false, nil case 1: user = *resp.Entries[0] - c.logger.Infof("username %q mapped to entry %s", username, user.DN) + c.logger.Info("username mapped to entry", "username", username, "user_dn", user.DN) return user, true, nil default: return ldap.Entry{}, false, fmt.Errorf("ldap: filter returned multiple (%d) results: %q", n, filter) @@ -457,6 +471,7 @@ func (c *ldapConnector) userEntry(conn *ldap.Conn, username string) (user ldap.E func (c *ldapConnector) Login(ctx context.Context, s connector.Scopes, username, password string) (ident connector.Identity, validPass bool, err error) { // make this check to avoid unauthenticated bind to the LDAP server. + if password == "" { return connector.Identity{}, false, nil } @@ -468,6 +483,8 @@ func (c *ldapConnector) Login(ctx context.Context, s connector.Scopes, username, user ldap.Entry ) + username = ldap.EscapeFilter(username) + err = c.do(ctx, func(conn *ldap.Conn) error { entry, found, err := c.userEntry(conn, username) if err != nil { @@ -485,11 +502,11 @@ func (c *ldapConnector) Login(ctx context.Context, s connector.Scopes, username, if ldapErr, ok := err.(*ldap.Error); ok { switch ldapErr.ResultCode { case ldap.LDAPResultInvalidCredentials: - c.logger.Errorf("ldap: invalid password for user %q", user.DN) + c.logger.Error("invalid password for user", "user_dn", user.DN) incorrectPass = true return nil case ldap.LDAPResultConstraintViolation: - c.logger.Errorf("ldap: constraint violation for user %q: %s", user.DN, ldapErr.Error()) + c.logger.Error("constraint violation for user", "user_dn", user.DN, "err", ldapErr.Error()) incorrectPass = true return nil } @@ -575,61 +592,124 @@ func (c *ldapConnector) Refresh(ctx context.Context, s connector.Scopes, ident c func (c *ldapConnector) groups(ctx context.Context, user ldap.Entry) ([]string, error) { if c.GroupSearch.BaseDN == "" { - c.logger.Debugf("No groups returned for %q because no groups baseDN has been configured.", getAttr(user, c.UserSearch.NameAttr)) + c.logger.Debug("No groups returned because no groups baseDN has been configured.", "base_dn", c.getAttr(user, c.UserSearch.NameAttr)) return nil, nil } - var groups []*ldap.Entry + var groupNames []string + for _, matcher := range c.GroupSearch.UserMatchers { - for _, attr := range getAttrs(user, matcher.UserAttr) { - filter := fmt.Sprintf("(%s=%s)", matcher.GroupAttr, ldap.EscapeFilter(attr)) - if c.GroupSearch.Filter != "" { - filter = fmt.Sprintf("(&%s%s)", c.GroupSearch.Filter, filter) + // Initial Search + var groups []*ldap.Entry + for _, attr := range c.getAttrs(user, matcher.UserAttr) { + obtained, filter, err := c.queryGroups(ctx, matcher.GroupAttr, attr) + if err != nil { + return nil, err + } + gotGroups := len(obtained) != 0 + if !gotGroups { + // TODO(ericchiang): Is this going to spam the logs? + c.logger.Error("ldap: groups search returned no groups", "filter", filter) } + groups = append(groups, obtained...) + } - req := &ldap.SearchRequest{ - BaseDN: c.GroupSearch.BaseDN, - Filter: filter, - Scope: c.groupSearchScope, - Attributes: []string{c.GroupSearch.NameAttr}, + // If RecursionGroupAttr is not set, convert direct groups into names and return + if matcher.RecursionGroupAttr == "" { + for _, group := range groups { + name := c.getAttr(*group, c.GroupSearch.NameAttr) + if name == "" { + return nil, fmt.Errorf( + "ldap: group entity %q missing required attribute %q", + group.DN, c.GroupSearch.NameAttr, + ) + } + groupNames = append(groupNames, name) } + continue + } + + // Recursive Search + c.logger.Info("Recursive group search enabled", "groupAttr", matcher.GroupAttr, "recursionAttr", matcher.RecursionGroupAttr) + for { + var nextLevel []*ldap.Entry + for _, group := range groups { + name := c.getAttr(*group, c.GroupSearch.NameAttr) + if name == "" { + return nil, fmt.Errorf("ldap: group entity %q missing required attribute %q", + group.DN, c.GroupSearch.NameAttr) + } + + // Prevent duplicates and circular references. + duplicate := false + for _, existingName := range groupNames { + if name == existingName { + c.logger.Debug("Found duplicate group", "name", name) + duplicate = true + break + } + } + if duplicate { + continue + } + + groupNames = append(groupNames, name) - gotGroups := false - if err := c.do(ctx, func(conn *ldap.Conn) error { - c.logger.Infof("performing ldap search %s %s %s", - req.BaseDN, scopeString(req.Scope), req.Filter) - resp, err := conn.Search(req) + // Search for parent groups using the group's DN. + parents, filter, err := c.queryGroups(ctx, matcher.RecursionGroupAttr, group.DN) if err != nil { - return fmt.Errorf("ldap: search failed: %v", err) + return nil, err + } + if len(parents) == 0 { + c.logger.Debug("No parent groups found", "filter", filter) + } else { + nextLevel = append(nextLevel, parents...) } - gotGroups = len(resp.Entries) != 0 - groups = append(groups, resp.Entries...) - return nil - }); err != nil { - return nil, err } - if !gotGroups { - // TODO(ericchiang): Is this going to spam the logs? - c.logger.Errorf("ldap: groups search with filter %q returned no groups", filter) + if len(nextLevel) == 0 { + break } + groups = nextLevel } } + return groupNames, nil +} + +func (c *ldapConnector) queryGroups(ctx context.Context, memberAttr, dn string) ([]*ldap.Entry, string, error) { + filter := fmt.Sprintf("(%s=%s)", memberAttr, ldap.EscapeFilter(dn)) + if c.GroupSearch.Filter != "" { + filter = fmt.Sprintf("(&%s%s)", c.GroupSearch.Filter, filter) + } - groupNames := make([]string, 0, len(groups)) - for _, group := range groups { - name := getAttr(*group, c.GroupSearch.NameAttr) - if name == "" { - // Be obnoxious about missing missing attributes. If the group entry is - // missing its name attribute, that indicates a misconfiguration. - // - // In the future we can add configuration options to just log these errors. - return nil, fmt.Errorf("ldap: group entity %q missing required attribute %q", - group.DN, c.GroupSearch.NameAttr) + req := &ldap.SearchRequest{ + BaseDN: c.GroupSearch.BaseDN, + Filter: filter, + Scope: c.groupSearchScope, + Attributes: []string{c.GroupSearch.NameAttr}, + } + + var entries []*ldap.Entry + if err := c.do(ctx, func(conn *ldap.Conn) error { + c.logger.Info( + "performing ldap search", + "base_dn", req.BaseDN, + "scope", scopeString(req.Scope), + "filter", req.Filter, + ) + resp, err := conn.Search(req) + if err != nil { + if ldapErr, ok := err.(*ldap.Error); ok && ldapErr.ResultCode == ldap.LDAPResultNoSuchObject { + c.logger.Info("LDAP search returned no groups", "filter", filter) + return nil + } + return fmt.Errorf("ldap: search failed: %v", err) } - - groupNames = append(groupNames, name) + entries = append(entries, resp.Entries...) + return nil + }); err != nil { + return nil, filter, err } - return groupNames, nil + return entries, filter, nil } func (c *ldapConnector) Prompt() string { diff --git a/connector/ldap/ldap_test.go b/connector/ldap/ldap_test.go index 83f9f4790c..a9665e128d 100644 --- a/connector/ldap/ldap_test.go +++ b/connector/ldap/ldap_test.go @@ -3,12 +3,11 @@ package ldap import ( "context" "fmt" - "io" + "log/slog" "os" "testing" "github.com/kylelemons/godebug/pretty" - "github.com/sirupsen/logrus" "github.com/dexidp/dex/connector" ) @@ -83,6 +82,18 @@ func TestQuery(t *testing.T) { password: "foo", wantBadPW: true, // Want invalid password, not a query error. }, + { + name: "invalid wildcard username", + username: "a*", // wildcard query is not allowed + password: "foo", + wantBadPW: true, // Want invalid password, not a query error. + }, + { + name: "invalid wildcard password", + username: "john", + password: "*", // wildcard password is not allowed + wantBadPW: true, // Want invalid password, not a query error. + }, } runTests(t, connectLDAP, c, tests) @@ -277,7 +288,7 @@ func TestGroupFilter(t *testing.T) { c.GroupSearch.BaseDN = "ou=TestGroupFilter,dc=example,dc=org" c.GroupSearch.UserMatchers = []UserMatcher{ { - UserAttr: "DN", + UserAttr: "dn", GroupAttr: "member", }, } @@ -514,6 +525,56 @@ func TestUsernamePrompt(t *testing.T) { } } +func TestNestedGroups(t *testing.T) { + c := &Config{} + c.UserSearch.BaseDN = "ou=People,ou=TestNestedGroups,dc=example,dc=org" + c.UserSearch.NameAttr = "cn" + c.UserSearch.EmailAttr = "mail" + c.UserSearch.IDAttr = "DN" + c.UserSearch.Username = "cn" + + c.GroupSearch.BaseDN = "ou=TestNestedGroups,dc=example,dc=org" + c.GroupSearch.UserMatchers = []UserMatcher{ + { + UserAttr: "DN", + GroupAttr: "member", + // Enable Recursive Search + RecursionGroupAttr: "member", + }, + } + c.GroupSearch.NameAttr = "cn" + + tests := []subtest{ + { + name: "nestedgroups_jane", + username: "jane", + password: "foo", + groups: true, + want: connector.Identity{ + UserID: "cn=jane,ou=People,ou=TestNestedGroups,dc=example,dc=org", + Username: "jane", + Email: "janedoe@example.com", + EmailVerified: true, + Groups: []string{"childGroup", "circularGroup1", "intermediateGroup", "circularGroup2", "parentGroup"}, + }, + }, + { + name: "nestedgroups_john", + username: "john", + password: "bar", + groups: true, + want: connector.Identity{ + UserID: "cn=john,ou=People,ou=TestNestedGroups,dc=example,dc=org", + Username: "john", + Email: "johndoe@example.com", + EmailVerified: true, + Groups: []string{"circularGroup2", "intermediateGroup", "circularGroup1", "parentGroup"}, + }, + }, + } + runTests(t, connectLDAP, c, tests) +} + func getenv(key, defaultVal string) string { if val := os.Getenv(key); val != "" { return val @@ -523,7 +584,7 @@ func getenv(key, defaultVal string) string { // runTests runs a set of tests against an LDAP schema. // -// The tests require LDAP to be runnning. +// The tests require LDAP to be running. // You can use the provided docker-compose file to setup an LDAP server. func runTests(t *testing.T, connMethod connectionMethod, config *Config, tests []subtest) { ldapHost := os.Getenv("DEX_LDAP_HOST") @@ -555,7 +616,7 @@ func runTests(t *testing.T, connMethod connectionMethod, config *Config, tests [ c.BindDN = "cn=admin,dc=example,dc=org" c.BindPW = "admin" - l := &logrus.Logger{Out: io.Discard, Formatter: &logrus.TextFormatter{}} + l := slog.New(slog.DiscardHandler) conn, err := c.openConnector(l) if err != nil { diff --git a/connector/ldap/testdata/schema.ldif b/connector/ldap/testdata/schema.ldif index 69c7b3ff64..a7f1393d4e 100644 --- a/connector/ldap/testdata/schema.ldif +++ b/connector/ldap/testdata/schema.ldif @@ -445,3 +445,63 @@ sn: doe cn: jane mail: janedoe@example.com userpassword: foo + +######################################################################## + +dn: ou=TestNestedGroups,dc=example,dc=org +objectClass: organizationalUnit +ou: TestNestedGroups + +dn: ou=People,ou=TestNestedGroups,dc=example,dc=org +objectClass: organizationalUnit +ou: People + +dn: cn=jane,ou=People,ou=TestNestedGroups,dc=example,dc=org +objectClass: person +objectClass: inetOrgPerson +sn: doe +cn: jane +mail: janedoe@example.com +userpassword: foo + +dn: cn=john,ou=People,ou=TestNestedGroups,dc=example,dc=org +objectClass: person +objectClass: inetOrgPerson +sn: doe +cn: john +mail: johndoe@example.com +userpassword: bar + +# Group definitions. + +dn: ou=Groups,ou=TestNestedGroups,dc=example,dc=org +objectClass: organizationalUnit +ou: Groups + +dn: cn=childGroup,ou=Groups,ou=TestNestedGroups,dc=example,dc=org +objectClass: groupOfNames +cn: childGroup +member: cn=jane,ou=People,ou=TestNestedGroups,dc=example,dc=org + +dn: cn=intermediateGroup,ou=Groups,ou=TestNestedGroups,dc=example,dc=org +objectClass: groupOfNames +cn: intermediateGroup +member: cn=childGroup,ou=Groups,ou=TestNestedGroups,dc=example,dc=org +member: cn=john,ou=People,ou=TestNestedGroups,dc=example,dc=org + +dn: cn=parentGroup,ou=Groups,ou=TestNestedGroups,dc=example,dc=org +objectClass: groupOfNames +cn: parentGroup +member: cn=intermediateGroup,ou=Groups,ou=TestNestedGroups,dc=example,dc=org + +dn: cn=circularGroup1,ou=Groups,ou=TestNestedGroups,dc=example,dc=org +objectClass: groupOfNames +cn: circularGroup1 +member: cn=circularGroup2,ou=Groups,ou=TestNestedGroups,dc=example,dc=org +member: cn=jane,ou=People,ou=TestNestedGroups,dc=example,dc=org + +dn: cn=circularGroup2,ou=Groups,ou=TestNestedGroups,dc=example,dc=org +objectClass: groupOfNames +cn: circularGroup2 +member: cn=circularGroup1,ou=Groups,ou=TestNestedGroups,dc=example,dc=org +member: cn=john,ou=People,ou=TestNestedGroups,dc=example,dc=org diff --git a/connector/linkedin/linkedin.go b/connector/linkedin/linkedin.go index f79f1c49d8..f17d17cca1 100644 --- a/connector/linkedin/linkedin.go +++ b/connector/linkedin/linkedin.go @@ -6,13 +6,13 @@ import ( "encoding/json" "fmt" "io" + "log/slog" "net/http" "strings" "golang.org/x/oauth2" "github.com/dexidp/dex/connector" - "github.com/dexidp/dex/pkg/log" ) const ( @@ -29,7 +29,7 @@ type Config struct { } // Open returns a strategy for logging in through LinkedIn -func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) { +func (c *Config) Open(id string, logger *slog.Logger) (connector.Connector, error) { return &linkedInConnector{ oauth2Config: &oauth2.Config{ ClientID: c.ClientID, @@ -41,7 +41,7 @@ func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) Scopes: []string{"r_liteprofile", "r_emailaddress"}, RedirectURL: c.RedirectURI, }, - logger: logger, + logger: logger.With(slog.Group("connector", "type", "linkedin", "id", id)), }, nil } @@ -51,7 +51,7 @@ type connectorData struct { type linkedInConnector struct { oauth2Config *oauth2.Config - logger log.Logger + logger *slog.Logger } // LinkedIn doesn't provide refresh tokens, so refresh tokens issued by Dex diff --git a/connector/microsoft/microsoft.go b/connector/microsoft/microsoft.go index 3952c94be6..2fcf6a7515 100644 --- a/connector/microsoft/microsoft.go +++ b/connector/microsoft/microsoft.go @@ -8,6 +8,7 @@ import ( "errors" "fmt" "io" + "log/slog" "net/http" "strings" "sync" @@ -17,7 +18,6 @@ import ( "github.com/dexidp/dex/connector" groups_pkg "github.com/dexidp/dex/pkg/groups" - "github.com/dexidp/dex/pkg/log" ) // GroupNameFormat represents the format of the group identifier @@ -54,6 +54,9 @@ type Config struct { UseGroupsAsWhitelist bool `json:"useGroupsAsWhitelist"` EmailToLowercase bool `json:"emailToLowercase"` + APIURL string `json:"apiURL"` + GraphURL string `json:"graphURL"` + // PromptType is used for the prompt query parameter. // For valid values, see https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow#request-an-authorization-code. PromptType string `json:"promptType"` @@ -63,10 +66,10 @@ type Config struct { } // Open returns a strategy for logging in through Microsoft. -func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) { +func (c *Config) Open(id string, logger *slog.Logger) (connector.Connector, error) { m := microsoftConnector{ - apiURL: "https://login.microsoftonline.com", - graphURL: "https://graph.microsoft.com", + apiURL: strings.TrimSuffix(c.APIURL, "/"), + graphURL: strings.TrimSuffix(c.GraphURL, "/"), redirectURI: c.RedirectURI, clientID: c.ClientID, clientSecret: c.ClientSecret, @@ -75,12 +78,21 @@ func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) groups: c.Groups, groupNameFormat: c.GroupNameFormat, useGroupsAsWhitelist: c.UseGroupsAsWhitelist, - logger: logger, + logger: logger.With(slog.Group("connector", "type", "microsoft", "id", id)), emailToLowercase: c.EmailToLowercase, promptType: c.PromptType, domainHint: c.DomainHint, scopes: c.Scopes, } + + if m.apiURL == "" { + m.apiURL = "https://login.microsoftonline.com" + } + + if m.graphURL == "" { + m.graphURL = "https://graph.microsoft.com" + } + // By default allow logins from both personal and business/school // accounts. if m.tenant == "" { @@ -121,7 +133,7 @@ type microsoftConnector struct { groupNameFormat GroupNameFormat groups []string useGroupsAsWhitelist bool - logger log.Logger + logger *slog.Logger emailToLowercase bool promptType string domainHint string @@ -316,22 +328,27 @@ func (c *microsoftConnector) Refresh(ctx context.Context, s connector.Scopes, id // https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/resources/user // id - The unique identifier for the user. Inherited from -// directoryObject. Key. Not nullable. Read-only. +// +// directoryObject. Key. Not nullable. Read-only. +// // displayName - The name displayed in the address book for the user. -// This is usually the combination of the user's first name, -// middle initial and last name. This property is required -// when a user is created and it cannot be cleared during -// updates. Supports $filter and $orderby. +// +// This is usually the combination of the user's first name, +// middle initial and last name. This property is required +// when a user is created and it cannot be cleared during +// updates. Supports $filter and $orderby. +// // userPrincipalName - The user principal name (UPN) of the user. -// The UPN is an Internet-style login name for the user -// based on the Internet standard RFC 822. By convention, -// this should map to the user's email name. The general -// format is alias@domain, where domain must be present in -// the tenant’s collection of verified domains. This -// property is required when a user is created. The -// verified domains for the tenant can be accessed from the -// verifiedDomains property of organization. Supports -// $filter and $orderby. +// +// The UPN is an Internet-style login name for the user +// based on the Internet standard RFC 822. By convention, +// this should map to the user's email name. The general +// format is alias@domain, where domain must be present in +// the tenant’s collection of verified domains. This +// property is required when a user is created. The +// verified domains for the tenant can be accessed from the +// verifiedDomains property of organization. Supports +// $filter and $orderby. type user struct { ID string `json:"id"` Name string `json:"displayName"` @@ -364,8 +381,9 @@ func (c *microsoftConnector) user(ctx context.Context, client *http.Client) (u u // https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/resources/group // displayName - The display name for the group. This property is required when -// a group is created and it cannot be cleared during updates. -// Supports $filter and $orderby. +// +// a group is created and it cannot be cleared during updates. +// Supports $filter and $orderby. type group struct { Name string `json:"displayName"` } diff --git a/connector/mock/connectortest.go b/connector/mock/connectortest.go index e7ee438625..7e5979a992 100644 --- a/connector/mock/connectortest.go +++ b/connector/mock/connectortest.go @@ -5,16 +5,16 @@ import ( "context" "errors" "fmt" + "log/slog" "net/http" "net/url" "github.com/dexidp/dex/connector" - "github.com/dexidp/dex/pkg/log" ) // NewCallbackConnector returns a mock connector which requires no user interaction. It always returns // the same (fake) identity. -func NewCallbackConnector(logger log.Logger) connector.Connector { +func NewCallbackConnector(logger *slog.Logger) connector.Connector { return &Callback{ Identity: connector.Identity{ UserID: "0-385-28089-0", @@ -39,7 +39,7 @@ var ( type Callback struct { // The returned identity. Identity connector.Identity - Logger log.Logger + Logger *slog.Logger } // LoginURL returns the URL to redirect the user to login with. @@ -66,11 +66,16 @@ func (m *Callback) Refresh(ctx context.Context, s connector.Scopes, identity con return m.Identity, nil } +func (m *Callback) TokenIdentity(ctx context.Context, subjectTokenType, subjectToken string) (connector.Identity, error) { + return m.Identity, nil +} + // CallbackConfig holds the configuration parameters for a connector which requires no interaction. type CallbackConfig struct{} // Open returns an authentication strategy which requires no user interaction. -func (c *CallbackConfig) Open(id string, logger log.Logger) (connector.Connector, error) { +func (c *CallbackConfig) Open(id string, logger *slog.Logger) (connector.Connector, error) { + logger = logger.With(slog.Group("connector", "type", "callback", "id", id)) return NewCallbackConnector(logger), nil } @@ -82,7 +87,7 @@ type PasswordConfig struct { } // Open returns an authentication strategy which prompts for a predefined username and password. -func (c *PasswordConfig) Open(id string, logger log.Logger) (connector.Connector, error) { +func (c *PasswordConfig) Open(id string, logger *slog.Logger) (connector.Connector, error) { if c.Username == "" { return nil, errors.New("no username supplied") } @@ -95,7 +100,7 @@ func (c *PasswordConfig) Open(id string, logger log.Logger) (connector.Connector type passwordConnector struct { username string password string - logger log.Logger + logger *slog.Logger } func (p passwordConnector) Close() error { return nil } diff --git a/connector/oauth/oauth.go b/connector/oauth/oauth.go index 237d075e83..413a813a08 100644 --- a/connector/oauth/oauth.go +++ b/connector/oauth/oauth.go @@ -2,22 +2,18 @@ package oauth import ( "context" - "crypto/tls" - "crypto/x509" "encoding/base64" "encoding/json" "errors" "fmt" - "net" + "log/slog" "net/http" - "os" "strings" - "time" "golang.org/x/oauth2" "github.com/dexidp/dex/connector" - "github.com/dexidp/dex/pkg/log" + "github.com/dexidp/dex/pkg/httpclient" ) type oauthConnector struct { @@ -35,7 +31,7 @@ type oauthConnector struct { emailVerifiedKey string groupsKey string httpClient *http.Client - logger log.Logger + logger *slog.Logger } type connectorData struct { @@ -62,7 +58,7 @@ type Config struct { } `json:"claimMapping"` } -func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) { +func (c *Config) Open(id string, logger *slog.Logger) (connector.Connector, error) { var err error userIDKey := c.UserIDKey @@ -103,7 +99,7 @@ func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) userInfoURL: c.UserInfoURL, scopes: c.Scopes, redirectURI: c.RedirectURI, - logger: logger, + logger: logger.With(slog.Group("connector", "type", "oauth", "id", id)), userIDKey: userIDKey, userNameKey: userNameKey, preferredUsernameKey: preferredUsernameKey, @@ -112,7 +108,7 @@ func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) emailVerifiedKey: emailVerifiedKey, } - oauthConn.httpClient, err = newHTTPClient(c.RootCAs, c.InsecureSkipVerify) + oauthConn.httpClient, err = httpclient.NewHTTPClient(c.RootCAs, c.InsecureSkipVerify) if err != nil { return nil, err } @@ -120,40 +116,6 @@ func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) return oauthConn, err } -func newHTTPClient(rootCAs []string, insecureSkipVerify bool) (*http.Client, error) { - pool, err := x509.SystemCertPool() - if err != nil { - return nil, err - } - - tlsConfig := tls.Config{RootCAs: pool, InsecureSkipVerify: insecureSkipVerify} - for _, rootCA := range rootCAs { - rootCABytes, err := os.ReadFile(rootCA) - if err != nil { - return nil, fmt.Errorf("failed to read root-ca: %v", err) - } - if !tlsConfig.RootCAs.AppendCertsFromPEM(rootCABytes) { - return nil, fmt.Errorf("no certs found in root CA file %q", rootCA) - } - } - - return &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: &tlsConfig, - Proxy: http.ProxyFromEnvironment, - DialContext: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - DualStack: true, - }).DialContext, - MaxIdleConns: 100, - IdleConnTimeout: 90 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, - }, - }, nil -} - func (c *oauthConnector) LoginURL(scopes connector.Scopes, callbackURL, state string) (string, error) { if c.redirectURI != callbackURL { return "", fmt.Errorf("expected callback URL %q did not match the URL in the config %q", callbackURL, c.redirectURI) diff --git a/connector/oauth/oauth_test.go b/connector/oauth/oauth_test.go index 3a5ec6bf59..2f6b0b95a3 100644 --- a/connector/oauth/oauth_test.go +++ b/connector/oauth/oauth_test.go @@ -6,15 +6,15 @@ import ( "encoding/json" "errors" "fmt" + "log/slog" "net/http" "net/http/httptest" "net/url" "sort" "testing" - "github.com/sirupsen/logrus" + "github.com/go-jose/go-jose/v4" "github.com/stretchr/testify/assert" - jose "gopkg.in/square/go-jose.v2" "github.com/dexidp/dex/connector" ) @@ -270,7 +270,7 @@ func newConnector(t *testing.T, serverURL string) *oauthConnector { testConfig.ClaimMapping.EmailKey = "mail" testConfig.ClaimMapping.EmailVerifiedKey = "has_verified_email" - log := logrus.New() + log := slog.New(slog.DiscardHandler) conn, err := testConfig.Open("id", log) if err != nil { diff --git a/connector/oidc/oidc.go b/connector/oidc/oidc.go index e345dca0b2..1cf2b62ad8 100644 --- a/connector/oidc/oidc.go +++ b/connector/oidc/oidc.go @@ -6,8 +6,10 @@ import ( "encoding/json" "errors" "fmt" + "log/slog" "net/http" "net/url" + "regexp" "strings" "time" @@ -15,16 +17,26 @@ import ( "golang.org/x/oauth2" "github.com/dexidp/dex/connector" - "github.com/dexidp/dex/pkg/log" + groups_pkg "github.com/dexidp/dex/pkg/groups" + "github.com/dexidp/dex/pkg/httpclient" ) // Config holds configuration options for OpenID Connect logins. type Config struct { - Issuer string `json:"issuer"` + Issuer string `json:"issuer"` + // Some offspec providers like Azure, Oracle IDCS have oidc discovery url + // different from issuer url which causes issuerValidation to fail + // IssuerAlias provides a way to override the Issuer url + // from the .well-known/openid-configuration issuer + IssuerAlias string `json:"issuerAlias"` ClientID string `json:"clientID"` ClientSecret string `json:"clientSecret"` RedirectURI string `json:"redirectURI"` + // The section to override options discovered automatically from + // the providers' discovery URL (.well-known/openid-configuration). + ProviderDiscoveryOverrides ProviderDiscoveryOverrides `json:"providerDiscoveryOverrides"` + // Causes client_secret to be passed as POST parameters instead of basic // auth. This is specifically "NOT RECOMMENDED" by the OAuth2 RFC, but some // providers require it. @@ -34,17 +46,32 @@ type Config struct { Scopes []string `json:"scopes"` // defaults to "profile" and "email" + // HostedDomains was an optional list of whitelisted domains when using the OIDC connector with Google. + // Only users from a whitelisted domain were allowed to log in. + // Support for this option was removed from the OIDC connector. + // Consider switching to the Google connector which supports this option. + // + // Deprecated: will be removed in future releases. + HostedDomains []string `json:"hostedDomains"` + + // Certificates for SSL validation + RootCAs []string `json:"rootCAs"` + // Override the value of email_verified to true in the returned claims InsecureSkipEmailVerified bool `json:"insecureSkipEmailVerified"` // InsecureEnableGroups enables groups claims. This is disabled by default until https://github.com/dexidp/dex/issues/1065 is resolved - InsecureEnableGroups bool `json:"insecureEnableGroups"` + InsecureEnableGroups bool `json:"insecureEnableGroups"` + AllowedGroups []string `json:"allowedGroups"` // AcrValues (Authentication Context Class Reference Values) that specifies the Authentication Context Class Values // within the Authentication Request that the Authorization Server is being requested to use for // processing requests from this Client, with the values appearing in order of preference. AcrValues []string `json:"acrValues"` + // Disable certificate verification + InsecureSkipVerify bool `json:"insecureSkipVerify"` + // GetUserInfo uses the userinfo endpoint to get additional claims for // the token. This is especially useful where upstreams return "thin" // id tokens @@ -54,8 +81,8 @@ type Config struct { UserNameKey string `json:"userNameKey"` - // PromptType will be used fot the prompt parameter (when offline_access, by default prompt=consent) - PromptType string `json:"promptType"` + // PromptType will be used for the prompt parameter (when offline_access, by default prompt=consent) + PromptType *string `json:"promptType"` // OverrideClaimMapping will be used to override the options defined in claimMappings. // i.e. if there are 'email' and `preferred_email` claims available, by default Dex will always use the `email` claim independent of the ClaimMapping.EmailKey. @@ -72,6 +99,101 @@ type Config struct { // Configurable key which contains the groups claims GroupsKey string `json:"groups"` // defaults to "groups" } `json:"claimMapping"` + + // ClaimMutations holds all claim mutations options + ClaimMutations struct { + NewGroupFromClaims []NewGroupFromClaims `json:"newGroupFromClaims"` + FilterGroupClaims FilterGroupClaims `json:"filterGroupClaims"` + ModifyGroupNames ModifyGroupNames `json:"modifyGroupNames"` + } `json:"claimModifications"` +} + +type ProviderDiscoveryOverrides struct { + // TokenURL provides a way to user overwrite the Token URL + // from the .well-known/openid-configuration token_endpoint + TokenURL string `json:"tokenURL"` + // AuthURL provides a way to user overwrite the Auth URL + // from the .well-known/openid-configuration authorization_endpoint + AuthURL string `json:"authURL"` + // JWKSURL provides a way to user overwrite the JWKS URL + // from the .well-known/openid-configuration jwks_uri + JWKSURL string `json:"jwksURL"` +} + +func (o *ProviderDiscoveryOverrides) Empty() bool { + return o.TokenURL == "" && o.AuthURL == "" && o.JWKSURL == "" +} + +func getProvider(ctx context.Context, issuer string, overrides ProviderDiscoveryOverrides) (*oidc.Provider, error) { + provider, err := oidc.NewProvider(ctx, issuer) + if err != nil { + return nil, fmt.Errorf("failed to get provider: %v", err) + } + + if overrides.Empty() { + return provider, nil + } + + v := &struct { + Issuer string `json:"issuer"` + AuthURL string `json:"authorization_endpoint"` + TokenURL string `json:"token_endpoint"` + DeviceAuthURL string `json:"device_authorization_endpoint"` + JWKSURL string `json:"jwks_uri"` + UserInfoURL string `json:"userinfo_endpoint"` + Algorithms []string `json:"id_token_signing_alg_values_supported"` + }{} + if err := provider.Claims(v); err != nil { + return nil, fmt.Errorf("failed to extract provider discovery claims: %v", err) + } + config := oidc.ProviderConfig{ + IssuerURL: v.Issuer, + AuthURL: v.AuthURL, + TokenURL: v.TokenURL, + DeviceAuthURL: v.DeviceAuthURL, + JWKSURL: v.JWKSURL, + UserInfoURL: v.UserInfoURL, + Algorithms: v.Algorithms, + } + + if overrides.TokenURL != "" { + config.TokenURL = overrides.TokenURL + } + if overrides.AuthURL != "" { + config.AuthURL = overrides.AuthURL + } + if overrides.JWKSURL != "" { + config.JWKSURL = overrides.JWKSURL + } + return config.NewProvider(context.Background()), nil +} + +// NewGroupFromClaims creates a new group from a list of claims and appends it to the list of existing groups. +type NewGroupFromClaims struct { + // List of claim to join together + Claims []string `json:"claims"` + + // String to separate the claims + Delimiter string `json:"delimiter"` + + // Should Dex remove the Delimiter string from claim values + // This is done to keep resulting claim structure in full control of the Dex operator + ClearDelimiter bool `json:"clearDelimiter"` + + // String to place before the first claim + Prefix string `json:"prefix"` +} + +// FilterGroupClaims is a regex filter for to keep only the matching groups. +// This is useful when the groups list is too large to fit within an HTTP header. +type FilterGroupClaims struct { + GroupsFilter string `json:"groupsFilter"` +} + +// ModifyGroupNames allows to modify the group claims by adding a prefix and/or suffix to each group. +type ModifyGroupNames struct { + Prefix string `json:"prefix"` + Suffix string `json:"suffix"` } // Domains that don't support basic auth. golang.org/x/oauth2 has an internal @@ -104,13 +226,28 @@ func knownBrokenAuthHeaderProvider(issuerURL string) bool { // Open returns a connector which can be used to login users through an upstream // OpenID Connect provider. -func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, err error) { - ctx, cancel := context.WithCancel(context.Background()) +func (c *Config) Open(id string, logger *slog.Logger) (conn connector.Connector, err error) { + if len(c.HostedDomains) > 0 { + return nil, fmt.Errorf("support for the Hosted domains option had been deprecated and removed, consider switching to the Google connector") + } + + httpClient, err := httpclient.NewHTTPClient(c.RootCAs, c.InsecureSkipVerify) + if err != nil { + return nil, err + } - provider, err := oidc.NewProvider(ctx, c.Issuer) + bgctx, cancel := context.WithCancel(context.Background()) + ctx := context.WithValue(bgctx, oauth2.HTTPClient, httpClient) + if c.IssuerAlias != "" { + ctx = oidc.InsecureIssuerURLContext(ctx, c.IssuerAlias) + } + provider, err := getProvider(ctx, c.Issuer, c.ProviderDiscoveryOverrides) if err != nil { cancel() - return nil, fmt.Errorf("failed to get provider: %v", err) + return nil, err + } + if !c.ProviderDiscoveryOverrides.Empty() { + logger.Warn("overrides for connector are set, this can be a vulnerability when not properly configured", "connector_id", id) } endpoint := provider.Endpoint() @@ -132,8 +269,17 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e } // PromptType should be "consent" by default, if not set - if c.PromptType == "" { - c.PromptType = "consent" + promptType := "consent" + if c.PromptType != nil { + promptType = *c.PromptType + } + + var groupsFilter *regexp.Regexp + if c.ClaimMutations.FilterGroupClaims.GroupsFilter != "" { + groupsFilter, err = regexp.Compile(c.ClaimMutations.FilterGroupClaims.GroupsFilter) + if err != nil { + logger.Warn("ignoring invalid", "invalid_regex", c.ClaimMutations.FilterGroupClaims.GroupsFilter, "connector_id", id) + } } clientID := c.ClientID @@ -147,22 +293,29 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e Scopes: scopes, RedirectURL: c.RedirectURI, }, - verifier: provider.Verifier( + verifier: provider.VerifierContext( + ctx, // Pass our ctx with customized http.Client &oidc.Config{ClientID: clientID}, ), - logger: logger, + logger: logger.With(slog.Group("connector", "type", "oidc", "id", id)), cancel: cancel, + httpClient: httpClient, insecureSkipEmailVerified: c.InsecureSkipEmailVerified, insecureEnableGroups: c.InsecureEnableGroups, + allowedGroups: c.AllowedGroups, acrValues: c.AcrValues, getUserInfo: c.GetUserInfo, - promptType: c.PromptType, + promptType: promptType, userIDKey: c.UserIDKey, userNameKey: c.UserNameKey, overrideClaimMapping: c.OverrideClaimMapping, preferredUsernameKey: c.ClaimMapping.PreferredUsernameKey, emailKey: c.ClaimMapping.EmailKey, groupsKey: c.ClaimMapping.GroupsKey, + newGroupFromClaims: c.ClaimMutations.NewGroupFromClaims, + groupsFilter: groupsFilter, + groupsPrefix: c.ClaimMutations.ModifyGroupNames.Prefix, + groupsSuffix: c.ClaimMutations.ModifyGroupNames.Suffix, }, nil } @@ -177,9 +330,11 @@ type oidcConnector struct { oauth2Config *oauth2.Config verifier *oidc.IDTokenVerifier cancel context.CancelFunc - logger log.Logger + logger *slog.Logger + httpClient *http.Client insecureSkipEmailVerified bool insecureEnableGroups bool + allowedGroups []string acrValues []string getUserInfo bool promptType string @@ -189,6 +344,10 @@ type oidcConnector struct { preferredUsernameKey string emailKey string groupsKey string + newGroupFromClaims []NewGroupFromClaims + groupsFilter *regexp.Regexp + groupsPrefix string + groupsSuffix string } func (c *oidcConnector) Close() error { @@ -231,6 +390,7 @@ type caller uint const ( createCaller caller = iota refreshCaller + exchangeCaller ) func (c *oidcConnector) HandleCallback(s connector.Scopes, r *http.Request) (identity connector.Identity, err error) { @@ -238,11 +398,14 @@ func (c *oidcConnector) HandleCallback(s connector.Scopes, r *http.Request) (ide if errType := q.Get("error"); errType != "" { return identity, &oauth2Error{errType, q.Get("error_description")} } - token, err := c.oauth2Config.Exchange(r.Context(), q.Get("code")) + + ctx := context.WithValue(r.Context(), oauth2.HTTPClient, c.httpClient) + + token, err := c.oauth2Config.Exchange(ctx, q.Get("code")) if err != nil { return identity, fmt.Errorf("oidc: failed to get token: %v", err) } - return c.createIdentity(r.Context(), identity, token, createCaller) + return c.createIdentity(ctx, identity, token, createCaller) } // Refresh is used to refresh a session with the refresh token provided by the IdP @@ -253,6 +416,8 @@ func (c *oidcConnector) Refresh(ctx context.Context, s connector.Scopes, identit return identity, fmt.Errorf("oidc: failed to unmarshal connector data: %v", err) } + ctx = context.WithValue(ctx, oauth2.HTTPClient, c.httpClient) + t := &oauth2.Token{ RefreshToken: string(cd.RefreshToken), Expiry: time.Now().Add(-time.Hour), @@ -264,11 +429,22 @@ func (c *oidcConnector) Refresh(ctx context.Context, s connector.Scopes, identit return c.createIdentity(ctx, identity, token, refreshCaller) } +func (c *oidcConnector) TokenIdentity(ctx context.Context, subjectTokenType, subjectToken string) (connector.Identity, error) { + var identity connector.Identity + + ctx = context.WithValue(ctx, oauth2.HTTPClient, c.httpClient) + + token := &oauth2.Token{ + AccessToken: subjectToken, + TokenType: subjectTokenType, + } + return c.createIdentity(ctx, identity, token, exchangeCaller) +} + func (c *oidcConnector) createIdentity(ctx context.Context, identity connector.Identity, token *oauth2.Token, caller caller) (connector.Identity, error) { var claims map[string]interface{} - rawIDToken, ok := token.Extra("id_token").(string) - if ok { + if rawIDToken, ok := token.Extra("id_token").(string); ok { idToken, err := c.verifier.Verify(ctx, rawIDToken) if err != nil { return identity, fmt.Errorf("oidc: failed to verify ID Token: %v", err) @@ -277,14 +453,36 @@ func (c *oidcConnector) createIdentity(ctx context.Context, identity connector.I if err := idToken.Claims(&claims); err != nil { return identity, fmt.Errorf("oidc: failed to decode claims: %v", err) } + } else if caller == exchangeCaller { + switch token.TokenType { + case "urn:ietf:params:oauth:token-type:id_token": + // Verify only works on ID tokens + idToken, err := c.provider.Verifier(&oidc.Config{SkipClientIDCheck: true}).Verify(ctx, token.AccessToken) + if err != nil { + return identity, fmt.Errorf("oidc: failed to verify token: %v", err) + } + if err := idToken.Claims(&claims); err != nil { + return identity, fmt.Errorf("oidc: failed to decode claims: %v", err) + } + case "urn:ietf:params:oauth:token-type:access_token": + if !c.getUserInfo { + return identity, fmt.Errorf("oidc: getUserInfo is required for access token exchange") + } + default: + return identity, fmt.Errorf("unknown token type for token exchange: %s", token.TokenType) + } } else if caller != refreshCaller { // ID tokens aren't mandatory in the reply when using a refresh_token grant return identity, errors.New("oidc: no id_token in token response") } - // We immediately want to run getUserInfo if configured before we validate the claims + // We immediately want to run getUserInfo if configured before we validate the claims. + // For token exchanges with access tokens, this is how we verify the token. if c.getUserInfo { - userInfo, err := c.provider.UserInfo(ctx, oauth2.StaticTokenSource(token)) + userInfo, err := c.provider.UserInfo(ctx, oauth2.StaticTokenSource(&oauth2.Token{ + AccessToken: token.AccessToken, + TokenType: "Bearer", // The UserInfo endpoint requires a bearer token as per RFC6750 + })) if err != nil { return identity, fmt.Errorf("oidc: error loading userinfo: %v", err) } @@ -359,12 +557,65 @@ func (c *oidcConnector) createIdentity(ctx context.Context, identity connector.I if found { for _, v := range vs { if s, ok := v.(string); ok { + if c.groupsFilter != nil && !c.groupsFilter.MatchString(s) { + continue + } groups = append(groups, s) + } else if groupMap, ok := v.(map[string]interface{}); ok { + if s, ok := groupMap["name"].(string); ok { + if c.groupsFilter != nil && !c.groupsFilter.MatchString(s) { + continue + } + groups = append(groups, s) + } } else { return identity, fmt.Errorf("malformed \"%v\" claim", groupsKey) } } } + + // Validate that the user is part of allowedGroups + if len(c.allowedGroups) > 0 { + groupMatches := groups_pkg.Filter(groups, c.allowedGroups) + + if len(groupMatches) == 0 { + // No group membership matches found, disallowing + return identity, fmt.Errorf("user not a member of allowed groups") + } + + groups = groupMatches + } + } + + // add prefix/suffix to groups + if c.groupsPrefix != "" || c.groupsSuffix != "" { + for i, group := range groups { + groups[i] = c.groupsPrefix + group + c.groupsSuffix + } + } + + for _, config := range c.newGroupFromClaims { + newGroupSegments := []string{ + config.Prefix, + } + for _, claimName := range config.Claims { + claimValue, ok := claims[claimName].(string) + if !ok { // Non string claim value are ignored, concatenating them doesn't really make any sense + continue + } + + if config.ClearDelimiter { + // Removing the delimiter string from the concatenated claim to ensure resulting claim structure + // is in full control of Dex operator + claimValue = strings.ReplaceAll(claimValue, config.Delimiter, "") + } + + newGroupSegments = append(newGroupSegments, claimValue) + } + + if len(newGroupSegments) > 1 { + groups = append(groups, strings.Join(newGroupSegments, config.Delimiter)) + } } cd := connectorData{ diff --git a/connector/oidc/oidc_test.go b/connector/oidc/oidc_test.go index d94af79de8..9a3d712665 100644 --- a/connector/oidc/oidc_test.go +++ b/connector/oidc/oidc_test.go @@ -2,6 +2,7 @@ package oidc import ( "bytes" + "context" "crypto/rand" "crypto/rsa" "encoding/base64" @@ -9,6 +10,7 @@ import ( "encoding/json" "errors" "fmt" + "log/slog" "net/http" "net/http/httptest" "reflect" @@ -16,8 +18,8 @@ import ( "testing" "time" - "github.com/sirupsen/logrus" - "gopkg.in/square/go-jose.v2" + "github.com/go-jose/go-jose/v4" + "github.com/stretchr/testify/require" "github.com/dexidp/dex/connector" ) @@ -61,6 +63,10 @@ func TestHandleCallback(t *testing.T) { expectPreferredUsername string expectedEmailField string token map[string]interface{} + groupsRegex string + newGroupFromClaims []NewGroupFromClaims + groupsPrefix string + groupsSuffix string }{ { name: "simpleCase", @@ -287,6 +293,197 @@ func TestHandleCallback(t *testing.T) { "email_verified": true, }, }, + { + name: "singularGroupResponseAsMap", + userIDKey: "", // not configured + userNameKey: "", // not configured + expectUserID: "subvalue", + expectUserName: "namevalue", + expectGroups: []string{"group1"}, + expectedEmailField: "emailvalue", + token: map[string]interface{}{ + "sub": "subvalue", + "name": "namevalue", + "groups": []map[string]string{{"name": "group1"}}, + "email": "emailvalue", + "email_verified": true, + }, + }, + { + name: "multipleGroupResponseAsMap", + userIDKey: "", // not configured + userNameKey: "", // not configured + expectUserID: "subvalue", + expectUserName: "namevalue", + expectGroups: []string{"group1", "group2"}, + expectedEmailField: "emailvalue", + token: map[string]interface{}{ + "sub": "subvalue", + "name": "namevalue", + "groups": []map[string]string{{"name": "group1"}, {"name": "group2"}}, + "email": "emailvalue", + "email_verified": true, + }, + }, + { + name: "newGroupFromClaims", + userIDKey: "", // not configured + userNameKey: "", // not configured + expectUserID: "subvalue", + expectUserName: "namevalue", + expectGroups: []string{"group1", "gh::acme::pipeline-one", "clr_delim-acme-foobar", "keep_delim-acme-foo-bar", "bk-emailvalue"}, + expectedEmailField: "emailvalue", + newGroupFromClaims: []NewGroupFromClaims{ + { // The basic functionality, should create "gh::acme::pipeline-one". + Claims: []string{ + "organization", + "pipeline", + }, + Delimiter: "::", + Prefix: "gh", + }, + { // Non existing claims, should not generate any any new group claim. + Claims: []string{ + "non-existing1", + "non-existing2", + }, + Delimiter: "::", + Prefix: "tfe", + }, + { // In this case the delimiter character("-") should be removed removed from "claim-with-delimiter" claim to ensure the resulting + // claim structure is in full control of the Dex operator and not the person creating a new pipeline. + // Should create "clr_delim-acme-foobar" and not "tfe-acme-foo-bar". + Claims: []string{ + "organization", + "claim-with-delimiter", + }, + Delimiter: "-", + ClearDelimiter: true, + Prefix: "clr_delim", + }, + { // In this case the delimiter character("-") should be NOT removed from "claim-with-delimiter" claim. + // Should create "keep_delim-acme-foo-bar". + Claims: []string{ + "organization", + "claim-with-delimiter", + }, + Delimiter: "-", + // ClearDelimiter: false, + Prefix: "keep_delim", + }, + { // Ignore non string claims (like arrays), this should result in "bk-emailvalue". + Claims: []string{ + "non-string-claim", + "non-string-claim2", + "email", + }, + Delimiter: "-", + Prefix: "bk", + }, + }, + + token: map[string]interface{}{ + "sub": "subvalue", + "name": "namevalue", + "groups": "group1", + "organization": "acme", + "pipeline": "pipeline-one", + "email": "emailvalue", + "email_verified": true, + "claim-with-delimiter": "foo-bar", + "non-string-claim": []string{ + "element1", + "element2", + }, + "non-string-claim2": 666, + }, + }, + { + name: "prefixGroupNames", + userIDKey: "", // not configured + userNameKey: "", // not configured + expectUserID: "subvalue", + expectUserName: "namevalue", + expectGroups: []string{"prefix-group1", "prefix-group2", "prefix-groupA", "prefix-groupB"}, + expectedEmailField: "emailvalue", + groupsPrefix: "prefix-", + token: map[string]interface{}{ + "sub": "subvalue", + "name": "namevalue", + "groups": []string{"group1", "group2", "groupA", "groupB"}, + "email": "emailvalue", + "email_verified": true, + }, + }, + { + name: "suffixGroupNames", + userIDKey: "", // not configured + userNameKey: "", // not configured + expectUserID: "subvalue", + expectUserName: "namevalue", + expectGroups: []string{"group1-suffix", "group2-suffix", "groupA-suffix", "groupB-suffix"}, + expectedEmailField: "emailvalue", + groupsSuffix: "-suffix", + token: map[string]interface{}{ + "sub": "subvalue", + "name": "namevalue", + "groups": []string{"group1", "group2", "groupA", "groupB"}, + "email": "emailvalue", + "email_verified": true, + }, + }, + { + name: "preAndSuffixGroupNames", + userIDKey: "", // not configured + userNameKey: "", // not configured + expectUserID: "subvalue", + expectUserName: "namevalue", + expectGroups: []string{"prefix-group1-suffix", "prefix-group2-suffix", "prefix-groupA-suffix", "prefix-groupB-suffix"}, + expectedEmailField: "emailvalue", + groupsPrefix: "prefix-", + groupsSuffix: "-suffix", + token: map[string]interface{}{ + "sub": "subvalue", + "name": "namevalue", + "groups": []string{"group1", "group2", "groupA", "groupB"}, + "email": "emailvalue", + "email_verified": true, + }, + }, + { + name: "filterGroupClaims", + userIDKey: "", // not configured + userNameKey: "", // not configured + groupsRegex: `^.*\d$`, + expectUserID: "subvalue", + expectUserName: "namevalue", + expectGroups: []string{"group1", "group2"}, + expectedEmailField: "emailvalue", + token: map[string]interface{}{ + "sub": "subvalue", + "name": "namevalue", + "groups": []string{"group1", "group2", "groupA", "groupB"}, + "email": "emailvalue", + "email_verified": true, + }, + }, + { + name: "filterGroupClaimsMap", + userIDKey: "", // not configured + userNameKey: "", // not configured + groupsRegex: `^.*\d$`, + expectUserID: "subvalue", + expectUserName: "namevalue", + expectGroups: []string{"group1", "group2"}, + expectedEmailField: "emailvalue", + token: map[string]interface{}{ + "sub": "subvalue", + "name": "namevalue", + "groups": []map[string]string{{"name": "group1"}, {"name": "group2"}, {"name": "groupA"}, {"name": "groupB"}}, + "email": "emailvalue", + "email_verified": true, + }, + }, } for _, tc := range tests { @@ -322,6 +519,10 @@ func TestHandleCallback(t *testing.T) { config.ClaimMapping.PreferredUsernameKey = tc.preferredUsernameKey config.ClaimMapping.EmailKey = tc.emailKey config.ClaimMapping.GroupsKey = tc.groupsKey + config.ClaimMutations.NewGroupFromClaims = tc.newGroupFromClaims + config.ClaimMutations.FilterGroupClaims.GroupsFilter = tc.groupsRegex + config.ClaimMutations.ModifyGroupNames.Prefix = tc.groupsPrefix + config.ClaimMutations.ModifyGroupNames.Suffix = tc.groupsSuffix conn, err := newConnector(config) if err != nil { @@ -428,6 +629,171 @@ func TestRefresh(t *testing.T) { } } +func TestTokenIdentity(t *testing.T) { + tokenTypeAccess := "urn:ietf:params:oauth:token-type:access_token" + tokenTypeID := "urn:ietf:params:oauth:token-type:id_token" + long2short := map[string]string{ + tokenTypeAccess: "access_token", + tokenTypeID: "id_token", + } + + tests := []struct { + name string + subjectType string + userInfo bool + expectError bool + }{ + { + name: "id_token", + subjectType: tokenTypeID, + }, { + name: "access_token", + subjectType: tokenTypeAccess, + expectError: true, + }, { + name: "id_token with user info", + subjectType: tokenTypeID, + userInfo: true, + }, { + name: "access_token with user info", + subjectType: tokenTypeAccess, + userInfo: true, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + ctx := context.Background() + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + testServer, err := setupServer(map[string]any{ + "sub": "subvalue", + "name": "namevalue", + }, true) + if err != nil { + t.Fatal("failed to setup test server", err) + } + conn, err := newConnector(Config{ + Issuer: testServer.URL, + Scopes: []string{"openid", "groups"}, + GetUserInfo: tc.userInfo, + }) + if err != nil { + t.Fatal("failed to create new connector", err) + } + + res, err := http.Get(testServer.URL + "/token") + if err != nil { + t.Fatal("failed to get initial token", err) + } + defer res.Body.Close() + var tokenResponse map[string]any + err = json.NewDecoder(res.Body).Decode(&tokenResponse) + if err != nil { + t.Fatal("failed to decode initial token", err) + } + + origToken := tokenResponse[long2short[tc.subjectType]].(string) + identity, err := conn.TokenIdentity(ctx, tc.subjectType, origToken) + if err != nil { + if tc.expectError { + return + } + t.Fatal("failed to get token identity", err) + } + + // assert identity + expectEquals(t, identity.UserID, "subvalue") + expectEquals(t, identity.Username, "namevalue") + }) + } +} + +func TestPromptType(t *testing.T) { + pointer := func(s string) *string { + return &s + } + + tests := []struct { + name string + promptType *string + res string + }{ + {name: "none", promptType: pointer("none"), res: "none"}, + {name: "provided empty string", promptType: pointer(""), res: ""}, + {name: "login", promptType: pointer("login"), res: "login"}, + {name: "consent", promptType: pointer("consent"), res: "consent"}, + {name: "default value", promptType: nil, res: "consent"}, + } + + testServer, err := setupServer(nil, true) + require.NoError(t, err) + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + conn, err := newConnector(Config{ + Issuer: testServer.URL, + Scopes: []string{"openid", "groups"}, + PromptType: tc.promptType, + }) + require.NoError(t, err) + + require.Equal(t, tc.res, conn.promptType) + }) + } +} + +func TestProviderOverride(t *testing.T) { + testServer, err := setupServer(map[string]any{ + "sub": "subvalue", + "name": "namevalue", + }, true) + if err != nil { + t.Fatal("failed to setup test server", err) + } + + t.Run("No override", func(t *testing.T) { + conn, err := newConnector(Config{ + Issuer: testServer.URL, + Scopes: []string{"openid", "groups"}, + }) + if err != nil { + t.Fatal("failed to create new connector", err) + } + + expAuth := fmt.Sprintf("%s/authorize", testServer.URL) + if conn.provider.Endpoint().AuthURL != expAuth { + t.Fatalf("unexpected auth URL: %s, expected: %s\n", conn.provider.Endpoint().AuthURL, expAuth) + } + + expToken := fmt.Sprintf("%s/token", testServer.URL) + if conn.provider.Endpoint().TokenURL != expToken { + t.Fatalf("unexpected token URL: %s, expected: %s\n", conn.provider.Endpoint().TokenURL, expToken) + } + }) + + t.Run("Override", func(t *testing.T) { + conn, err := newConnector(Config{ + Issuer: testServer.URL, + Scopes: []string{"openid", "groups"}, + ProviderDiscoveryOverrides: ProviderDiscoveryOverrides{TokenURL: "/test1", AuthURL: "/test2"}, + }) + if err != nil { + t.Fatal("failed to create new connector", err) + } + + expAuth := "/test2" + if conn.provider.Endpoint().AuthURL != expAuth { + t.Fatalf("unexpected auth URL: %s, expected: %s\n", conn.provider.Endpoint().AuthURL, expAuth) + } + + expToken := "/test1" + if conn.provider.Endpoint().TokenURL != expToken { + t.Fatalf("unexpected token URL: %s, expected: %s\n", conn.provider.Endpoint().TokenURL, expToken) + } + }) +} + func setupServer(tok map[string]interface{}, idTokenDesired bool) (*httptest.Server, error) { key, err := rsa.GenerateKey(rand.Reader, 1024) if err != nil { @@ -523,7 +889,7 @@ func newToken(key *jose.JSONWebKey, claims map[string]interface{}) (string, erro } func newConnector(config Config) (*oidcConnector, error) { - logger := logrus.New() + logger := slog.New(slog.DiscardHandler) conn, err := config.Open("id", logger) if err != nil { return nil, fmt.Errorf("unable to open: %v", err) diff --git a/connector/openshift/openshift.go b/connector/openshift/openshift.go index 81d2b35633..4519a85b6d 100644 --- a/connector/openshift/openshift.go +++ b/connector/openshift/openshift.go @@ -2,22 +2,18 @@ package openshift import ( "context" - "crypto/tls" - "crypto/x509" "encoding/json" "fmt" "io" - "net" + "log/slog" "net/http" - "os" "strings" - "time" "golang.org/x/oauth2" "github.com/dexidp/dex/connector" "github.com/dexidp/dex/pkg/groups" - "github.com/dexidp/dex/pkg/log" + "github.com/dexidp/dex/pkg/httpclient" "github.com/dexidp/dex/storage/kubernetes/k8sapi" ) @@ -48,7 +44,7 @@ type openshiftConnector struct { clientID string clientSecret string cancel context.CancelFunc - logger log.Logger + logger *slog.Logger httpClient *http.Client oauth2Config *oauth2.Config insecureCA bool @@ -66,8 +62,13 @@ type user struct { // Open returns a connector which can be used to login users through an upstream // OpenShift OAuth2 provider. -func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, err error) { - httpClient, err := newHTTPClient(c.InsecureCA, c.RootCA) +func (c *Config) Open(id string, logger *slog.Logger) (conn connector.Connector, err error) { + var rootCAs []string + if c.RootCA != "" { + rootCAs = append(rootCAs, c.RootCA) + } + + httpClient, err := httpclient.NewHTTPClient(rootCAs, c.InsecureCA) if err != nil { return nil, fmt.Errorf("failed to create HTTP client: %w", err) } @@ -77,13 +78,17 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e // OpenWithHTTPClient returns a connector which can be used to login users through an upstream // OpenShift OAuth2 provider. It provides the ability to inject a http.Client. -func (c *Config) OpenWithHTTPClient(id string, logger log.Logger, +func (c *Config) OpenWithHTTPClient(id string, logger *slog.Logger, httpClient *http.Client, ) (conn connector.Connector, err error) { ctx, cancel := context.WithCancel(context.Background()) + defer cancel() wellKnownURL := strings.TrimSuffix(c.Issuer, "/") + wellKnownURLPath req, err := http.NewRequest(http.MethodGet, wellKnownURL, nil) + if err != nil { + return nil, fmt.Errorf("failed to create a request to OpenShift endpoint %w", err) + } openshiftConnector := openshiftConnector{ apiURL: c.Issuer, @@ -91,7 +96,7 @@ func (c *Config) OpenWithHTTPClient(id string, logger log.Logger, clientID: c.ClientID, clientSecret: c.ClientSecret, insecureCA: c.InsecureCA, - logger: logger, + logger: logger.With(slog.Group("connector", "type", "openshift", "id", id)), redirectURI: c.RedirectURI, rootCA: c.RootCA, groups: c.Groups, @@ -105,14 +110,12 @@ func (c *Config) OpenWithHTTPClient(id string, logger log.Logger, resp, err := openshiftConnector.httpClient.Do(req.WithContext(ctx)) if err != nil { - cancel() return nil, fmt.Errorf("failed to query OpenShift endpoint %w", err) } defer resp.Body.Close() if err := json.NewDecoder(resp.Body).Decode(&metadata); err != nil { - cancel() return nil, fmt.Errorf("discovery through endpoint %s failed to decode body: %w", wellKnownURL, err) } @@ -262,36 +265,3 @@ func validateAllowedGroups(userGroups, allowedGroups []string) bool { return len(matchingGroups) != 0 } - -// newHTTPClient returns a new HTTP client -func newHTTPClient(insecureCA bool, rootCA string) (*http.Client, error) { - tlsConfig := tls.Config{} - if insecureCA { - tlsConfig = tls.Config{InsecureSkipVerify: true} - } else if rootCA != "" { - tlsConfig = tls.Config{RootCAs: x509.NewCertPool()} - rootCABytes, err := os.ReadFile(rootCA) - if err != nil { - return nil, fmt.Errorf("failed to read root-ca: %w", err) - } - if !tlsConfig.RootCAs.AppendCertsFromPEM(rootCABytes) { - return nil, fmt.Errorf("no certs found in root CA file %q", rootCA) - } - } - - return &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: &tlsConfig, - Proxy: http.ProxyFromEnvironment, - DialContext: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - DualStack: true, - }).DialContext, - MaxIdleConns: 100, - IdleConnTimeout: 90 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, - }, - }, nil -} diff --git a/connector/openshift/openshift_test.go b/connector/openshift/openshift_test.go index 6280b831de..ef86e59314 100644 --- a/connector/openshift/openshift_test.go +++ b/connector/openshift/openshift_test.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "log/slog" "net/http" "net/http/httptest" "net/url" @@ -11,10 +12,10 @@ import ( "testing" "time" - "github.com/sirupsen/logrus" "golang.org/x/oauth2" "github.com/dexidp/dex/connector" + "github.com/dexidp/dex/pkg/httpclient" "github.com/dexidp/dex/storage/kubernetes/k8sapi" ) @@ -36,7 +37,7 @@ func TestOpen(t *testing.T) { InsecureCA: true, } - logger := logrus.New() + logger := slog.New(slog.DiscardHandler) oconfig, err := c.Open("id", logger) @@ -70,7 +71,7 @@ func TestGetUser(t *testing.T) { _, err = http.NewRequest("GET", hostURL.String(), nil) expectNil(t, err) - h, err := newHTTPClient(true, "") + h, err := httpclient.NewHTTPClient(nil, true) expectNil(t, err) @@ -128,7 +129,7 @@ func TestVerifyGroup(t *testing.T) { _, err = http.NewRequest("GET", hostURL.String(), nil) expectNil(t, err) - h, err := newHTTPClient(true, "") + h, err := httpclient.NewHTTPClient(nil, true) expectNil(t, err) @@ -164,7 +165,7 @@ func TestCallbackIdentity(t *testing.T) { req, err := http.NewRequest("GET", hostURL.String(), nil) expectNil(t, err) - h, err := newHTTPClient(true, "") + h, err := httpclient.NewHTTPClient(nil, true) expectNil(t, err) @@ -198,7 +199,7 @@ func TestRefreshIdentity(t *testing.T) { }) defer s.Close() - h, err := newHTTPClient(true, "") + h, err := httpclient.NewHTTPClient(nil, true) expectNil(t, err) oc := openshiftConnector{apiURL: s.URL, httpClient: h, oauth2Config: &oauth2.Config{ @@ -237,7 +238,7 @@ func TestRefreshIdentityFailure(t *testing.T) { }) defer s.Close() - h, err := newHTTPClient(true, "") + h, err := httpclient.NewHTTPClient(nil, true) expectNil(t, err) oc := openshiftConnector{apiURL: s.URL, httpClient: h, oauth2Config: &oauth2.Config{ diff --git a/connector/saml/saml.go b/connector/saml/saml.go index 908ec703c9..3e44b477e3 100644 --- a/connector/saml/saml.go +++ b/connector/saml/saml.go @@ -8,6 +8,7 @@ import ( "encoding/pem" "encoding/xml" "fmt" + "log/slog" "os" "strings" "sync" @@ -21,10 +22,8 @@ import ( "github.com/dexidp/dex/connector" "github.com/dexidp/dex/pkg/groups" - "github.com/dexidp/dex/pkg/log" ) -// nolint const ( bindingRedirect = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" bindingPOST = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" @@ -120,11 +119,12 @@ func (c certStore) Certificates() (roots []*x509.Certificate, err error) { // Open validates the config and returns a connector. It does not actually // validate connectivity with the provider. -func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error) { +func (c *Config) Open(id string, logger *slog.Logger) (connector.Connector, error) { + logger = logger.With(slog.Group("connector", "type", "saml", "id", id)) return c.openConnector(logger) } -func (c *Config) openConnector(logger log.Logger) (*provider, error) { +func (c *Config) openConnector(logger *slog.Logger) (*provider, error) { requiredFields := []struct { name, val string }{ @@ -252,7 +252,7 @@ type provider struct { nameIDPolicyFormat string - logger log.Logger + logger *slog.Logger } func (p *provider) POSTData(s connector.Scopes, id string) (action, value string, err error) { @@ -292,7 +292,6 @@ func (p *provider) POSTData(s connector.Scopes, id string) (action, value string // * Verify signature on XML document (or verify sig on assertion elements). // * Verify various parts of the Assertion element. Conditions, audience, etc. // * Map the Assertion's attribute elements to user info. -// func (p *provider) HandlePOST(s connector.Scopes, samlResponse, inResponseTo string) (ident connector.Identity, err error) { rawResp, err := base64.StdEncoding.DecodeString(samlResponse) if err != nil { @@ -390,7 +389,7 @@ func (p *provider) HandlePOST(s connector.Scopes, samlResponse, inResponseTo str // Log the actual attributes we got back from the server. This helps debug // configuration errors on the server side, where the SAML server doesn't // send us the correct attributes. - p.logger.Infof("parsed and verified saml response attributes %s", attributes) + p.logger.Info("parsed and verified saml response attributes", "attributes", attributes) // Grab the email. if ident.Email, _ = attributes.get(p.emailAttr); ident.Email == "" { @@ -468,7 +467,7 @@ func (p *provider) validateStatus(status *status) error { if statusMessage != nil && statusMessage.Value != "" { errorMessage += " -> " + statusMessage.Value } - return fmt.Errorf(errorMessage) + return errors.New(errorMessage) } return nil } @@ -531,7 +530,7 @@ func (p *provider) validateSubject(subject *subject, inResponseTo string) error return fmt.Errorf("failed to validate subject confirmation: %v", errs) } -// validationConditions ensures that dex is the intended audience +// validateConditions ensures that dex is the intended audience // for the request, and not another service provider. // // See: https://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf @@ -598,6 +597,9 @@ func verifyResponseSig(validator *dsig.ValidationContext, data []byte) (signed [ } response := doc.Root() + if response == nil { + return nil, false, fmt.Errorf("parse document: empty root") + } transformedResponse, err := validator.Validate(response) if err == nil { // Root element is verified, return it. @@ -610,7 +612,7 @@ func verifyResponseSig(validator *dsig.ValidationContext, data []byte) (signed [ // // TODO: Only select from child elements of the root. assertion, err := etreeutils.NSSelectOne(response, "urn:oasis:names:tc:SAML:2.0:assertion", "Assertion") - if err != nil { + if err != nil || assertion == nil { return nil, false, fmt.Errorf("response does not contain an Assertion element") } transformedAssertion, err := validator.Validate(assertion) diff --git a/connector/saml/saml_test.go b/connector/saml/saml_test.go index 95d513ed19..03e891fe64 100644 --- a/connector/saml/saml_test.go +++ b/connector/saml/saml_test.go @@ -5,6 +5,7 @@ import ( "encoding/base64" "encoding/pem" "errors" + "log/slog" "os" "sort" "testing" @@ -12,7 +13,6 @@ import ( "github.com/kylelemons/godebug/pretty" dsig "github.com/russellhaering/goxmldsig" - "github.com/sirupsen/logrus" "github.com/dexidp/dex/connector" ) @@ -24,19 +24,18 @@ import ( // To add a new test, define a new, unsigned SAML 2.0 response that exercises some // case, then sign it using the "testdata/gen.sh" script. // -// cp testdata/good-resp.tmpl testdata/( testname ).tmpl -// vim ( testname ).tmpl # Modify your template for your test case. -// vim testdata/gen.sh # Add a xmlsec1 command to the generation script. -// ./testdata/gen.sh # Sign your template. +// cp testdata/good-resp.tmpl testdata/( testname ).tmpl +// vim ( testname ).tmpl # Modify your template for your test case. +// vim testdata/gen.sh # Add a xmlsec1 command to the generation script. +// ./testdata/gen.sh # Sign your template. // // To install xmlsec1 on Fedora run: // -// sudo dnf install xmlsec1 xmlsec1-openssl +// sudo dnf install xmlsec1 xmlsec1-openssl // // On mac: // -// brew install Libxmlsec1 -// +// brew install Libxmlsec1 type responseTest struct { // CA file and XML file of the response. caFile string @@ -421,7 +420,7 @@ func (r responseTest) run(t *testing.T) { t.Fatalf("parse test time: %v", err) } - conn, err := c.openConnector(logrus.New()) + conn, err := c.openConnector(slog.New(slog.DiscardHandler)) if err != nil { t.Fatal(err) } @@ -455,7 +454,7 @@ func (r responseTest) run(t *testing.T) { } func TestConfigCAData(t *testing.T) { - logger := logrus.New() + logger := slog.New(slog.DiscardHandler) validPEM, err := os.ReadFile("testdata/ca.crt") if err != nil { t.Fatal(err) diff --git a/docker-compose.test.yaml b/docker-compose.test.yaml index 46dfd84c4d..933ff80164 100644 --- a/docker-compose.test.yaml +++ b/docker-compose.test.yaml @@ -11,8 +11,8 @@ services: LDAP_TLS: "true" LDAP_TLS_VERIFY_CLIENT: try ports: - - 389:389 - - 636:636 + - 3890:389 + - 6360:636 volumes: - ./connector/ldap/testdata/certs:/container/service/slapd/assets/certs - ./connector/ldap/testdata/schema.ldif:/container/service/slapd/assets/config/bootstrap/ldif/99-schema.ldif diff --git a/docs/enhancements/token-exchange-2023-02-03-#2812.md b/docs/enhancements/token-exchange-2023-02-03-#2812.md new file mode 100644 index 0000000000..f9f556d26e --- /dev/null +++ b/docs/enhancements/token-exchange-2023-02-03-#2812.md @@ -0,0 +1,175 @@ +# Dex Enhancement Proposal (DEP) 2812 - 2023-02-03 - Token Exchange + +## Table of Contents + +- [Summary](#summary) +- [Motivation](#motivation) + - [Goals/Pain](#goals) + - [Non-Goals](#non-goals) +- [Proposal](#proposal) + - [User Experience](#user-experience) + - [Implementation Details/Notes/Constraints](#implementation-detailsnotesconstraints) + - [Risks and Mitigations](#risks-and-mitigations) + - [Alternatives](#alternatives) +- [Future Improvements](#future-improvements) + +## Summary + +[RFC 8693] specifies a new OAuth2 `grant_type` of `urn:ietf:params:oauth:grant-type:token-exchange`. +Using this grant type, when clients start an authentication flow with Dex, +in lieu of being redirected to their upstream IDP for authentication on demand, +clients can present an independently obtained, valid token from their IDP to Dex. +This is primarily useful in fully automated environments with job/machine identities, +where there is no human in the loop to handle browser-based login flows. +This DEP proposes to implement the new grant type for Dex. + +[RFC 8693]: https://www.rfc-editor.org/rfc/rfc8693.html + +## Context + +- [#1668 Question: non-web based clients?] + was closed with no real resolution +- [#1484 Token exchange for external tokens] + mentions that Keycloak has a similar capability +- [#2657 Get OIDC token issued by Dex using a token issued by one of the connectors] + is similar to the previous issue, but this time links to the new (January 2020) [RFC 8693]. + +I believe the context for all of these are similar: +a downstream project using Dex as its only IDP wants to grant access to programmatic clients +without issuing long lived API tokens. + +Examples of downstream issues: + +- [argoproj/argo-cd#11632 ArgoCD SSO login via Azure AD Auth using OIDC not work for cli sso login] + +Other related Dex issues: + +- [#2450 Non-OIDC JWT Connector] is a functionally similar request, but expanded to arbitrary JWTs +- [#1225 GitHub Non-Web application flow support] also asks for an exchange, but for an opaque GitHub PAT + +More broadly, this fits into recent movements to issue machine identities: + +- [GCP Service Identity](https://cloud.google.com/run/docs/securing/service-identity) +- [AWS Execution Role](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html) +- [GitHub Actions OIDC](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect) +- [CircleCI OIDC](https://circleci.com/docs/openid-connect-tokens/) +- [Kubernetes Service Accounts](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) +- [SPIFFE](https://spiffe.io/) + +and granting access to resources based on trusting federated identities: + +- [GCP Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation) +- [AWS STS AssumeRoleWithWebIdentity](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html) + +[#1484 Token exchange for external tokens]: https://github.com/dexidp/dex/issues/1484 +[#1668 Question: non-web based clients?]: https://github.com/dexidp/dex/issues/1668 +[#2657 Get OIDC token issued by Dex using a token issued by one of the connectors]: https://github.com/dexidp/dex/issues/2657 +[argoproj/argo-cd#11632 ArgoCD SSO login via Azure AD Auth using OIDC not work for cli sso login]: https://github.com/argoproj/argo-cd/issues/11632 +[#2450 Non-OIDC JWT Connector]: https://github.com/dexidp/dex/issues/2450 +[#1225 GitHub Non-Web application flow support]: https://github.com/dexidp/dex/issues/1225 + +An initial attempt is at [#2806](https://github.com/dexidp/dex/pull/2806) + +## Motivation + +### Goals/Pain + +The goal is to allow programmatic access to Dex-protected resources +without the use of static/long-lived secret tokens (API keys, username/password) +or web-based redirect flows. +Such scenarios are common in CI/CD workflows, +and in general automation of common tasks. + +### Non-goals + +- Work will be scoped to just the OIDC connector +- [RFC 8693 Section 2.1.1. Relationship between Resource, Audience, and Scope] + details more complex authorization checks based on targeted resources. + This is considered out of scope. + +[RFC 8693 Section 2.1.1. Relationship between Resource, Audience, and Scope]: https://www.rfc-editor.org/rfc/rfc8693.html#name-relationship-between-resour + +## Proposal + +### User Experience + +Clients can make `POST` requests with `application/x-www-form-urlencoded` +parameters as specified by [RFC 8693] to Dex's `/token` endpoint. +If successful, an access token will be returned, +allowing direct authentication with Dex. +No refresh tokens will be issued, +perform a new exchange (possibly with refreshed upstream tokens) to obtain a new access token. + +The request parameters from [RFC 8693 Section 2.1](https://www.rfc-editor.org/rfc/rfc8693.html#name-request): + +- `grant_type`: REQUIRED - `urn:ietf:params:oauth:grant-type:token-exchange` +- `resource`: OPTIONAL - the `audience` in the issued Dex token +- `audience`: REQUIRED (RFC OPTIONAL) - the connector to verify the provided token against +- `scope`: OPTIONAL - the `scope` in the issued Dex token +- `requested_token_type`: OPTIONAL - one of `urn:ietf:params:oauth:token-type:access_token` or `urn:ietf:params:oauth:token-type:id_token`, defaulting to access token +- `subject_token`: REQUIRED - the token issued by the upstream IDP +- `subject_token_type`: REQUIRED - `urn:ietf:params:oauth:token-type:id_token` or `urn:ietf:params:oauth:token-type:access_token` if `getUserInfo` is `true`. +- `actor_token`: OPTIONAL - unused +- `actor_token_type`: OPTIONAL - unused + +The response parameters from [RFC 8693 Section 2.2](https://www.rfc-editor.org/rfc/rfc8693.html#name-response): + +- `access_token`: the issued token, the field is called `access_token` for legacy reasons +- `issued_token_type`: the actual type of the issued token +- `token_type`: the value `Bearer` +- `expires_in`: validity lifetime in seconds +- `scope`: the requested scope +- `refresh_token`: unused + +The connector only needs to be configured with an issuer, +no client ID / client secrets are necessary + +```yaml +connectors: +- type: oidc + id: my-platform + name: My Platform + config: + issuer: https://oidc.my-platform.example/ +``` + +We expose a global and connector setting, +`allowedGrantTypes: []string` defaulting to all implemented types. + +### Implementation Details/Notes/Constraints + +- Connectors expose a new interface `TokenIdentity` that will verify the given token and return the associated identity. + A Dex access/id token is then minted for the given identity. + +- `actor_token` and `actor_token_type` are "MUST ... if the actor token is present, + also perform the appropriate validation procedures for its indicated token type". + We will ignore these fields for the initial implementation. + + +### Risks and Mitigations + +With token exchanges (sometimes known as identity impersonation), +is they allow for easier lateral movement if an attacker gains access to an upstream token. +We limit the potential impact by not issuing refresh tokens, preventing persistent access. +Combined with short token lifetimes, it should limit the period of time between authentication to upstream IDPs. +Additionally, a new `allowedGrantTypes` would allow for disabling exchanges if the functionality isn't needed. + +### Alternatives + +- Continue to use static keys - + this is a secret management nightmare + and quite painful when client storage of keys is [breached](https://circleci.com/blog/january-4-2023-security-alert/) + +## Future Improvements + +- Other connectors may wish to implement the same capability under Oauth +- The password connector could be switch to support this new endpoint, submitting passwords as access tokens, + allowing for multiple password connectors to be configured +- The `audience` field could be made optional if there is a single connector or the id token is inspected for issuer url +- The `actor_token` and `actor_token_type` can be checked / validated if a suitable use case is determined. +- A policy language like [cel] or [rego] as mentioned on [#1635 Connector Middleware] + would allow for stronger assertions of the provided identity against requested resource access. + +[cel]: https://github.com/google/cel-go +[rego]: https://www.openpolicyagent.org/docs/latest/policy-language/ +[#1635 Connector Middleware]: https://github.com/dexidp/dex/issues/1635 diff --git a/examples/config-dev.yaml b/examples/config-dev.yaml index bf11570a4e..147597a265 100644 --- a/examples/config-dev.yaml +++ b/examples/config-dev.yaml @@ -52,6 +52,16 @@ web: # https: 127.0.0.1:5554 # tlsCert: /etc/dex/tls.crt # tlsKey: /etc/dex/tls.key + # headers: + # X-Frame-Options: "DENY" + # X-Content-Type-Options: "nosniff" + # X-XSS-Protection: "1; mode=block" + # Content-Security-Policy: "default-src 'self'" + # Strict-Transport-Security: "max-age=31536000; includeSubDomains" + # clientRemoteIP: + # header: X-Forwarded-For + # trustedProxies: + # - 10.0.0.0/8 # Configuration for dex appearance # frontend: @@ -91,7 +101,16 @@ telemetry: # Default values shown below # oauth2: - # use ["code", "token", "id_token"] to enable implicit flow for web-only clients + # grantTypes determines the allowed set of authorization flows. +# grantTypes: +# - "authorization_code" +# - "refresh_token" +# - "implicit" +# - "password" +# - "urn:ietf:params:oauth:grant-type:device_code" +# - "urn:ietf:params:oauth:grant-type:token-exchange" + # responseTypes determines the allowed response contents of a successful authorization flow. + # use ["code", "token", "id_token"] to enable implicit flow for web-only clients. # responseTypes: [ "code" ] # also allowed are "token" and "id_token" # By default, Dex will ask for approval to share data with application # (approval for sharing data from connected IdP to Dex is separate process on IdP) diff --git a/examples/example-app/main.go b/examples/example-app/main.go index 451bea5b46..af56670402 100644 --- a/examples/example-app/main.go +++ b/examples/example-app/main.go @@ -3,8 +3,11 @@ package main import ( "bytes" "context" + "crypto/rand" + "crypto/sha256" "crypto/tls" "crypto/x509" + "encoding/base64" "encoding/json" "errors" "fmt" @@ -24,9 +27,20 @@ import ( const exampleAppState = "I wish to wash my irish wristwatch" +var ( + codeVerifier string + codeChallenge string +) + +func init() { + codeVerifier = generateCodeVerifier() + codeChallenge = generateCodeChallenge(codeVerifier) +} + type app struct { clientID string clientSecret string + pkce bool redirectURI string verifier *oidc.IDTokenVerifier @@ -193,6 +207,7 @@ func cmd() *cobra.Command { } c.Flags().StringVar(&a.clientID, "client-id", "example-app", "OAuth2 client ID of this application.") c.Flags().StringVar(&a.clientSecret, "client-secret", "ZXhhbXBsZS1hcHAtc2VjcmV0", "OAuth2 client secret of this application.") + c.Flags().BoolVar(&a.pkce, "pkce", true, "Use PKCE flow for the code exchange.") c.Flags().StringVar(&a.redirectURI, "redirect-uri", "http://127.0.0.1:5555/callback", "Callback URL for OAuth2 responses.") c.Flags().StringVar(&issuerURL, "issuer", "http://127.0.0.1:5556/dex", "URL of the OpenID Connect issuer.") c.Flags().StringVar(&listen, "listen", "http://127.0.0.1:5555", "HTTP(S) address to listen at.") @@ -243,14 +258,22 @@ func (a *app) handleLogin(w http.ResponseWriter, r *http.Request) { authCodeURL := "" scopes = append(scopes, "openid", "profile", "email") - if r.FormValue("offline_access") != "yes" { - authCodeURL = a.oauth2Config(scopes).AuthCodeURL(exampleAppState) - } else if a.offlineAsScope { + + var authCodeOptions []oauth2.AuthCodeOption + + if a.pkce { + authCodeOptions = append(authCodeOptions, oauth2.SetAuthURLParam("code_challenge", codeChallenge)) + authCodeOptions = append(authCodeOptions, oauth2.SetAuthURLParam("code_challenge_method", "S256")) + } + + a.oauth2Config(scopes) + if r.FormValue("offline_access") == "yes" { + authCodeOptions = append(authCodeOptions, oauth2.AccessTypeOffline) + } + if a.offlineAsScope { scopes = append(scopes, "offline_access") - authCodeURL = a.oauth2Config(scopes).AuthCodeURL(exampleAppState) - } else { - authCodeURL = a.oauth2Config(scopes).AuthCodeURL(exampleAppState, oauth2.AccessTypeOffline) } + authCodeURL = a.oauth2Config(scopes).AuthCodeURL(exampleAppState, authCodeOptions...) if connectorID != "" { authCodeURL = authCodeURL + "&connector_id=" + connectorID } @@ -282,7 +305,13 @@ func (a *app) handleCallback(w http.ResponseWriter, r *http.Request) { http.Error(w, fmt.Sprintf("expected state %q got %q", exampleAppState, state), http.StatusBadRequest) return } - token, err = oauth2Config.Exchange(ctx, code) + + var authCodeOptions []oauth2.AuthCodeOption + if a.pkce { + authCodeOptions = append(authCodeOptions, oauth2.SetAuthURLParam("code_verifier", codeVerifier)) + } + + token, err = oauth2Config.Exchange(ctx, code, authCodeOptions...) case http.MethodPost: // Form request from frontend to refresh a token. refresh := r.FormValue("refresh_token") @@ -337,3 +366,16 @@ func (a *app) handleCallback(w http.ResponseWriter, r *http.Request) { renderToken(w, a.redirectURI, rawIDToken, accessToken, token.RefreshToken, buff.String()) } + +func generateCodeVerifier() string { + bytes := make([]byte, 64) // 86 symbols Base64URL + if _, err := rand.Read(bytes); err != nil { + log.Fatalf("rand.Read error: %v", err) + } + return base64.RawURLEncoding.EncodeToString(bytes) +} + +func generateCodeChallenge(verifier string) string { + hash := sha256.Sum256([]byte(verifier)) + return base64.RawURLEncoding.EncodeToString(hash[:]) +} diff --git a/examples/example-app/templates.go b/examples/example-app/templates.go index a9425ead27..7107eb8739 100644 --- a/examples/example-app/templates.go +++ b/examples/example-app/templates.go @@ -6,38 +6,225 @@ import ( "net/http" ) +const css = ` + body { + font-family: Arial, sans-serif; + background-color: #f2f2f2; + margin: 0; + } + + .header { + text-align: center; + margin-bottom: 20px; + } + + .dex { + font-size: 2em; + font-weight: bold; + color: #3F9FD8; /* Main color */ + } + + .example-app { + font-size: 1em; + color: #EF4B5C; /* Secondary color */ + } + + .form-instructions { + text-align: center; + margin-bottom: 15px; + font-size: 1em; + color: #555; + } + + hr { + border: none; + border-top: 1px solid #ccc; + margin-top: 10px; + margin-bottom: 20px; + } + + label { + flex: 1; + font-weight: bold; + color: #333; + } + + p { + margin-bottom: 15px; + display: flex; + align-items: center; + } + + input[type="text"] { + flex: 2; + padding: 8px; + border: 1px solid #ccc; + border-radius: 4px; + outline: none; + } + + input[type="checkbox"] { + margin-left: 10px; + transform: scale(1.2); + } + + .back-button { + display: inline-block; + padding: 8px 16px; + background-color: #EF4B5C; /* Secondary color */ + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 12px; + text-decoration: none; + transition: background-color 0.3s ease, transform 0.2s ease; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + position: fixed; + right: 20px; + bottom: 20px; + } + + .back-button:hover { + background-color: #C43B4B; /* Darker shade of secondary color */ + } + + .token-block { + background-color: #fff; + padding: 10px 15px; + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + margin-bottom: 15px; + word-wrap: break-word; + display: flex; + flex-direction: column; + gap: 5px; + position: relative; + } + + .token-title { + font-weight: bold; + display: flex; + justify-content: space-between; + align-items: center; + } + + .token-title a { + font-size: 0.9em; + text-decoration: none; + color: #3F9FD8; /* Main color */ + } + + .token-title a:hover { + text-decoration: underline; + } + + .token-code { + overflow-wrap: break-word; + word-break: break-all; + white-space: normal; + } + + pre { + white-space: pre-wrap; + background-color: #f9f9f9; + padding: 8px; + border-radius: 4px; + border: 1px solid #ddd; + margin: 0; + font-family: 'Courier New', Courier, monospace; + overflow-x: auto; + font-size: 0.9em; + position: relative; + margin-top: 5px; + } + + pre .key { + color: #c00; + } + + pre .string { + color: #080; + } + + pre .number { + color: #00f; + } +` + var indexTmpl = template.Must(template.New("index.html").Parse(` - + + + + + + Example App - Login - - + + +
+
Dex
+
Example App
+
-

- - -

-

- - -

-

- - -

-

- - -

-

- -

+
+ If needed, customize your login settings below, then click Login to proceed. +
+
+

+ + +

+

+ + +

+

+ + +

+

+ + +

+

+ +

- + `)) func renderIndex(w http.ResponseWriter) { @@ -53,30 +240,116 @@ type tokenTmplData struct { } var tokenTmpl = template.Must(template.New("token.html").Parse(` - + + + + + + Tokens - - -

ID Token:

{{ .IDToken }}

-

Access Token:

{{ .AccessToken }}

-

Claims:

{{ .Claims }}

- {{ if .RefreshToken }} -

Refresh Token:

{{ .RefreshToken }}

-
- - -
- {{ end }} - + + + {{ if .IDToken }} +
+
+ ID Token: + Decode on jwt.io +
+
{{ .IDToken }}
+
+ {{ end }} + + {{ if .AccessToken }} +
+
+ Access Token: + Decode on jwt.io +
+
{{ .AccessToken }}
+
+ {{ end }} + + {{ if .Claims }} +
+
Claims:
+
{{ .Claims }}
+
+ {{ end }} + + {{ if .RefreshToken }} +
+
Refresh Token:
+
{{ .RefreshToken }}
+
+ + +
+
+ {{ end }} + + Back to Home + + + `)) diff --git a/examples/go.mod b/examples/go.mod index d66c118a7f..de09f42cd1 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -1,25 +1,22 @@ module github.com/dexidp/dex/examples -go 1.17 +go 1.24.0 require ( - github.com/coreos/go-oidc/v3 v3.1.0 - github.com/dexidp/dex/api/v2 v2.0.0 - github.com/spf13/cobra v1.3.0 - golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 - google.golang.org/grpc v1.43.0 + github.com/coreos/go-oidc/v3 v3.16.0 + github.com/dexidp/dex/api/v2 v2.4.0 + github.com/spf13/cobra v1.10.2 + golang.org/x/oauth2 v0.34.0 + google.golang.org/grpc v1.77.0 ) require ( - github.com/golang/protobuf v1.5.2 // indirect - github.com/inconshreveable/mousetrap v1.0.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect - golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce // indirect - golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d // indirect - golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect - golang.org/x/text v0.3.7 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220114231437-d2e6a121cae0 // indirect - google.golang.org/protobuf v1.27.1 // indirect - gopkg.in/square/go-jose.v2 v2.6.0 // indirect + github.com/go-jose/go-jose/v4 v4.1.3 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/spf13/pflag v1.0.9 // indirect + golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 // indirect + golang.org/x/sys v0.37.0 // indirect + golang.org/x/text v0.30.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect + google.golang.org/protobuf v1.36.10 // indirect ) diff --git a/examples/go.sum b/examples/go.sum index 7907afde92..fadded371f 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -1,788 +1,54 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/coreos/go-oidc/v3 v3.1.0 h1:6avEvcdvTa1qYsOZ6I5PRkSYHzpTNWgKYmaJfaYbrRw= -github.com/coreos/go-oidc/v3 v3.1.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dexidp/dex/api/v2 v2.0.0 h1:bvge1sRmzVzWPWp4WlMzS04lcNQA+jFzHqKV3066bRw= -github.com/dexidp/dex/api/v2 v2.0.0/go.mod h1:k5arBJT1QYvpsEY3sEd0NXJp3hKWKuUUfzJ3BlcqPdM= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= -github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= -github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= -github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= -github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= -github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/coreos/go-oidc/v3 v3.16.0 h1:qRQUCFstKpXwmEjDQTIbyY/5jF00+asXzSkmkoa/mow= +github.com/coreos/go-oidc/v3 v3.16.0/go.mod h1:wqPbKFrVnE90vty060SB40FCJ8fTHTxSwyXJqZH+sI8= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/dexidp/dex/api/v2 v2.4.0 h1:gNba7n6BKVp8X4Jp24cxYn5rIIGhM6kDOXcZoL6tr9A= +github.com/dexidp/dex/api/v2 v2.4.0/go.mod h1:/p550ADvFFh7K95VmhUD+jgm15VdaNnab9td8DHOpyI= +github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= +github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v1.3.0 h1:R7cSvGu+Vv+qX0gW5R/85dx2kmmJT5z5NM8ifdYjdn0= -github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce h1:Roh6XWxHFKrPgC/EQhVubSAGQ6Ozk6IdxHSzt1mR0EI= -golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d h1:1n1fc535VhN8SYtD4cDUyNlfpAF2ROMM9+11equK3hs= -golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220114231437-d2e6a121cae0 h1:aCsSLXylHWFno0r4S3joLpiaWayvqd2Mn4iSvx4WZZc= -google.golang.org/genproto v0.0.0-20220114231437-d2e6a121cae0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.43.0 h1:Eeu7bZtDZ2DpRCsLhUlcrLnvYaMK1Gz86a+hMVvELmM= -google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -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.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= +github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= +golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= +golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= +golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= +google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= 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= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= -gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/examples/grpc-client/README.md b/examples/grpc-client/README.md index 59629e0590..6a78df9199 100644 --- a/examples/grpc-client/README.md +++ b/examples/grpc-client/README.md @@ -50,6 +50,9 @@ Running the gRPC client will cause the following API calls to be made to the ser 2. ListPasswords 3. VerifyPassword 4. DeletePassword +5. CreateClient +6. ListClients +7. DeleteClient ## Cleaning up diff --git a/examples/grpc-client/client.go b/examples/grpc-client/client.go index fb8d4aaf06..7bbbac6494 100644 --- a/examples/grpc-client/client.go +++ b/examples/grpc-client/client.go @@ -58,7 +58,7 @@ func createPassword(cli api.DexClient) error { // Create password. if resp, err := cli.CreatePassword(context.TODO(), createReq); err != nil || resp.AlreadyExists { - if resp != nil && resp.AlreadyExists { + if resp != nil && resp.AlreadyExists { return fmt.Errorf("Password %s already exists", createReq.Password.Email) } return fmt.Errorf("failed to create password: %v", err) @@ -125,6 +125,57 @@ func createPassword(cli api.DexClient) error { return nil } +func createAndListClients(cli api.DexClient) error { + client := &api.Client{ + Id: "example-client", + Secret: "example-secret", + RedirectUris: []string{"http://localhost:8080/callback"}, + TrustedPeers: []string{}, + Public: false, + Name: "Example Client", + LogoUrl: "http://example.com/logo.png", + } + + createReq := &api.CreateClientReq{ + Client: client, + } + + if resp, err := cli.CreateClient(context.TODO(), createReq); err != nil || resp.AlreadyExists { + if resp != nil && resp.AlreadyExists { + log.Printf("Client %s already exists", createReq.Client.Id) + } else { + return fmt.Errorf("failed to create client: %v", err) + } + } else { + log.Printf("Created client with ID %s", createReq.Client.Id) + } + + listResp, err := cli.ListClients(context.TODO(), &api.ListClientReq{}) + if err != nil { + return fmt.Errorf("failed to list clients: %v", err) + } + + log.Print("Listing Clients:\n") + for _, client := range listResp.Clients { + log.Printf("ID: %s, Name: %s, Public: %t, RedirectURIs: %v", + client.Id, client.Name, client.Public, client.RedirectUris) + } + + deleteReq := &api.DeleteClientReq{ + Id: client.Id, + } + + if resp, err := cli.DeleteClient(context.TODO(), deleteReq); err != nil || resp.NotFound { + if resp != nil && resp.NotFound { + return fmt.Errorf("Client %s not found", deleteReq.Id) + } + return fmt.Errorf("failed to delete client: %v", err) + } + log.Printf("Deleted client with ID %s", deleteReq.Id) + + return nil +} + func main() { caCrt := flag.String("ca-crt", "", "CA certificate") clientCrt := flag.String("client-crt", "", "Client certificate") @@ -143,4 +194,8 @@ func main() { if err := createPassword(client); err != nil { log.Fatalf("testPassword failed: %v", err) } + + if err := createAndListClients(client); err != nil { + log.Fatalf("testClients failed: %v", err) + } } diff --git a/examples/k8s/dex.yaml b/examples/k8s/dex.yaml index 89ac40b223..c8d8394401 100644 --- a/examples/k8s/dex.yaml +++ b/examples/k8s/dex.yaml @@ -23,7 +23,7 @@ spec: spec: serviceAccountName: dex # This is created below containers: - - image: ghcr.io/dexidp/dex:v2.30.0 + - image: ghcr.io/dexidp/dex:v2.32.0 name: dex command: ["/usr/local/bin/dex", "serve", "/etc/dex/cfg/config.yaml"] diff --git a/flake.lock b/flake.lock index b67b61d98b..302d0832f1 100644 --- a/flake.lock +++ b/flake.lock @@ -1,39 +1,252 @@ { "nodes": { - "flake-utils": { + "cachix": { + "inputs": { + "devenv": [ + "devenv" + ], + "flake-compat": [ + "devenv" + ], + "git-hooks": [ + "devenv", + "git-hooks" + ], + "nixpkgs": [ + "devenv", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1748883665, + "narHash": "sha256-R0W7uAg+BLoHjMRMQ8+oiSbTq8nkGz5RDpQ+ZfxxP3A=", + "owner": "cachix", + "repo": "cachix", + "rev": "f707778d902af4d62d8dd92c269f8e70de09acbe", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "latest", + "repo": "cachix", + "type": "github" + } + }, + "devenv": { + "inputs": { + "cachix": "cachix", + "flake-compat": "flake-compat", + "git-hooks": "git-hooks", + "nix": "nix", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1755355634, + "narHash": "sha256-3UNeb5pBLHtTyYIkzF/3+2YlAKf6OuWQYUQO+qmInA4=", + "owner": "cachix", + "repo": "devenv", + "rev": "85e78cbe26467a2c23c9d34869235740132d749f", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1747046372, + "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "devenv", + "nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1733312601, + "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1754487366, + "narHash": "sha256-pHYj8gUBapuUzKV/kN/tR3Zvqc7o6gdFB9XKXIp1SQ8=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "af66ad14b28a127c5c0f3bbb298218fc63528a18", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "git-hooks": { + "inputs": { + "flake-compat": [ + "devenv", + "flake-compat" + ], + "gitignore": "gitignore", + "nixpkgs": [ + "devenv", + "nixpkgs" + ] + }, "locked": { - "lastModified": 1659877975, - "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", + "lastModified": 1750779888, + "narHash": "sha256-wibppH3g/E2lxU43ZQHC5yA/7kIKLGxVEnsnVK1BtRg=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "16ec914f6fb6f599ce988427d9d94efddf25fe6d", "type": "github" }, "original": { - "owner": "numtide", - "repo": "flake-utils", + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "devenv", + "git-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "nix": { + "inputs": { + "flake-compat": [ + "devenv", + "flake-compat" + ], + "flake-parts": "flake-parts", + "git-hooks-nix": [ + "devenv", + "git-hooks" + ], + "nixpkgs": [ + "devenv", + "nixpkgs" + ], + "nixpkgs-23-11": [ + "devenv" + ], + "nixpkgs-regression": [ + "devenv" + ] + }, + "locked": { + "lastModified": 1755029779, + "narHash": "sha256-3+GHIYGg4U9XKUN4rg473frIVNn8YD06bjwxKS1IPrU=", + "owner": "cachix", + "repo": "nix", + "rev": "b0972b0eee6726081d10b1199f54de6d2917f861", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "devenv-2.30", + "repo": "nix", "type": "github" } }, "nixpkgs": { "locked": { - "lastModified": 1662019588, - "narHash": "sha256-oPEjHKGGVbBXqwwL+UjsveJzghWiWV0n9ogo1X6l4cw=", + "lastModified": 1750441195, + "narHash": "sha256-yke+pm+MdgRb6c0dPt8MgDhv7fcBbdjmv1ZceNTyzKg=", + "owner": "cachix", + "repo": "devenv-nixpkgs", + "rev": "0ceffe312871b443929ff3006960d29b120dc627", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "rolling", + "repo": "devenv-nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1753579242, + "narHash": "sha256-zvaMGVn14/Zz8hnp4VWT9xVnhc8vuL3TStRqwk22biA=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "0f36c44e01a6129be94e3ade315a5883f0228a6e", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1755268003, + "narHash": "sha256-nNaeJjo861wFR0tjHDyCnHs1rbRtrMgxAKMoig9Sj/w=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "2da64a81275b68fdad38af669afeda43d401e94b", + "rev": "32f313e49e42f715491e1ea7b306a87c16fe0388", "type": "github" }, "original": { - "id": "nixpkgs", - "ref": "nixos-unstable", - "type": "indirect" + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" } }, "root": { "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" + "devenv": "devenv", + "flake-parts": "flake-parts_2", + "nixpkgs": "nixpkgs_2" } } }, diff --git a/flake.nix b/flake.nix index 155ebf99e3..214bf2337f 100644 --- a/flake.nix +++ b/flake.nix @@ -1,27 +1,56 @@ { - description = "OpenID Connect (OIDC) identity and OAuth 2.0 provider with pluggable connectors"; - inputs = { - nixpkgs.url = "nixpkgs/nixos-unstable"; - flake-utils.url = "github:numtide/flake-utils"; + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + flake-parts.url = "github:hercules-ci/flake-parts"; + devenv.url = "github:cachix/devenv"; }; - outputs = { self, nixpkgs, flake-utils, ... }: - flake-utils.lib.eachDefaultSystem ( - system: - let - pkgs = nixpkgs.legacyPackages.${system}; - buildDeps = with pkgs; [ git go_1_19 gnumake ]; - devDeps = with pkgs; - buildDeps ++ [ - golangci-lint - gotestsum - protobuf - protoc-gen-go - protoc-gen-go-grpc - kind - ]; - in - { devShell = pkgs.mkShell { buildInputs = devDeps; }; } - ); + outputs = + inputs@{ flake-parts, ... }: + flake-parts.lib.mkFlake { inherit inputs; } { + imports = [ + inputs.devenv.flakeModule + ]; + + systems = [ + "x86_64-linux" + "x86_64-darwin" + "aarch64-darwin" + "aarch64-linux" + ]; + + perSystem = + { pkgs, ... }: + rec { + devenv.shells = { + default = { + languages = { + go = { + enable = true; + package = pkgs.go_1_25; + }; + }; + + packages = with pkgs; [ + gnumake + + # golangci-lint + (golangci-lint.override (o: { + buildGoModule = pkgs.buildGo125Module; + })) + gotestsum + protobuf + protoc-gen-go + protoc-gen-go-grpc + kind + ]; + + # https://github.com/cachix/devenv/issues/528#issuecomment-1556108767 + containers = pkgs.lib.mkForce { }; + }; + + ci = devenv.shells.default; + }; + }; + }; } diff --git a/go.mod b/go.mod index d15823aa1b..08770b5056 100644 --- a/go.mod +++ b/go.mod @@ -1,95 +1,115 @@ module github.com/dexidp/dex -go 1.19 +go 1.25.0 require ( - entgo.io/ent v0.11.2 - github.com/AppsFlyer/go-sundheit v0.5.0 + cloud.google.com/go/compute/metadata v0.9.0 + entgo.io/ent v0.14.5 + github.com/AppsFlyer/go-sundheit v0.6.0 github.com/Masterminds/semver v1.5.0 - github.com/Masterminds/sprig/v3 v3.2.2 - github.com/beevik/etree v1.1.0 - github.com/coreos/go-oidc/v3 v3.3.0 - github.com/dexidp/dex/api/v2 v2.1.0 - github.com/felixge/httpsnoop v1.0.3 + github.com/Masterminds/sprig/v3 v3.3.0 + github.com/beevik/etree v1.6.0 + github.com/coreos/go-oidc/v3 v3.14.1 + github.com/dexidp/dex/api/v2 v2.3.0 + github.com/fsnotify/fsnotify v1.9.0 github.com/ghodss/yaml v1.0.0 - github.com/go-ldap/ldap/v3 v3.4.4 - github.com/go-sql-driver/mysql v1.6.0 - github.com/gorilla/handlers v1.5.1 - github.com/gorilla/mux v1.8.0 + github.com/go-jose/go-jose/v4 v4.1.3 + github.com/go-ldap/ldap/v3 v3.4.12 + github.com/go-sql-driver/mysql v1.9.3 + github.com/google/uuid v1.6.0 + github.com/gorilla/handlers v1.5.2 + github.com/gorilla/mux v1.8.1 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/kylelemons/godebug v1.1.0 - github.com/lib/pq v1.10.5 + github.com/lib/pq v1.10.9 github.com/mattermost/xml-roundtrip-validator v0.1.0 - github.com/mattn/go-sqlite3 v1.14.15 - github.com/oklog/run v1.1.0 + github.com/mattn/go-sqlite3 v1.14.32 + github.com/oklog/run v1.2.0 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.13.0 - github.com/russellhaering/goxmldsig v1.2.0 - github.com/sirupsen/logrus v1.9.0 - github.com/spf13/cobra v1.5.0 - github.com/stretchr/testify v1.8.0 - go.etcd.io/etcd/client/pkg/v3 v3.5.4 - go.etcd.io/etcd/client/v3 v3.5.4 - golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d - golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b - golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 - google.golang.org/api v0.94.0 - google.golang.org/grpc v1.49.0 - google.golang.org/protobuf v1.28.1 - gopkg.in/square/go-jose.v2 v2.6.0 + github.com/prometheus/client_golang v1.23.2 + github.com/russellhaering/goxmldsig v1.5.0 + github.com/spf13/cobra v1.10.1 + github.com/stretchr/testify v1.11.1 + go.etcd.io/etcd/client/pkg/v3 v3.6.5 + go.etcd.io/etcd/client/v3 v3.6.5 + golang.org/x/crypto v0.46.0 + golang.org/x/exp v0.0.0-20221004215720-b9f4876ce741 + golang.org/x/net v0.47.0 + golang.org/x/oauth2 v0.34.0 + google.golang.org/api v0.257.0 + google.golang.org/grpc v1.77.0 + google.golang.org/protobuf v1.36.10 ) require ( - ariga.io/atlas v0.5.1-0.20220717122844-8593d7eb1a8e // indirect - cloud.google.com/go/compute v1.7.0 // indirect - github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect + ariga.io/atlas v0.32.1-0.20250325101103-175b25e1c1b9 // indirect + cloud.google.com/go/auth v0.17.0 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect + dario.cat/mergo v1.0.1 // indirect + filippo.io/edwards25519 v1.1.0 // indirect + github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver/v3 v3.1.1 // indirect - github.com/agext/levenshtein v1.2.1 // indirect - github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect + github.com/Masterminds/semver/v3 v3.3.0 // indirect + github.com/agext/levenshtein v1.2.3 // indirect + github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/coreos/go-semver v0.3.0 // indirect - github.com/coreos/go-systemd/v22 v22.3.2 // indirect + github.com/bmatcuk/doublestar v1.3.4 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/coreos/go-semver v0.3.1 // indirect + github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/inflect v0.19.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-cmp v0.5.8 // indirect - github.com/google/uuid v1.3.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect - github.com/googleapis/gax-go/v2 v2.4.0 // indirect - github.com/hashicorp/hcl/v2 v2.10.0 // indirect - github.com/huandu/xstrings v1.3.1 // indirect - github.com/imdario/mergo v0.3.11 // indirect - github.com/inconshreveable/mousetrap v1.0.0 // indirect - github.com/jonboulle/clockwork v0.2.2 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect - github.com/mitchellh/copystructure v1.0.0 // indirect - github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect - github.com/mitchellh/reflectwalk v1.0.0 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/s2a-go v0.1.9 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.7 // indirect + github.com/googleapis/gax-go/v2 v2.15.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect + github.com/hashicorp/hcl/v2 v2.18.1 // indirect + github.com/huandu/xstrings v1.5.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jonboulle/clockwork v0.5.0 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.37.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect - github.com/shopspring/decimal v1.2.0 // indirect - github.com/spf13/cast v1.4.1 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/zclconf/go-cty v1.8.0 // indirect - go.etcd.io/etcd/api/v3 v3.5.4 // indirect - go.opencensus.io v0.23.0 // indirect - go.uber.org/atomic v1.7.0 // indirect - go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.17.0 // indirect - golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect - golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect - golang.org/x/text v0.3.7 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.66.1 // indirect + github.com/prometheus/procfs v0.16.1 // indirect + github.com/shopspring/decimal v1.4.0 // indirect + github.com/spf13/cast v1.7.0 // indirect + github.com/spf13/pflag v1.0.9 // indirect + github.com/zclconf/go-cty v1.14.4 // indirect + github.com/zclconf/go-cty-yaml v1.1.0 // indirect + go.etcd.io/etcd/api/v3 v3.6.5 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect + go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect + golang.org/x/mod v0.30.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/text v0.32.0 // indirect + golang.org/x/tools v0.39.0 // indirect + golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) replace github.com/dexidp/dex/api/v2 => ./api/v2 + +tool entgo.io/ent/cmd/ent diff --git a/go.sum b/go.sum index 27fdbb8eea..29c01de719 100644 --- a/go.sum +++ b/go.sum @@ -1,923 +1,301 @@ -ariga.io/atlas v0.5.1-0.20220717122844-8593d7eb1a8e h1:/r1xGMwmLg4LZ2V3/wWui9TtM3+STh1fp5ExSVRNFZo= -ariga.io/atlas v0.5.1-0.20220717122844-8593d7eb1a8e/go.mod h1:ofVetkJqlaWle3mvYmaS2uyFGFcc7dSq436tmxa/Mzk= -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= -cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= -cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= -cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= -cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= -cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= -cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= -cloud.google.com/go/compute v1.7.0 h1:v/k9Eueb8aAJ0vZuxKMrgm6kPhCLZU9HxFU+AFDs9Uk= -cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -entgo.io/ent v0.11.2 h1:UM2/BUhF2FfsxPHRxLjQbhqJNaDdVlOwNIAMLs2jyto= -entgo.io/ent v0.11.2/go.mod h1:YGHEQnmmIUgtD5b1ICD5vg74dS3npkNnmC5K+0J+IHU= -github.com/AppsFlyer/go-sundheit v0.5.0 h1:/VxpyigCfJrq1r97mn9HPiAB2qrhcTFHwNIIDr15CZM= -github.com/AppsFlyer/go-sundheit v0.5.0/go.mod h1:2ZM0BnfqT/mljBQO224VbL5XH06TgWuQ6Cn+cTtCpTY= -github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e h1:NeAW1fUYUEWhft7pkxDf6WoUvEZJ/uOKsvtpjLnn8MU= -github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +ariga.io/atlas v0.32.1-0.20250325101103-175b25e1c1b9 h1:E0wvcUXTkgyN4wy4LGtNzMNGMytJN8afmIWXJVMi4cc= +ariga.io/atlas v0.32.1-0.20250325101103-175b25e1c1b9/go.mod h1:Oe1xWPuu5q9LzyrWfbZmEZxFYeu4BHTyzfjeW2aZp/w= +cloud.google.com/go/auth v0.17.0 h1:74yCm7hCj2rUyyAocqnFzsAYXgJhrG26XCFimrc/Kz4= +cloud.google.com/go/auth v0.17.0/go.mod h1:6wv/t5/6rOPAX4fJiRjKkJCvswLwdet7G8+UGXt7nCQ= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= +cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= +cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +entgo.io/ent v0.14.5 h1:Rj2WOYJtCkWyFo6a+5wB3EfBRP0rnx1fMk6gGA0UUe4= +entgo.io/ent v0.14.5/go.mod h1:zTzLmWtPvGpmSwtkaayM2cm5m819NdM7z7tYPq3vN0U= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/AppsFlyer/go-sundheit v0.6.0 h1:d2hBvCjBSb2lUsEWGfPigr4MCOt04sxB+Rppl0yUMSk= +github.com/AppsFlyer/go-sundheit v0.6.0/go.mod h1:LDdBHD6tQBtmHsdW+i1GwdTt6Wqc0qazf5ZEJVTbTME= +github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= +github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= +github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= -github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8= -github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8= -github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= -github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= -github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= -github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= -github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= -github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= +github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= +github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= +github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= +github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e h1:4dAU9FXIyQktpoUAgOJK3OTFc/xug0PCXYCqU0FgDKI= +github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= +github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= +github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= +github.com/beevik/etree v1.6.0 h1:u8Kwy8pp9D9XeITj2Z0XtA5qqZEmtJtuXZRQi+j03eE= +github.com/beevik/etree v1.6.0/go.mod h1:bh4zJxiIr62SOf9pRzN7UUYaEDa9HEKafK25+sLc0Gc= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/coreos/go-oidc/v3 v3.3.0 h1:Y1LV3mP+QT3MEycATZpAiwfyN+uxZLqVbAHJUuOJEe4= -github.com/coreos/go-oidc/v3 v3.3.0/go.mod h1:eHUXhZtXPQLgEaDrOVTgwbgmz1xGOkJNye6h3zkD2Pw= -github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0= +github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/coreos/go-oidc/v3 v3.14.1 h1:9ePWwfdwC4QKRlCXsJGou56adA/owXczOzwKdOumLqk= +github.com/coreos/go-oidc/v3 v3.14.1/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU= +github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= +github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= -github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A= -github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-ldap/ldap/v3 v3.4.4 h1:qPjipEpt+qDa6SI/h1fzuGWoRUY+qqQ9sOZq67/PYUs= -github.com/go-ldap/ldap/v3 v3.4.4/go.mod h1:fe1MsuN5eJJ1FeLT/LEBVdWfNWKh459R7aXgXtJC+aI= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 h1:BP4M0CvQ4S3TGls2FvczZtj5Re/2ZzkV9VwqPHH/3Bo= +github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= +github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= +github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= +github.com/go-ldap/ldap/v3 v3.4.12 h1:1b81mv7MagXZ7+1r7cLTWmyuTqVqdwbtJSjC0DAp9s4= +github.com/go-ldap/ldap/v3 v3.4.12/go.mod h1:+SPAGcTtOfmGsCb3h1RFiq4xpp4N636G75OEace8lNo= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= -github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= -github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= +github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.1.0 h1:zO8WHNx/MYiAKJ3d5spxZXZE6KHmIQGQcAzwUzV7qQw= -github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= -github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= -github.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk= -github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= -github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= -github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= -github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.3.7 h1:zrn2Ee/nWmHulBx5sAVrGgAa0f2/R35S4DJwfFaUPFQ= +github.com/googleapis/enterprise-certificate-proxy v0.3.7/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= +github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo= +github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= +github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= +github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/hcl/v2 v2.10.0 h1:1S1UnuhDGlv3gRFV4+0EdwB+znNP5HmcGbIqwnSCByg= -github.com/hashicorp/hcl/v2 v2.10.0/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg= -github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs= -github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= -github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= -github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= +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= +github.com/hashicorp/hcl/v2 v2.18.1 h1:6nxnOJFku1EuSawSD81fuviYUV8DxFr3fp2dUi3ZYSo= +github.com/hashicorp/hcl/v2 v2.18.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= +github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= +github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= +github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= +github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8= +github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= +github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= +github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I= +github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/lib/pq v1.10.5 h1:J+gdV2cUmX7ZqL2B0lFcW0m+egaHC2V3lpO8nWxyYiQ= -github.com/lib/pq v1.10.5/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattermost/xml-roundtrip-validator v0.1.0 h1:RXbVD2UAl7A7nOTR4u7E3ILa4IbtvKBHw64LDsmu9hU= github.com/mattermost/xml-roundtrip-validator v0.1.0/go.mod h1:qccnGMcpgwcNaBnxqpJpWWUiPNr5H3O8eDgGV9gT5To= -github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= -github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= -github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM= -github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= -github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= +github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/oklog/run v1.2.0 h1:O8x3yXwah4A73hJdlrwo/2X6J62gE5qTMusH0dvz60E= +github.com/oklog/run v1.2.0/go.mod h1:mgDbKRSwPhJfesJ4PntqFUbKQRZ50NgmZTSPlFA0YFk= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= -github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= -github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/russellhaering/goxmldsig v1.2.0 h1:Y6GTTc9Un5hCxSzVz4UIWQ/zuVwDvzJk80guqzwx6Vg= -github.com/russellhaering/goxmldsig v1.2.0/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw= +github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= +github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= +github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/russellhaering/goxmldsig v1.5.0 h1:AU2UkkYIUOTyZRbe08XMThaOCelArgvNfYapcmSjBNw= +github.com/russellhaering/goxmldsig v1.5.0/go.mod h1:x98CjQNFJcWfMxeOrMnMKg70lvDP6tE0nTaeUnjXDmk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= -github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= -github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= -github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= +github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= +github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= +github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= -github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= -github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= -github.com/zclconf/go-cty v1.8.0 h1:s4AvqaeQzJIu3ndv4gVIhplVD0krU+bgrcLSVUnaWuA= -github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= -github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= -go.etcd.io/etcd/api/v3 v3.5.4 h1:OHVyt3TopwtUQ2GKdd5wu3PmmipR4FTwCqoEjSyRdIc= -go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= -go.etcd.io/etcd/client/pkg/v3 v3.5.4 h1:lrneYvz923dvC14R54XcA7FXoZ3mlGZAgmwhfm7HqOg= -go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v3 v3.5.4 h1:p83BUL3tAYS0OT/r0qglgc3M1JjhM0diV8DSWAhVXv4= -go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= +github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty-yaml v1.1.0 h1:nP+jp0qPHv2IhUVqmQSzjvqAWcObN0KBkUl2rWBdig0= +github.com/zclconf/go-cty-yaml v1.1.0/go.mod h1:9YLUH4g7lOhVWqUbctnVlZ5KLpg7JAprQNgxSZ1Gyxs= +go.etcd.io/etcd/api/v3 v3.6.5 h1:pMMc42276sgR1j1raO/Qv3QI9Af/AuyQUW6CBAWuntA= +go.etcd.io/etcd/api/v3 v3.6.5/go.mod h1:ob0/oWA/UQQlT1BmaEkWQzI0sJ1M0Et0mMpaABxguOQ= +go.etcd.io/etcd/client/pkg/v3 v3.6.5 h1:Duz9fAzIZFhYWgRjp/FgNq2gO1jId9Yae/rLn3RrBP8= +go.etcd.io/etcd/client/pkg/v3 v3.6.5/go.mod h1:8Wx3eGRPiy0qOFMZT/hfvdos+DjEaPxdIDiCDUv/FQk= +go.etcd.io/etcd/client/v3 v3.6.5 h1:yRwZNFBx/35VKHTcLDeO7XVLbCBFbPi+XV4OC3QJf2U= +go.etcd.io/etcd/client/v3 v3.6.5/go.mod h1:ZqwG/7TAFZ0BJ0jXRPoJjKQJtbFo/9NIY8uoFFKcCyo= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= +go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= +golang.org/x/exp v0.0.0-20221004215720-b9f4876ce741 h1:fGZugkZk2UgYBxtpKmvub51Yno1LJDeEsRp2xGD+0gY= +golang.org/x/exp v0.0.0-20221004215720-b9f4876ce741/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= +golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY= -golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 h1:2o1E+E8TpNLklK9nHiPiK1uzIYrIHt+cQx3ynCwq9V8= -golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= +golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools/go/expect v0.1.0-deprecated h1:jY2C5HGYR5lqex3gEniOQL0r7Dq5+VGVgY1nudX5lXY= +golang.org/x/tools/go/expect v0.1.0-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= +golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= +golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= -google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= -google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= -google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= -google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= -google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= -google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= -google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= -google.golang.org/api v0.94.0 h1:KtKM9ru3nzQioV1HLlUf1cR7vMYJIpgls5VhAYQXIwA= -google.golang.org/api v0.94.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f h1:hJ/Y5SqPXbarffmAsApliUlcvMU+wScNGfyop4bZm8o= -google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.49.0 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw= -google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -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.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/api v0.257.0 h1:8Y0lzvHlZps53PEaw+G29SsQIkuKrumGWs9puiexNAA= +google.golang.org/api v0.257.0/go.mod h1:4eJrr+vbVaZSqs7vovFd1Jb/A6ml6iw2e6FBYf3GAO4= +google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= +google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= +google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 h1:mepRgnBZa07I4TRuomDE4sTIYieg/osKmzIf4USdWS4= +google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846 h1:Wgl1rcDNThT+Zn47YyCXOXyX/COgMTIdhJ717F0l4xk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= +google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= 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= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= -gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/pkg/featureflags/flag.go b/pkg/featureflags/flag.go new file mode 100644 index 0000000000..98729ac9ed --- /dev/null +++ b/pkg/featureflags/flag.go @@ -0,0 +1,33 @@ +package featureflags + +import ( + "os" + "strconv" + "strings" +) + +type flag struct { + Name string + Default bool +} + +func (f *flag) env() string { + return "DEX_" + strings.ToUpper(f.Name) +} + +func (f *flag) Enabled() bool { + raw := os.Getenv(f.env()) + if raw == "" { + return f.Default + } + + res, err := strconv.ParseBool(raw) + if err != nil { + return f.Default + } + return res +} + +func newFlag(s string, d bool) *flag { + return &flag{Name: s, Default: d} +} diff --git a/pkg/featureflags/set.go b/pkg/featureflags/set.go new file mode 100644 index 0000000000..bd86f1e749 --- /dev/null +++ b/pkg/featureflags/set.go @@ -0,0 +1,17 @@ +package featureflags + +var ( + // EntEnabled enables experimental ent-based engine for the database storages. + // https://entgo.io/ + EntEnabled = newFlag("ent_enabled", false) + + // ExpandEnv can enable or disable env expansion in the config which can be useful in environments where, e.g., + // $ sign is a part of the password for LDAP user. + ExpandEnv = newFlag("expand_env", true) + + // APIConnectorsCRUD allows CRUD operations on connectors through the gRPC API + APIConnectorsCRUD = newFlag("api_connectors_crud", false) + + // ContinueOnConnectorFailure allows the server to start even if some connectors fail to initialize. + ContinueOnConnectorFailure = newFlag("continue_on_connector_failure", false) +) diff --git a/pkg/httpclient/httpclient.go b/pkg/httpclient/httpclient.go new file mode 100644 index 0000000000..671e0e7754 --- /dev/null +++ b/pkg/httpclient/httpclient.go @@ -0,0 +1,64 @@ +package httpclient + +import ( + "crypto/tls" + "crypto/x509" + "encoding/base64" + "fmt" + "net" + "net/http" + "os" + "time" +) + +func extractCAs(input []string) [][]byte { + result := make([][]byte, 0, len(input)) + for _, ca := range input { + if ca == "" { + continue + } + + pemData, err := os.ReadFile(ca) + if err != nil { + pemData, err = base64.StdEncoding.DecodeString(ca) + if err != nil { + pemData = []byte(ca) + } + } + + result = append(result, pemData) + } + return result +} + +func NewHTTPClient(rootCAs []string, insecureSkipVerify bool) (*http.Client, error) { + pool, err := x509.SystemCertPool() + if err != nil { + return nil, err + } + + tlsConfig := tls.Config{RootCAs: pool, InsecureSkipVerify: insecureSkipVerify} + for index, rootCABytes := range extractCAs(rootCAs) { + if !tlsConfig.RootCAs.AppendCertsFromPEM(rootCABytes) { + return nil, fmt.Errorf("rootCAs.%d is not in PEM format, certificate must be "+ + "a PEM encoded string, a base64 encoded bytes that contain PEM encoded string, "+ + "or a path to a PEM encoded certificate", index) + } + } + + return &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tlsConfig, + Proxy: http.ProxyFromEnvironment, + DialContext: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + DualStack: true, + }).DialContext, + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + }, + }, nil +} diff --git a/pkg/httpclient/httpclient_test.go b/pkg/httpclient/httpclient_test.go new file mode 100644 index 0000000000..6f561c1030 --- /dev/null +++ b/pkg/httpclient/httpclient_test.go @@ -0,0 +1,83 @@ +package httpclient_test + +import ( + "crypto/tls" + "encoding/base64" + "fmt" + "io" + "net/http" + "net/http/httptest" + "os" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/dexidp/dex/pkg/httpclient" +) + +func TestRootCAs(t *testing.T) { + ts, err := NewLocalHTTPSTestServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, "Hello, client") + })) + assert.Nil(t, err) + defer ts.Close() + + runTest := func(name string, certs []string) { + t.Run(name, func(t *testing.T) { + rootCAs := certs + testClient, err := httpclient.NewHTTPClient(rootCAs, false) + assert.Nil(t, err) + + res, err := testClient.Get(ts.URL) + assert.Nil(t, err) + + greeting, err := io.ReadAll(res.Body) + res.Body.Close() + assert.Nil(t, err) + + assert.Equal(t, "Hello, client", string(greeting)) + }) + } + + runTest("From file", []string{"testdata/rootCA.pem"}) + + content, err := os.ReadFile("testdata/rootCA.pem") + assert.NoError(t, err) + runTest("From string", []string{string(content)}) + + contentStr := base64.StdEncoding.EncodeToString(content) + runTest("From bytes", []string{contentStr}) +} + +func TestInsecureSkipVerify(t *testing.T) { + ts, err := NewLocalHTTPSTestServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, "Hello, client") + })) + assert.Nil(t, err) + defer ts.Close() + + insecureSkipVerify := true + + testClient, err := httpclient.NewHTTPClient(nil, insecureSkipVerify) + assert.Nil(t, err) + + res, err := testClient.Get(ts.URL) + assert.Nil(t, err) + + greeting, err := io.ReadAll(res.Body) + res.Body.Close() + assert.Nil(t, err) + + assert.Equal(t, "Hello, client", string(greeting)) +} + +func NewLocalHTTPSTestServer(handler http.Handler) (*httptest.Server, error) { + ts := httptest.NewUnstartedServer(handler) + cert, err := tls.LoadX509KeyPair("testdata/server.crt", "testdata/server.key") + if err != nil { + return nil, err + } + ts.TLS = &tls.Config{Certificates: []tls.Certificate{cert}} + ts.StartTLS() + return ts, nil +} diff --git a/pkg/httpclient/readme.md b/pkg/httpclient/readme.md new file mode 100644 index 0000000000..cc26252293 --- /dev/null +++ b/pkg/httpclient/readme.md @@ -0,0 +1,44 @@ +# Regenerate testdata + +### server.csr.cnf + +``` +[req] +default_bits = 2048 +prompt = no +default_md = sha256 +distinguished_name = dn + +[dn] +C=US +ST=RandomState +L=RandomCity +O=RandomOrganization +OU=RandomOrganizationUnit +emailAddress=hello@example.com +CN = localhost +``` + +and + +### v3.ext +``` +authorityKeyIdentifier=keyid,issuer +basicConstraints=CA:FALSE +keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment +subjectAltName = @alt_names + +[alt_names] +DNS.1 = localhost +IP.1 = 127.0.0.1 +``` + +### Then enter the following commands: + +`openssl genrsa -out rootCA.key 2048` + +`openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.pem -config server.csr.cnf` + +`openssl req -new -sha256 -nodes -out server.csr -newkey rsa:2048 -keyout server.key -config server.csr.cnf` + +`openssl x509 -req -in server.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out server.crt -days 3650 -sha256 -extfile v3.ext` diff --git a/pkg/httpclient/testdata/rootCA.key b/pkg/httpclient/testdata/rootCA.key new file mode 100644 index 0000000000..9c4eeee12a --- /dev/null +++ b/pkg/httpclient/testdata/rootCA.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA4dB5aQCjCmMsW71u9F0WNm1TYjXQBZ4p7oNT+BQwCc/MZ2xc +5NexS2O86nbRkw5jwyfAAMSMKRr9s2FluVTHqiln78rg+XUgmrmNT3ZroLmW6QL6 +Ca8dbMPky+tQclZsvMd3HAeCyyrs4pf7wM1AyUJD7H0xAlVD1fsohkg7jhBFUfV+ +q2VMMdnsaV5vFrW/2vPBWz1SNPW/Xm+Ilny7xg9njQLcPMNtVtF+7EPB6sxD6qrj +BC+Kj5zQ3bZOfdrh7yy63dbh/Kh+3NScgO+k+x92HlAjRIvj5y4KrbGZl7CmOth5 +y7fPywApVbDfZRWJChI1PVflOyDdnC+vhMLbHQIDAQABAoIBAEmjrrQrXP/6L3EL +aa+O27uME3Enk1sBpTL+6Ncx3iiU91eS4whNvqeTMvxTGy0VuDrgL6EQd5TAFJP2 +4zF5EFPRhO+R/aPcKnHKqOaM+7RCUZBTRC78SGA70dUeO/HNdVBqy9D8Mg8HRJDw +d0z8om//iB8LBHx6SdDyQtjnnWRKFTzQRurBBoyLe2vPMFtINKtNUkahjc8HE4GO +aIv1LICJUzf4ZnkntKd5cFHZ42R2Tmfj0Y9G9DyJbuSA3+0u5IhYB39Uy6jFxLi8 +I5PoIVhgYZ0aivsVBIviShwQ9kgv6807YBxt22eSNovBDrSp+cAnIF9+p0b3MnkU +aCHSiBECgYEA84lssi6AqfCEsSiQMSM9kMCXJ4KQI/l7pmrIA50+V5HSEby9lg2Y +N6XJ4V4q46t8FcZBjmMvzn9fwiPMRw5e995cVNBQ31a1FX/1Hy6RNtEiLZRnkHI5 +WznY9IxQ+c9JXJeFY1sO0BfO0TS3WvOf1rwqOb92q+cQaItnPQ+4Ya8CgYEA7V7e +IqW3PpO4H+c5hH9egM0BjAxH71C9YpYzZpF9uiPIkuMnJ8nm9bB6RiuDaYCxvrfE +A0h/SQewoYJKL4OfKGjrbG7U4zLMZHIWlf8Za55Zik5BNjvgBqFFrrSgLUGxdRTX +N0+TlWlW1bvJblWpdjIbJbg/6kCU98TzK852fvMCgYAWYa/apElw1MjtGyQ9T9bN +odWCbQ5gMAJ8Jd4h7uaW17DtrmHiE3fEzXjDPItGhzENMz49HsJ7ANvFFNMmSJzT +vNzRcp+sFuTnh+34Iqh32DqC49usu8KnrqZQu0CJ5NICL26z1d+DolyAf47GThOH +gZ2D1yPJ4p9wbDddtj8kwwKBgCFKB68mPG+rOcxHmjppvnAj0A66/i+izBySYf0F +dHNxZ0SqVKhw2VIlgNBsc86M/OB5VyT6utccG/paklrdg6mgJTwcwwBl9GI12dMJ +ZqBAIeCSnvSjKwTjAynALSKLrv5zgMdCArmWf1YUMuilXNG1rzb4AwawLfQdi9jd +6KJfAoGBALFl6ldywl3sGPk9K2xCDYYhb1TNQyheA5YvoZzZ6XCo1q0Lbwy/FamZ +0TSWkoEmGB/Hck3HgtZDRo3CTI1vYfbpAtgI7oD1NA1zMaLulNQxKjH3iVvyb+R7 +ZcIT7EVPZgkUwr0bsp22yVDekh/CHoB6FZPCyoAb8WnfJfooTBzB +-----END RSA PRIVATE KEY----- diff --git a/pkg/httpclient/testdata/rootCA.pem b/pkg/httpclient/testdata/rootCA.pem new file mode 100644 index 0000000000..c03bdac0c0 --- /dev/null +++ b/pkg/httpclient/testdata/rootCA.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID1jCCAr4CCQCG4JBeSi6cDjANBgkqhkiG9w0BAQsFADCBrDELMAkGA1UEBhMC +VVMxFDASBgNVBAgMC1JhbmRvbVN0YXRlMRMwEQYDVQQHDApSYW5kb21DaXR5MRsw +GQYDVQQKDBJSYW5kb21Pcmdhbml6YXRpb24xHzAdBgNVBAsMFlJhbmRvbU9yZ2Fu +aXphdGlvblVuaXQxIDAeBgkqhkiG9w0BCQEWEWhlbGxvQGV4YW1wbGUuY29tMRIw +EAYDVQQDDAlsb2NhbGhvc3QwHhcNMjIxMDA3MjIwNjQwWhcNMzIxMDA0MjIwNjQw +WjCBrDELMAkGA1UEBhMCVVMxFDASBgNVBAgMC1JhbmRvbVN0YXRlMRMwEQYDVQQH +DApSYW5kb21DaXR5MRswGQYDVQQKDBJSYW5kb21Pcmdhbml6YXRpb24xHzAdBgNV +BAsMFlJhbmRvbU9yZ2FuaXphdGlvblVuaXQxIDAeBgkqhkiG9w0BCQEWEWhlbGxv +QGV4YW1wbGUuY29tMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDh0HlpAKMKYyxbvW70XRY2bVNiNdAFninug1P4FDAJ +z8xnbFzk17FLY7zqdtGTDmPDJ8AAxIwpGv2zYWW5VMeqKWfvyuD5dSCauY1Pdmug +uZbpAvoJrx1sw+TL61ByVmy8x3ccB4LLKuzil/vAzUDJQkPsfTECVUPV+yiGSDuO +EEVR9X6rZUwx2expXm8Wtb/a88FbPVI09b9eb4iWfLvGD2eNAtw8w21W0X7sQ8Hq +zEPqquMEL4qPnNDdtk592uHvLLrd1uH8qH7c1JyA76T7H3YeUCNEi+PnLgqtsZmX +sKY62HnLt8/LAClVsN9lFYkKEjU9V+U7IN2cL6+EwtsdAgMBAAEwDQYJKoZIhvcN +AQELBQADggEBAN6g0qit/3R2X+KdR0LgRXF/h4qQFgcV6cxnhRAmLIDNJlxKSHqN +IE5+bxzCbkblzGfr/jNPqW0s+yaN4CyMgKNYSzkLBPE4FF+19Uv+dyYfFms3mDJ7 +0rGjS5bCscThWhpaSw20LcwQcr/+X+/fGzJ01dVFK1UOjBKg4d4dMwxklbIkZqIq +siRW0GMy26mgVZ/BSjeh5kEjs6h6H3cJsGl7xYT+BI7wnxHwGeT9tkBgiyT5FwaS +vtdZkBpQ9q8f7FwsEm3woLHdWuOnrtUtVpY/oc6WFGdROQdGzjSk0D3kHs9YhueC +GSzZKrqX+TSIgpPrLYNHX4uxlo5TAwP/5GM= +-----END CERTIFICATE----- diff --git a/pkg/httpclient/testdata/rootCA.srl b/pkg/httpclient/testdata/rootCA.srl new file mode 100644 index 0000000000..214ae68bf1 --- /dev/null +++ b/pkg/httpclient/testdata/rootCA.srl @@ -0,0 +1 @@ +C1B35F0051A641BB diff --git a/pkg/httpclient/testdata/server.crt b/pkg/httpclient/testdata/server.crt new file mode 100644 index 0000000000..9b0f12ec58 --- /dev/null +++ b/pkg/httpclient/testdata/server.crt @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIE5TCCA82gAwIBAgIJAMGzXwBRpkG7MA0GCSqGSIb3DQEBCwUAMIGsMQswCQYD +VQQGEwJVUzEUMBIGA1UECAwLUmFuZG9tU3RhdGUxEzARBgNVBAcMClJhbmRvbUNp +dHkxGzAZBgNVBAoMElJhbmRvbU9yZ2FuaXphdGlvbjEfMB0GA1UECwwWUmFuZG9t +T3JnYW5pemF0aW9uVW5pdDEgMB4GCSqGSIb3DQEJARYRaGVsbG9AZXhhbXBsZS5j +b20xEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0yMjEwMDcyMjA3MDhaFw0zMjEwMDQy +MjA3MDhaMIGsMQswCQYDVQQGEwJVUzEUMBIGA1UECAwLUmFuZG9tU3RhdGUxEzAR +BgNVBAcMClJhbmRvbUNpdHkxGzAZBgNVBAoMElJhbmRvbU9yZ2FuaXphdGlvbjEf +MB0GA1UECwwWUmFuZG9tT3JnYW5pemF0aW9uVW5pdDEgMB4GCSqGSIb3DQEJARYR +aGVsbG9AZXhhbXBsZS5jb20xEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMuKdpXP87Q7Kg3iafXzvBuVIyV1K5UmMYiN +koztkC5XrCzHaQRS/CoIb7/nUqmtAxx7RL0jzhZ93zBN4HY/Zcnrd9tXoPPxi0mG +ZZWfFU6nN8nOkMHWzEbHVBmhxpfGtwmLcajQ4HrK1TZwJUn6GqclHQRy/gjxkiw5 +KPqzfVOVlA6ht4KdKstKazQkWZ5gdWT4d8yrEy/IT4oaW05xALBMQ7YGjkzWKsSF +6ygXI7xqF9rg9jCnUsPYg4f8ut3N0c00KjsfKOOj2dF/ZyjedQ5c0u4hHmxSo3Ka +0ZTmIrMfbVXgGjxRG2HZXLpPvQKoCf/fOX8Irdr+lahFVKASxN0CAwEAAaOCAQYw +ggECMIHLBgNVHSMEgcMwgcChgbKkga8wgawxCzAJBgNVBAYTAlVTMRQwEgYDVQQI +DAtSYW5kb21TdGF0ZTETMBEGA1UEBwwKUmFuZG9tQ2l0eTEbMBkGA1UECgwSUmFu +ZG9tT3JnYW5pemF0aW9uMR8wHQYDVQQLDBZSYW5kb21Pcmdhbml6YXRpb25Vbml0 +MSAwHgYJKoZIhvcNAQkBFhFoZWxsb0BleGFtcGxlLmNvbTESMBAGA1UEAwwJbG9j +YWxob3N0ggkAhuCQXkounA4wCQYDVR0TBAIwADALBgNVHQ8EBAMCBPAwGgYDVR0R +BBMwEYIJbG9jYWxob3N0hwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQCWmh5ebpkm +v2B1yQgarSCSSkLZ5DZSAJjrPgW2IJqCW2q2D1HworbW1Yn5jqrM9FKGnJfjCyve +zBB5AOlGp+0bsZGgMRMCavgv4QhTThXUoJqqHcfEu4wHndcgrqSadxmV5aisSR4u +gXnjW43o3akby+h1K40RR3vVkpzPaoC3/bgk7WVpfpPiP32E24a01gETozRb/of/ +ATN3JBe0xh+e63CrPX1sago5+u3UETIoOr0fW8M/gU9GApmJiFAXwHag6j54hLCG +23EtVDwmlarG8Pj+i0yru8s22QqzAJi5E0OwR4aB8tqicLKYBVfzyLCOielIBUrK +OkuFKp+VjxQX +-----END CERTIFICATE----- diff --git a/pkg/httpclient/testdata/server.csr b/pkg/httpclient/testdata/server.csr new file mode 100644 index 0000000000..f422a853c3 --- /dev/null +++ b/pkg/httpclient/testdata/server.csr @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIC8jCCAdoCAQAwgawxCzAJBgNVBAYTAlVTMRQwEgYDVQQIDAtSYW5kb21TdGF0 +ZTETMBEGA1UEBwwKUmFuZG9tQ2l0eTEbMBkGA1UECgwSUmFuZG9tT3JnYW5pemF0 +aW9uMR8wHQYDVQQLDBZSYW5kb21Pcmdhbml6YXRpb25Vbml0MSAwHgYJKoZIhvcN +AQkBFhFoZWxsb0BleGFtcGxlLmNvbTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy4p2lc/ztDsqDeJp9fO8G5UjJXUr +lSYxiI2SjO2QLlesLMdpBFL8Kghvv+dSqa0DHHtEvSPOFn3fME3gdj9lyet321eg +8/GLSYZllZ8VTqc3yc6QwdbMRsdUGaHGl8a3CYtxqNDgesrVNnAlSfoapyUdBHL+ +CPGSLDko+rN9U5WUDqG3gp0qy0prNCRZnmB1ZPh3zKsTL8hPihpbTnEAsExDtgaO +TNYqxIXrKBcjvGoX2uD2MKdSw9iDh/y63c3RzTQqOx8o46PZ0X9nKN51DlzS7iEe +bFKjcprRlOYisx9tVeAaPFEbYdlcuk+9AqgJ/985fwit2v6VqEVUoBLE3QIDAQAB +oAAwDQYJKoZIhvcNAQELBQADggEBADjuujIFoDJllR6Xo/w7j5vfNOeHO5GSgxF2 +XnuuDOI9Tomi7vURFZNbz3VAYiehpxRxYqLwFoQUwFtux2qRuGyg0P9fP1iQXPUE +QUfFXmvB80uf2bG4lkbUwnmlZLFOEwhGZyPxpvsrxp2Ei2ppkUopCkzOMsSk3m0X +MC50ZsTHOxfkA3r1WmS7oE2c0p0Fvyx+UJw0URAXFvDS1X0ONgww3FxqbBbm9W37 +5N4FZzGAK6j1wzuynKKXrn20YDCANXYH55PZyupfCeSZT0H0AZifWL7rz/G9uqme +RzbIYc/CNQQTympjinBegQdVeB3yjVNZIvpGOuPSKQqhwFtmDFo= +-----END CERTIFICATE REQUEST----- diff --git a/pkg/httpclient/testdata/server.csr.cnf b/pkg/httpclient/testdata/server.csr.cnf new file mode 100644 index 0000000000..6ff57d1a35 --- /dev/null +++ b/pkg/httpclient/testdata/server.csr.cnf @@ -0,0 +1,14 @@ +[req] +default_bits = 2048 +prompt = no +default_md = sha256 +distinguished_name = dn + +[dn] +C=US +ST=RandomState +L=RandomCity +O=RandomOrganization +OU=RandomOrganizationUnit +emailAddress=hello@example.com +CN = localhost diff --git a/pkg/httpclient/testdata/server.key b/pkg/httpclient/testdata/server.key new file mode 100644 index 0000000000..9708e1e6ea --- /dev/null +++ b/pkg/httpclient/testdata/server.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDLinaVz/O0OyoN +4mn187wblSMldSuVJjGIjZKM7ZAuV6wsx2kEUvwqCG+/51KprQMce0S9I84Wfd8w +TeB2P2XJ63fbV6Dz8YtJhmWVnxVOpzfJzpDB1sxGx1QZocaXxrcJi3Go0OB6ytU2 +cCVJ+hqnJR0Ecv4I8ZIsOSj6s31TlZQOobeCnSrLSms0JFmeYHVk+HfMqxMvyE+K +GltOcQCwTEO2Bo5M1irEhesoFyO8ahfa4PYwp1LD2IOH/LrdzdHNNCo7Hyjjo9nR +f2co3nUOXNLuIR5sUqNymtGU5iKzH21V4Bo8URth2Vy6T70CqAn/3zl/CK3a/pWo +RVSgEsTdAgMBAAECggEAU6cxu7q+54kVbKVsdThaTF/MFR4F7oPHAd9lpuQQSOuh +iLngMHXGy6OyAgYZlEDWMYN8KdwoXFgZPaoUIaVGuWk8Vnq6XOgeHfbNk2PRhwT0 +yc1K80/Lnx9XMj2p+EEkgxi7eu12BSGN5ZTLzo6rG50GQwjb3WMjd2d6rybL0GjC +wg2arcBk3sSMYmvZOqlAsaQmtgwkJhvhVkVfEQSD3VKF7g0dh/h3LIPyM0Ff4M67 +KpLMPPwzUJ/0Z4ewAP06mMKUA86R93M+dWs2eh1oBGnRkVQdhCJLXJpuGHZ6BTiB +Ry0AeorHfnVXPbtpUeAq6m5/BBl6qX0ooB08BIFwAQKBgQDqJpTZS/ZzqL6Kcs14 +MyFu+7DungSxQ5oK9ju7EFSosanSk4UEa/lw992kM6nsIMwgSVQgba5zKcVMeSmk +AVbpznegQD1BYCwOGwbGvkJ8jbhPy+WLbbRjWT/E6AItZgUK+fyTIcNvSehcQqsT +fhgWsK7ueZCmLQfVhK1AxtvY3QKBgQDeiKuo8plsH/7IxDn7KVHBOHKPC2ZPzg03 +i7La6zomiRckwwPnhicRSYsjtfCCW6Ms+uzjTEItgFM+5PdrXheeku+z/sExRtZu +emqPqDomixlXDRQ6RN3gnBSk4RU+ROB1u1uBLWXqRz8Gp2zJGRxhHfYt2zefBv4w +/cIuPC3cAQKBgD2UsAkGJWb9tj8LOmama+CYaUwYWvuT3+uKHuNvxBQpxZQQICet +jgjb53rL66Cib4z+PBXbQsoe7jjSlNUBVS5gkq2et31+IZgEG6AhYbMIQrUZ1uD4 +lTybuF289vWhoynj3T2E37VhJq89CWky/HrbNOabKiPKLAlHv5kNs7wxAoGBANEJ +XQbU7J2O6Iy7FyQBSlTQq3wHX1Iz4mJ9DcNrFzK/sEfOEMrZT7WDefpPm984KW3F +P+S766ZGVuxLtMbcmh9RM23HLr8VJbSdtZ/AjO9L1r/Y/1lE+49TzmibLpNRq++r +0WbkuEl8J44ek6fLuMbZmDi3JeZycTCgDlnUGdgBAoGAYdliovtURZCm46t1uE3F +idCLCXCccjkt1hcNGNjck/b0trHA7wOEqICIguoWDlEBTc0PDvHEq6PfKyqptGkj +AgaZTMF/aZiGqlT7VRpBuzxM/uV5xzCg+i2ViaW/p3xq0z2PRljVZiEfe5aWcjiM +ouTtnC3TgmcjhTgGmb48QQE= +-----END PRIVATE KEY----- diff --git a/pkg/httpclient/testdata/v3.ext b/pkg/httpclient/testdata/v3.ext new file mode 100644 index 0000000000..68e35be863 --- /dev/null +++ b/pkg/httpclient/testdata/v3.ext @@ -0,0 +1,8 @@ +authorityKeyIdentifier=keyid,issuer +basicConstraints=CA:FALSE +keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment +subjectAltName = @alt_names + +[alt_names] +DNS.1 = localhost +IP.1 = 127.0.0.1 diff --git a/pkg/log/deprecated.go b/pkg/log/deprecated.go deleted file mode 100644 index f20e8b4cb8..0000000000 --- a/pkg/log/deprecated.go +++ /dev/null @@ -1,5 +0,0 @@ -package log - -func Deprecated(logger Logger, f string, args ...interface{}) { - logger.Warnf("Deprecated: "+f, args...) -} diff --git a/pkg/log/logger.go b/pkg/log/logger.go deleted file mode 100644 index 4f3cdd3851..0000000000 --- a/pkg/log/logger.go +++ /dev/null @@ -1,18 +0,0 @@ -// Package log provides a logger interface for logger libraries -// so that dex does not depend on any of them directly. -// It also includes a default implementation using Logrus (used by dex previously). -package log - -// Logger serves as an adapter interface for logger libraries -// so that dex does not depend on any of them directly. -type Logger interface { - Debug(args ...interface{}) - Info(args ...interface{}) - Warn(args ...interface{}) - Error(args ...interface{}) - - Debugf(format string, args ...interface{}) - Infof(format string, args ...interface{}) - Warnf(format string, args ...interface{}) - Errorf(format string, args ...interface{}) -} diff --git a/scripts/git-diff b/scripts/git-diff deleted file mode 100755 index 302ac2ce3e..0000000000 --- a/scripts/git-diff +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -e - -DIFF=$( git diff . ) -if [ "$DIFF" != "" ]; then - echo "$DIFF" >&2 - exit 1 -fi diff --git a/scripts/git-version b/scripts/git-version index 936641cb0b..a60cdc405d 100755 --- a/scripts/git-version +++ b/scripts/git-version @@ -1,5 +1,4 @@ #!/bin/sh -e -# Since this script will be run in a rkt container, use "/bin/sh" instead of "/bin/bash" # parse the current git commit hash COMMIT=`git rev-parse HEAD` diff --git a/server/api.go b/server/api.go index a68742b3cc..4fceae9617 100644 --- a/server/api.go +++ b/server/api.go @@ -2,20 +2,23 @@ package server import ( "context" + "encoding/json" "errors" "fmt" + "log/slog" + "strconv" "golang.org/x/crypto/bcrypt" "github.com/dexidp/dex/api/v2" - "github.com/dexidp/dex/pkg/log" + "github.com/dexidp/dex/pkg/featureflags" "github.com/dexidp/dex/server/internal" "github.com/dexidp/dex/storage" ) // apiVersion increases every time a new call is added to the API. Clients should use this info // to determine if the server supports specific features. -const apiVersion = 2 +const apiVersion = 3 const ( // recCost is the recommended bcrypt cost, which balances hash strength and @@ -29,11 +32,12 @@ const ( ) // NewAPI returns a server which implements the gRPC API interface. -func NewAPI(s storage.Storage, logger log.Logger, version string) api.DexServer { +func NewAPI(s storage.Storage, logger *slog.Logger, version string, server *Server) api.DexServer { return dexAPI{ s: s, - logger: logger, + logger: logger.With("component", "api"), version: version, + server: server, } } @@ -41,8 +45,28 @@ type dexAPI struct { api.UnimplementedDexServer s storage.Storage - logger log.Logger + logger *slog.Logger version string + server *Server +} + +func (d dexAPI) GetClient(ctx context.Context, req *api.GetClientReq) (*api.GetClientResp, error) { + c, err := d.s.GetClient(ctx, req.Id) + if err != nil { + return nil, err + } + + return &api.GetClientResp{ + Client: &api.Client{ + Id: c.ID, + Name: c.Name, + Secret: c.Secret, + RedirectUris: c.RedirectURIs, + TrustedPeers: c.TrustedPeers, + Public: c.Public, + LogoUrl: c.LogoURL, + }, + }, nil } func (d dexAPI) CreateClient(ctx context.Context, req *api.CreateClientReq) (*api.CreateClientResp, error) { @@ -66,11 +90,11 @@ func (d dexAPI) CreateClient(ctx context.Context, req *api.CreateClientReq) (*ap Name: req.Client.Name, LogoURL: req.Client.LogoUrl, } - if err := d.s.CreateClient(c); err != nil { + if err := d.s.CreateClient(ctx, c); err != nil { if err == storage.ErrAlreadyExists { return &api.CreateClientResp{AlreadyExists: true}, nil } - d.logger.Errorf("api: failed to create client: %v", err) + d.logger.Error("failed to create client", "err", err) return nil, fmt.Errorf("create client: %v", err) } @@ -84,7 +108,7 @@ func (d dexAPI) UpdateClient(ctx context.Context, req *api.UpdateClientReq) (*ap return nil, errors.New("update client: no client ID supplied") } - err := d.s.UpdateClient(req.Id, func(old storage.Client) (storage.Client, error) { + err := d.s.UpdateClient(ctx, req.Id, func(old storage.Client) (storage.Client, error) { if req.RedirectUris != nil { old.RedirectURIs = req.RedirectUris } @@ -103,24 +127,49 @@ func (d dexAPI) UpdateClient(ctx context.Context, req *api.UpdateClientReq) (*ap if err == storage.ErrNotFound { return &api.UpdateClientResp{NotFound: true}, nil } - d.logger.Errorf("api: failed to update the client: %v", err) + d.logger.Error("failed to update the client", "err", err) return nil, fmt.Errorf("update client: %v", err) } return &api.UpdateClientResp{}, nil } func (d dexAPI) DeleteClient(ctx context.Context, req *api.DeleteClientReq) (*api.DeleteClientResp, error) { - err := d.s.DeleteClient(req.Id) + err := d.s.DeleteClient(ctx, req.Id) if err != nil { if err == storage.ErrNotFound { return &api.DeleteClientResp{NotFound: true}, nil } - d.logger.Errorf("api: failed to delete client: %v", err) + d.logger.Error("failed to delete client", "err", err) return nil, fmt.Errorf("delete client: %v", err) } return &api.DeleteClientResp{}, nil } +func (d dexAPI) ListClients(ctx context.Context, req *api.ListClientReq) (*api.ListClientResp, error) { + clientList, err := d.s.ListClients(ctx) + if err != nil { + d.logger.Error("failed to list clients", "err", err) + return nil, fmt.Errorf("list clients: %v", err) + } + + clients := make([]*api.ClientInfo, 0, len(clientList)) + for _, client := range clientList { + c := api.ClientInfo{ + Id: client.ID, + Name: client.Name, + RedirectUris: client.RedirectURIs, + TrustedPeers: client.TrustedPeers, + Public: client.Public, + LogoUrl: client.LogoURL, + } + clients = append(clients, &c) + } + + return &api.ListClientResp{ + Clients: clients, + }, nil +} + // checkCost returns an error if the hash provided does not meet lower or upper // bound cost requirements. func checkCost(hash []byte) error { @@ -158,11 +207,11 @@ func (d dexAPI) CreatePassword(ctx context.Context, req *api.CreatePasswordReq) Username: req.Password.Username, UserID: req.Password.UserId, } - if err := d.s.CreatePassword(p); err != nil { + if err := d.s.CreatePassword(ctx, p); err != nil { if err == storage.ErrAlreadyExists { return &api.CreatePasswordResp{AlreadyExists: true}, nil } - d.logger.Errorf("api: failed to create password: %v", err) + d.logger.Error("failed to create password", "err", err) return nil, fmt.Errorf("create password: %v", err) } @@ -195,11 +244,11 @@ func (d dexAPI) UpdatePassword(ctx context.Context, req *api.UpdatePasswordReq) return old, nil } - if err := d.s.UpdatePassword(req.Email, updater); err != nil { + if err := d.s.UpdatePassword(ctx, req.Email, updater); err != nil { if err == storage.ErrNotFound { return &api.UpdatePasswordResp{NotFound: true}, nil } - d.logger.Errorf("api: failed to update password: %v", err) + d.logger.Error("failed to update password", "err", err) return nil, fmt.Errorf("update password: %v", err) } @@ -211,12 +260,12 @@ func (d dexAPI) DeletePassword(ctx context.Context, req *api.DeletePasswordReq) return nil, errors.New("no email supplied") } - err := d.s.DeletePassword(req.Email) + err := d.s.DeletePassword(ctx, req.Email) if err != nil { if err == storage.ErrNotFound { return &api.DeletePasswordResp{NotFound: true}, nil } - d.logger.Errorf("api: failed to delete password: %v", err) + d.logger.Error("failed to delete password", "err", err) return nil, fmt.Errorf("delete password: %v", err) } return &api.DeletePasswordResp{}, nil @@ -229,10 +278,24 @@ func (d dexAPI) GetVersion(ctx context.Context, req *api.VersionReq) (*api.Versi }, nil } +func (d dexAPI) GetDiscovery(ctx context.Context, req *api.DiscoveryReq) (*api.DiscoveryResp, error) { + discoveryDoc := d.server.constructDiscovery() + data, err := json.Marshal(discoveryDoc) + if err != nil { + return nil, fmt.Errorf("failed to marshal discovery data: %v", err) + } + resp := api.DiscoveryResp{} + err = json.Unmarshal(data, &resp) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal discovery data: %v", err) + } + return &resp, nil +} + func (d dexAPI) ListPasswords(ctx context.Context, req *api.ListPasswordReq) (*api.ListPasswordResp, error) { - passwordList, err := d.s.ListPasswords() + passwordList, err := d.s.ListPasswords(ctx) if err != nil { - d.logger.Errorf("api: failed to list passwords: %v", err) + d.logger.Error("failed to list passwords", "err", err) return nil, fmt.Errorf("list passwords: %v", err) } @@ -260,19 +323,19 @@ func (d dexAPI) VerifyPassword(ctx context.Context, req *api.VerifyPasswordReq) return nil, errors.New("no password to verify supplied") } - password, err := d.s.GetPassword(req.Email) + password, err := d.s.GetPassword(ctx, req.Email) if err != nil { if err == storage.ErrNotFound { return &api.VerifyPasswordResp{ NotFound: true, }, nil } - d.logger.Errorf("api: there was an error retrieving the password: %v", err) + d.logger.Error("there was an error retrieving the password", "err", err) return nil, fmt.Errorf("verify password: %v", err) } if err := bcrypt.CompareHashAndPassword(password.Hash, []byte(req.Password)); err != nil { - d.logger.Infof("api: password check failed: %v", err) + d.logger.Info("password check failed", "err", err) return &api.VerifyPasswordResp{ Verified: false, }, nil @@ -285,18 +348,18 @@ func (d dexAPI) VerifyPassword(ctx context.Context, req *api.VerifyPasswordReq) func (d dexAPI) ListRefresh(ctx context.Context, req *api.ListRefreshReq) (*api.ListRefreshResp, error) { id := new(internal.IDTokenSubject) if err := internal.Unmarshal(req.UserId, id); err != nil { - d.logger.Errorf("api: failed to unmarshal ID Token subject: %v", err) + d.logger.Error("failed to unmarshal ID Token subject", "err", err) return nil, err } - offlineSessions, err := d.s.GetOfflineSessions(id.UserId, id.ConnId) + offlineSessions, err := d.s.GetOfflineSessions(ctx, id.UserId, id.ConnId) if err != nil { if err == storage.ErrNotFound { // This means that this user-client pair does not have a refresh token yet. // An empty list should be returned instead of an error. return &api.ListRefreshResp{}, nil } - d.logger.Errorf("api: failed to list refresh tokens %t here : %v", err == storage.ErrNotFound, err) + d.logger.Error("failed to list refresh tokens here", "err", err) return nil, err } @@ -319,7 +382,7 @@ func (d dexAPI) ListRefresh(ctx context.Context, req *api.ListRefreshReq) (*api. func (d dexAPI) RevokeRefresh(ctx context.Context, req *api.RevokeRefreshReq) (*api.RevokeRefreshResp, error) { id := new(internal.IDTokenSubject) if err := internal.Unmarshal(req.UserId, id); err != nil { - d.logger.Errorf("api: failed to unmarshal ID Token subject: %v", err) + d.logger.Error("failed to unmarshal ID Token subject", "err", err) return nil, err } @@ -330,7 +393,7 @@ func (d dexAPI) RevokeRefresh(ctx context.Context, req *api.RevokeRefreshReq) (* updater := func(old storage.OfflineSessions) (storage.OfflineSessions, error) { refreshRef := old.Refresh[req.ClientId] if refreshRef == nil || refreshRef.ID == "" { - d.logger.Errorf("api: refresh token issued to client %q for user %q not found for deletion", req.ClientId, id.UserId) + d.logger.Error("refresh token issued to client not found for deletion", "client_id", req.ClientId, "user_id", id.UserId) notFound = true return old, storage.ErrNotFound } @@ -343,11 +406,11 @@ func (d dexAPI) RevokeRefresh(ctx context.Context, req *api.RevokeRefreshReq) (* return old, nil } - if err := d.s.UpdateOfflineSessions(id.UserId, id.ConnId, updater); err != nil { + if err := d.s.UpdateOfflineSessions(ctx, id.UserId, id.ConnId, updater); err != nil { if err == storage.ErrNotFound { return &api.RevokeRefreshResp{NotFound: true}, nil } - d.logger.Errorf("api: failed to update offline session object: %v", err) + d.logger.Error("failed to update offline session object", "err", err) return nil, err } @@ -359,10 +422,156 @@ func (d dexAPI) RevokeRefresh(ctx context.Context, req *api.RevokeRefreshReq) (* // // TODO(ericchiang): we don't have any good recourse if this call fails. // Consider garbage collection of refresh tokens with no associated ref. - if err := d.s.DeleteRefresh(refreshID); err != nil { - d.logger.Errorf("failed to delete refresh token: %v", err) + if err := d.s.DeleteRefresh(ctx, refreshID); err != nil { + d.logger.Error("failed to delete refresh token", "err", err) return nil, err } return &api.RevokeRefreshResp{}, nil } + +func (d dexAPI) CreateConnector(ctx context.Context, req *api.CreateConnectorReq) (*api.CreateConnectorResp, error) { + if !featureflags.APIConnectorsCRUD.Enabled() { + return nil, fmt.Errorf("%s feature flag is not enabled", featureflags.APIConnectorsCRUD.Name) + } + + if req.Connector.Id == "" { + return nil, errors.New("no id supplied") + } + + if req.Connector.Type == "" { + return nil, errors.New("no type supplied") + } + + if req.Connector.Name == "" { + return nil, errors.New("no name supplied") + } + + if len(req.Connector.Config) == 0 { + return nil, errors.New("no config supplied") + } + + if !json.Valid(req.Connector.Config) { + return nil, errors.New("invalid config supplied") + } + + c := storage.Connector{ + ID: req.Connector.Id, + Name: req.Connector.Name, + Type: req.Connector.Type, + ResourceVersion: "1", + Config: req.Connector.Config, + } + if err := d.s.CreateConnector(ctx, c); err != nil { + if err == storage.ErrAlreadyExists { + return &api.CreateConnectorResp{AlreadyExists: true}, nil + } + d.logger.Error("api: failed to create connector", "err", err) + return nil, fmt.Errorf("create connector: %v", err) + } + + return &api.CreateConnectorResp{}, nil +} + +func (d dexAPI) UpdateConnector(ctx context.Context, req *api.UpdateConnectorReq) (*api.UpdateConnectorResp, error) { + if !featureflags.APIConnectorsCRUD.Enabled() { + return nil, fmt.Errorf("%s feature flag is not enabled", featureflags.APIConnectorsCRUD.Name) + } + + if req.Id == "" { + return nil, errors.New("no email supplied") + } + + if len(req.NewConfig) == 0 && req.NewName == "" && req.NewType == "" { + return nil, errors.New("nothing to update") + } + + if !json.Valid(req.NewConfig) { + return nil, errors.New("invalid config supplied") + } + + updater := func(old storage.Connector) (storage.Connector, error) { + if req.NewType != "" { + old.Type = req.NewType + } + + if req.NewName != "" { + old.Name = req.NewName + } + + if len(req.NewConfig) != 0 { + old.Config = req.NewConfig + } + + if rev, err := strconv.Atoi(defaultTo(old.ResourceVersion, "0")); err == nil { + old.ResourceVersion = strconv.Itoa(rev + 1) + } + + return old, nil + } + + if err := d.s.UpdateConnector(ctx, req.Id, updater); err != nil { + if err == storage.ErrNotFound { + return &api.UpdateConnectorResp{NotFound: true}, nil + } + d.logger.Error("api: failed to update connector", "err", err) + return nil, fmt.Errorf("update connector: %v", err) + } + + return &api.UpdateConnectorResp{}, nil +} + +func (d dexAPI) DeleteConnector(ctx context.Context, req *api.DeleteConnectorReq) (*api.DeleteConnectorResp, error) { + if !featureflags.APIConnectorsCRUD.Enabled() { + return nil, fmt.Errorf("%s feature flag is not enabled", featureflags.APIConnectorsCRUD.Name) + } + + if req.Id == "" { + return nil, errors.New("no id supplied") + } + + err := d.s.DeleteConnector(ctx, req.Id) + if err != nil { + if err == storage.ErrNotFound { + return &api.DeleteConnectorResp{NotFound: true}, nil + } + d.logger.Error("api: failed to delete connector", "err", err) + return nil, fmt.Errorf("delete connector: %v", err) + } + return &api.DeleteConnectorResp{}, nil +} + +func (d dexAPI) ListConnectors(ctx context.Context, req *api.ListConnectorReq) (*api.ListConnectorResp, error) { + if !featureflags.APIConnectorsCRUD.Enabled() { + return nil, fmt.Errorf("%s feature flag is not enabled", featureflags.APIConnectorsCRUD.Name) + } + + connectorList, err := d.s.ListConnectors(ctx) + if err != nil { + d.logger.Error("api: failed to list connectors", "err", err) + return nil, fmt.Errorf("list connectors: %v", err) + } + + connectors := make([]*api.Connector, 0, len(connectorList)) + for _, connector := range connectorList { + c := api.Connector{ + Id: connector.ID, + Name: connector.Name, + Type: connector.Type, + Config: connector.Config, + } + connectors = append(connectors, &c) + } + + return &api.ListConnectorResp{ + Connectors: connectors, + }, nil +} + +func defaultTo[T comparable](v, def T) T { + var zeroT T + if v == zeroT { + return def + } + return v +} diff --git a/server/api_test.go b/server/api_test.go index 01c59cf875..5ddbcc4ac8 100644 --- a/server/api_test.go +++ b/server/api_test.go @@ -1,18 +1,17 @@ package server import ( - "context" + "log/slog" "net" - "os" + "slices" + "strings" "testing" "time" - "github.com/sirupsen/logrus" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "github.com/dexidp/dex/api/v2" - "github.com/dexidp/dex/pkg/log" "github.com/dexidp/dex/server/internal" "github.com/dexidp/dex/storage" "github.com/dexidp/dex/storage/memory" @@ -29,20 +28,24 @@ type apiClient struct { Close func() } +func newLogger(t *testing.T) *slog.Logger { + return slog.New(slog.NewTextHandler(t.Output(), &slog.HandlerOptions{Level: slog.LevelDebug})) +} + // newAPI constructs a gRCP client connected to a backing server. -func newAPI(s storage.Storage, logger log.Logger, t *testing.T) *apiClient { +func newAPI(t *testing.T, s storage.Storage, logger *slog.Logger) *apiClient { l, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) } serv := grpc.NewServer() - api.RegisterDexServer(serv, NewAPI(s, logger, "test")) + api.RegisterDexServer(serv, NewAPI(s, logger, "test", nil)) go serv.Serve(l) - // Dial will retry automatically if the serv.Serve() goroutine + // NewClient will retry automatically if the serv.Serve() goroutine // hasn't started yet. - conn, err := grpc.Dial(l.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) + conn, err := grpc.NewClient(l.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { t.Fatal(err) } @@ -59,17 +62,14 @@ func newAPI(s storage.Storage, logger log.Logger, t *testing.T) *apiClient { // Attempts to create, update and delete a test Password func TestPassword(t *testing.T) { - logger := &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, - } - + logger := newLogger(t) s := memory.New(logger) - client := newAPI(s, logger, t) + + client := newAPI(t, s, logger) defer client.Close() - ctx := context.Background() + ctx := t.Context() + email := "test@example.com" p := api.Password{ Email: email, @@ -152,7 +152,7 @@ func TestPassword(t *testing.T) { t.Fatalf("Unable to update password: %v", err) } - pass, err := s.GetPassword(updateReq.Email) + pass, err := s.GetPassword(ctx, updateReq.Email) if err != nil { t.Fatalf("Unable to retrieve password: %v", err) } @@ -172,14 +172,10 @@ func TestPassword(t *testing.T) { // Ensures checkCost returns expected values func TestCheckCost(t *testing.T) { - logger := &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, - } - + logger := newLogger(t) s := memory.New(logger) - client := newAPI(s, logger, t) + + client := newAPI(t, s, logger) defer client.Close() tests := []struct { @@ -229,17 +225,13 @@ func TestCheckCost(t *testing.T) { // Attempts to list and revoke an existing refresh token. func TestRefreshToken(t *testing.T) { - logger := &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, - } - + logger := newLogger(t) s := memory.New(logger) - client := newAPI(s, logger, t) + + client := newAPI(t, s, logger) defer client.Close() - ctx := context.Background() + ctx := t.Context() // Creating a storage with an existing refresh token and offline session for the user. id := storage.NewID() @@ -262,7 +254,7 @@ func TestRefreshToken(t *testing.T) { ConnectorData: []byte(`{"some":"data"}`), } - if err := s.CreateRefresh(r); err != nil { + if err := s.CreateRefresh(ctx, r); err != nil { t.Fatalf("create refresh token: %v", err) } @@ -280,7 +272,7 @@ func TestRefreshToken(t *testing.T) { } session.Refresh[tokenRef.ClientID] = &tokenRef - if err := s.CreateOfflineSessions(session); err != nil { + if err := s.CreateOfflineSessions(ctx, session); err != nil { t.Fatalf("create offline session: %v", err) } @@ -337,21 +329,18 @@ func TestRefreshToken(t *testing.T) { } if resp, _ := client.ListRefresh(ctx, &listReq); len(resp.RefreshTokens) != 0 { - t.Fatalf("Refresh token returned inspite of revoking it.") + t.Fatalf("Refresh token returned in spite of revoking it.") } } func TestUpdateClient(t *testing.T) { - logger := &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, - } - + logger := newLogger(t) s := memory.New(logger) - client := newAPI(s, logger, t) + + client := newAPI(t, s, logger) defer client.Close() - ctx := context.Background() + + ctx := t.Context() createClient := func(t *testing.T, clientId string) { resp, err := client.CreateClient(ctx, &api.CreateClientReq{ @@ -464,7 +453,7 @@ func TestUpdateClient(t *testing.T) { t.Errorf("expected in response NotFound: %t", tc.want.NotFound) } - client, err := s.GetClient(tc.req.Id) + client, err := s.GetClient(ctx, tc.req.Id) if err != nil { t.Errorf("no client found in the storage: %v", err) } @@ -479,13 +468,13 @@ func TestUpdateClient(t *testing.T) { t.Errorf("expected stored client with LogoURL: %s, found %s", tc.req.LogoUrl, client.LogoURL) } for _, redirectURI := range tc.req.RedirectUris { - found := find(redirectURI, client.RedirectURIs) + found := slices.Contains(client.RedirectURIs, redirectURI) if !found { t.Errorf("expected redirect URI: %s", redirectURI) } } for _, peer := range tc.req.TrustedPeers { - found := find(peer, client.TrustedPeers) + found := slices.Contains(client.TrustedPeers, peer) if !found { t.Errorf("expected trusted peer: %s", peer) } @@ -499,11 +488,340 @@ func TestUpdateClient(t *testing.T) { } } -func find(item string, items []string) bool { - for _, i := range items { - if item == i { - return true +func TestCreateConnector(t *testing.T) { + t.Setenv("DEX_API_CONNECTORS_CRUD", "true") + + logger := newLogger(t) + s := memory.New(logger) + + client := newAPI(t, s, logger) + defer client.Close() + + ctx := t.Context() + + connectorID := "connector123" + connectorName := "TestConnector" + connectorType := "TestType" + connectorConfig := []byte(`{"key": "value"}`) + + createReq := api.CreateConnectorReq{ + Connector: &api.Connector{ + Id: connectorID, + Name: connectorName, + Type: connectorType, + Config: connectorConfig, + }, + } + + // Test valid connector creation + if resp, err := client.CreateConnector(ctx, &createReq); err != nil || resp.AlreadyExists { + if err != nil { + t.Fatalf("Unable to create connector: %v", err) + } else if resp.AlreadyExists { + t.Fatalf("Unable to create connector since %s already exists", connectorID) + } + t.Fatalf("Unable to create connector: %v", err) + } + + // Test creating the same connector again (expecting failure) + if resp, _ := client.CreateConnector(ctx, &createReq); !resp.AlreadyExists { + t.Fatalf("Created connector %s twice", connectorID) + } + + createReq.Connector.Config = []byte("invalid_json") + + // Test invalid JSON config + if _, err := client.CreateConnector(ctx, &createReq); err == nil { + t.Fatal("Expected an error for invalid JSON config, but none occurred") + } else if !strings.Contains(err.Error(), "invalid config supplied") { + t.Fatalf("Unexpected error: %v", err) + } +} + +func TestUpdateConnector(t *testing.T) { + t.Setenv("DEX_API_CONNECTORS_CRUD", "true") + + logger := newLogger(t) + s := memory.New(logger) + + client := newAPI(t, s, logger) + defer client.Close() + + ctx := t.Context() + + connectorID := "connector123" + newConnectorName := "UpdatedConnector" + newConnectorType := "UpdatedType" + newConnectorConfig := []byte(`{"updated_key": "updated_value"}`) + + // Create a connector for testing + createReq := api.CreateConnectorReq{ + Connector: &api.Connector{ + Id: connectorID, + Name: "TestConnector", + Type: "TestType", + Config: []byte(`{"key": "value"}`), + }, + } + client.CreateConnector(ctx, &createReq) + + updateReq := api.UpdateConnectorReq{ + Id: connectorID, + NewName: newConnectorName, + NewType: newConnectorType, + NewConfig: newConnectorConfig, + } + + // Test valid connector update + if _, err := client.UpdateConnector(ctx, &updateReq); err != nil { + t.Fatalf("Unable to update connector: %v", err) + } + + resp, err := client.ListConnectors(ctx, &api.ListConnectorReq{}) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + for _, connector := range resp.Connectors { + if connector.Id == connectorID { + if connector.Name != newConnectorName { + t.Fatal("connector name should have been updated") + } + if string(connector.Config) != string(newConnectorConfig) { + t.Fatal("connector config should have been updated") + } + if connector.Type != newConnectorType { + t.Fatal("connector type should have been updated") + } + } + } + + updateReq.NewConfig = []byte("invalid_json") + + // Test invalid JSON config in update request + if _, err := client.UpdateConnector(ctx, &updateReq); err == nil { + t.Fatal("Expected an error for invalid JSON config in update, but none occurred") + } else if !strings.Contains(err.Error(), "invalid config supplied") { + t.Fatalf("Unexpected error: %v", err) + } +} + +func TestDeleteConnector(t *testing.T) { + t.Setenv("DEX_API_CONNECTORS_CRUD", "true") + + logger := newLogger(t) + s := memory.New(logger) + + client := newAPI(t, s, logger) + defer client.Close() + + ctx := t.Context() + + connectorID := "connector123" + + // Create a connector for testing + createReq := api.CreateConnectorReq{ + Connector: &api.Connector{ + Id: connectorID, + Name: "TestConnector", + Type: "TestType", + Config: []byte(`{"key": "value"}`), + }, + } + client.CreateConnector(ctx, &createReq) + + deleteReq := api.DeleteConnectorReq{ + Id: connectorID, + } + + // Test valid connector deletion + if _, err := client.DeleteConnector(ctx, &deleteReq); err != nil { + t.Fatalf("Unable to delete connector: %v", err) + } + + // Test non existent connector deletion + resp, err := client.DeleteConnector(ctx, &deleteReq) + if err != nil { + t.Fatalf("Unable to delete connector: %v", err) + } + + if !resp.NotFound { + t.Fatal("Should return not found") + } +} + +func TestListConnectors(t *testing.T) { + t.Setenv("DEX_API_CONNECTORS_CRUD", "true") + + logger := newLogger(t) + s := memory.New(logger) + + client := newAPI(t, s, logger) + defer client.Close() + + ctx := t.Context() + + // Create connectors for testing + createReq1 := api.CreateConnectorReq{ + Connector: &api.Connector{ + Id: "connector1", + Name: "Connector1", + Type: "Type1", + Config: []byte(`{"key": "value1"}`), + }, + } + client.CreateConnector(ctx, &createReq1) + + createReq2 := api.CreateConnectorReq{ + Connector: &api.Connector{ + Id: "connector2", + Name: "Connector2", + Type: "Type2", + Config: []byte(`{"key": "value2"}`), + }, + } + client.CreateConnector(ctx, &createReq2) + + listReq := api.ListConnectorReq{} + + // Test listing connectors + if resp, err := client.ListConnectors(ctx, &listReq); err != nil { + t.Fatalf("Unable to list connectors: %v", err) + } else if len(resp.Connectors) != 2 { // Check the number of connectors in the response + t.Fatalf("Expected 2 connectors, found %d", len(resp.Connectors)) + } +} + +func TestMissingConnectorsCRUDFeatureFlag(t *testing.T) { + logger := newLogger(t) + s := memory.New(logger) + + client := newAPI(t, s, logger) + defer client.Close() + + ctx := t.Context() + + // Create connectors for testing + createReq1 := api.CreateConnectorReq{ + Connector: &api.Connector{ + Id: "connector1", + Name: "Connector1", + Type: "Type1", + Config: []byte(`{"key": "value1"}`), + }, + } + client.CreateConnector(ctx, &createReq1) + + createReq2 := api.CreateConnectorReq{ + Connector: &api.Connector{ + Id: "connector2", + Name: "Connector2", + Type: "Type2", + Config: []byte(`{"key": "value2"}`), + }, + } + client.CreateConnector(ctx, &createReq2) + + listReq := api.ListConnectorReq{} + + if _, err := client.ListConnectors(ctx, &listReq); err == nil { + t.Fatal("ListConnectors should have returned an error") + } +} + +func TestListClients(t *testing.T) { + logger := newLogger(t) + s := memory.New(logger) + + client := newAPI(t, s, logger) + defer client.Close() + + ctx := t.Context() + + // List Clients + listResp, err := client.ListClients(ctx, &api.ListClientReq{}) + if err != nil { + t.Fatalf("Unable to list clients: %v", err) + } + if len(listResp.Clients) != 0 { + t.Fatalf("Expected 0 clients, got %d", len(listResp.Clients)) + } + + client1 := &api.Client{ + Id: "client1", + Secret: "secret1", + RedirectUris: []string{"http://localhost:8080/callback"}, + TrustedPeers: []string{"peer1"}, + Public: false, + Name: "Test Client 1", + LogoUrl: "http://example.com/logo1.png", + } + + client2 := &api.Client{ + Id: "client2", + Secret: "secret2", + RedirectUris: []string{"http://localhost:8081/callback"}, + TrustedPeers: []string{"peer2"}, + Public: true, + Name: "Test Client 2", + LogoUrl: "http://example.com/logo2.png", + } + + _, err = client.CreateClient(ctx, &api.CreateClientReq{Client: client1}) + if err != nil { + t.Fatalf("Unable to create client1: %v", err) + } + + _, err = client.CreateClient(ctx, &api.CreateClientReq{Client: client2}) + if err != nil { + t.Fatalf("Unable to create client2: %v", err) + } + + listResp, err = client.ListClients(ctx, &api.ListClientReq{}) + if err != nil { + t.Fatalf("Unable to list clients: %v", err) + } + + if len(listResp.Clients) != 2 { + t.Fatalf("Expected 2 clients, got %d", len(listResp.Clients)) + } + + clientMap := make(map[string]*api.ClientInfo) + for _, c := range listResp.Clients { + clientMap[c.Id] = c + } + + if c1, exists := clientMap["client1"]; !exists { + t.Fatal("client1 not found in list") + } else { + if c1.Name != "Test Client 1" { + t.Errorf("Expected client1 name 'Test Client 1', got '%s'", c1.Name) + } + if len(c1.RedirectUris) != 1 || c1.RedirectUris[0] != "http://localhost:8080/callback" { + t.Errorf("Expected client1 redirect URIs ['http://localhost:8080/callback'], got %v", c1.RedirectUris) + } + if c1.Public != false { + t.Errorf("Expected client1 public false, got %v", c1.Public) + } + if c1.LogoUrl != "http://example.com/logo1.png" { + t.Errorf("Expected client1 logo URL 'http://example.com/logo1.png', got '%s'", c1.LogoUrl) + } + } + + if c2, exists := clientMap["client2"]; !exists { + t.Fatal("client2 not found in list") + } else { + if c2.Name != "Test Client 2" { + t.Errorf("Expected client2 name 'Test Client 2', got '%s'", c2.Name) + } + if len(c2.RedirectUris) != 1 || c2.RedirectUris[0] != "http://localhost:8081/callback" { + t.Errorf("Expected client2 redirect URIs ['http://localhost:8081/callback'], got %v", c2.RedirectUris) + } + if c2.Public != true { + t.Errorf("Expected client2 public true, got %v", c2.Public) + } + if c2.LogoUrl != "http://example.com/logo2.png" { + t.Errorf("Expected client2 logo URL 'http://example.com/logo2.png', got '%s'", c2.LogoUrl) } } - return false } diff --git a/server/deviceflowhandlers.go b/server/deviceflowhandlers.go index 95fed3b3c3..3cbfbf16c2 100644 --- a/server/deviceflowhandlers.go +++ b/server/deviceflowhandlers.go @@ -13,7 +13,6 @@ import ( "golang.org/x/net/html" - "github.com/dexidp/dex/pkg/log" "github.com/dexidp/dex/storage" ) @@ -49,7 +48,7 @@ func (s *Server) handleDeviceExchange(w http.ResponseWriter, r *http.Request) { invalidAttempt = false } if err := s.templates.device(r, w, s.getDeviceVerificationURI(), userCode, invalidAttempt); err != nil { - s.logger.Errorf("Server template error: %v", err) + s.logger.ErrorContext(r.Context(), "server template error", "err", err) s.renderError(r, w, http.StatusNotFound, "Page not found") } default: @@ -58,13 +57,14 @@ func (s *Server) handleDeviceExchange(w http.ResponseWriter, r *http.Request) { } func (s *Server) handleDeviceCode(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() pollIntervalSeconds := 5 switch r.Method { case http.MethodPost: err := r.ParseForm() if err != nil { - s.logger.Errorf("Could not parse Device Request body: %v", err) + s.logger.ErrorContext(r.Context(), "could not parse Device Request body", "err", err) s.tokenErrHelper(w, errInvalidRequest, "", http.StatusNotFound) return } @@ -85,7 +85,13 @@ func (s *Server) handleDeviceCode(w http.ResponseWriter, r *http.Request) { return } - s.logger.Infof("Received device request for client %v with scopes %v", clientID, scopes) + if len(scopes) == 0 { + // per RFC8628 section 3.1, https://datatracker.ietf.org/doc/html/rfc8628#section-3.1 + // scope is optional but dex requires that it is always at least 'openid' so default it + scopes = []string{"openid"} + } + + s.logger.InfoContext(r.Context(), "received device request", "client_id", clientID, "scoped", scopes) // Make device code deviceCode := storage.NewDeviceCode() @@ -106,8 +112,8 @@ func (s *Server) handleDeviceCode(w http.ResponseWriter, r *http.Request) { Expiry: expireTime, } - if err := s.storage.CreateDeviceRequest(deviceReq); err != nil { - s.logger.Errorf("Failed to store device request; %v", err) + if err := s.storage.CreateDeviceRequest(ctx, deviceReq); err != nil { + s.logger.ErrorContext(r.Context(), "failed to store device request", "err", err) s.tokenErrHelper(w, errInvalidRequest, "", http.StatusInternalServerError) return } @@ -125,15 +131,15 @@ func (s *Server) handleDeviceCode(w http.ResponseWriter, r *http.Request) { }, } - if err := s.storage.CreateDeviceToken(deviceToken); err != nil { - s.logger.Errorf("Failed to store device token %v", err) + if err := s.storage.CreateDeviceToken(ctx, deviceToken); err != nil { + s.logger.ErrorContext(r.Context(), "failed to store device token", "err", err) s.tokenErrHelper(w, errInvalidRequest, "", http.StatusInternalServerError) return } u, err := url.Parse(s.issuerURL.String()) if err != nil { - s.logger.Errorf("Could not parse issuer URL %v", err) + s.logger.ErrorContext(r.Context(), "could not parse issuer URL", "err", err) s.tokenErrHelper(w, errInvalidRequest, "", http.StatusInternalServerError) return } @@ -174,14 +180,14 @@ func (s *Server) handleDeviceCode(w http.ResponseWriter, r *http.Request) { } func (s *Server) handleDeviceTokenDeprecated(w http.ResponseWriter, r *http.Request) { - log.Deprecated(s.logger, `The /device/token endpoint was called. It will be removed, use /token instead.`) + s.logger.Warn(`the /device/token endpoint was called. It will be removed, use /token instead.`, "deprecated", true) w.Header().Set("Content-Type", "application/json") switch r.Method { case http.MethodPost: err := r.ParseForm() if err != nil { - s.logger.Warnf("Could not parse Device Token Request body: %v", err) + s.logger.Warn("could not parse Device Token Request body", "err", err) s.tokenErrHelper(w, errInvalidRequest, "", http.StatusBadRequest) return } @@ -199,6 +205,7 @@ func (s *Server) handleDeviceTokenDeprecated(w http.ResponseWriter, r *http.Requ } func (s *Server) handleDeviceToken(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() deviceCode := r.Form.Get("device_code") if deviceCode == "" { s.tokenErrHelper(w, errInvalidRequest, "No device code received", http.StatusBadRequest) @@ -208,10 +215,10 @@ func (s *Server) handleDeviceToken(w http.ResponseWriter, r *http.Request) { now := s.now() // Grab the device token, check validity - deviceToken, err := s.storage.GetDeviceToken(deviceCode) + deviceToken, err := s.storage.GetDeviceToken(ctx, deviceCode) if err != nil { if err != storage.ErrNotFound { - s.logger.Errorf("failed to get device code: %v", err) + s.logger.ErrorContext(r.Context(), "failed to get device code", "err", err) } s.tokenErrHelper(w, errInvalidRequest, "Invalid Device code.", http.StatusBadRequest) return @@ -240,15 +247,15 @@ func (s *Server) handleDeviceToken(w http.ResponseWriter, r *http.Request) { return old, nil } // Update device token last request time in storage - if err := s.storage.UpdateDeviceToken(deviceCode, updater); err != nil { - s.logger.Errorf("failed to update device token: %v", err) + if err := s.storage.UpdateDeviceToken(ctx, deviceCode, updater); err != nil { + s.logger.ErrorContext(r.Context(), "failed to update device token", "err", err) s.renderError(r, w, http.StatusInternalServerError, "") return } if slowDown { s.tokenErrHelper(w, deviceTokenSlowDown, "", http.StatusBadRequest) } else { - s.tokenErrHelper(w, deviceTokenPending, "", http.StatusUnauthorized) + s.tokenErrHelper(w, deviceTokenPending, "", http.StatusBadRequest) } case deviceTokenComplete: codeChallengeFromStorage := deviceToken.PKCE.CodeChallenge @@ -258,7 +265,7 @@ func (s *Server) handleDeviceToken(w http.ResponseWriter, r *http.Request) { case providedCodeVerifier != "" && codeChallengeFromStorage != "": calculatedCodeChallenge, err := s.calculateCodeChallenge(providedCodeVerifier, deviceToken.PKCE.CodeChallengeMethod) if err != nil { - s.logger.Error(err) + s.logger.ErrorContext(r.Context(), "failed to calculate code challenge", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) return } @@ -280,6 +287,7 @@ func (s *Server) handleDeviceToken(w http.ResponseWriter, r *http.Request) { } func (s *Server) handleDeviceCallback(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() switch r.Method { case http.MethodGet: userCode := r.FormValue("state") @@ -298,11 +306,11 @@ func (s *Server) handleDeviceCallback(w http.ResponseWriter, r *http.Request) { return } - authCode, err := s.storage.GetAuthCode(code) + authCode, err := s.storage.GetAuthCode(ctx, code) if err != nil || s.now().After(authCode.Expiry) { errCode := http.StatusBadRequest if err != nil && err != storage.ErrNotFound { - s.logger.Errorf("failed to get auth code: %v", err) + s.logger.ErrorContext(r.Context(), "failed to get auth code", "err", err) errCode = http.StatusInternalServerError } s.renderError(r, w, errCode, "Invalid or expired auth code.") @@ -310,21 +318,21 @@ func (s *Server) handleDeviceCallback(w http.ResponseWriter, r *http.Request) { } // Grab the device request from storage - deviceReq, err := s.storage.GetDeviceRequest(userCode) + deviceReq, err := s.storage.GetDeviceRequest(ctx, userCode) if err != nil || s.now().After(deviceReq.Expiry) { errCode := http.StatusBadRequest if err != nil && err != storage.ErrNotFound { - s.logger.Errorf("failed to get device code: %v", err) + s.logger.ErrorContext(r.Context(), "failed to get device code", "err", err) errCode = http.StatusInternalServerError } s.renderError(r, w, errCode, "Invalid or expired user code.") return } - client, err := s.storage.GetClient(deviceReq.ClientID) + client, err := s.storage.GetClient(ctx, deviceReq.ClientID) if err != nil { if err != storage.ErrNotFound { - s.logger.Errorf("failed to get client: %v", err) + s.logger.ErrorContext(r.Context(), "failed to get client", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) } else { s.tokenErrHelper(w, errInvalidClient, "Invalid client credentials.", http.StatusUnauthorized) @@ -336,19 +344,19 @@ func (s *Server) handleDeviceCallback(w http.ResponseWriter, r *http.Request) { return } - resp, err := s.exchangeAuthCode(w, authCode, client) + resp, err := s.exchangeAuthCode(ctx, w, authCode, client) if err != nil { - s.logger.Errorf("Could not exchange auth code for client %q: %v", deviceReq.ClientID, err) + s.logger.ErrorContext(r.Context(), "could not exchange auth code for clien", "client_id", deviceReq.ClientID, "err", err) s.renderError(r, w, http.StatusInternalServerError, "Failed to exchange auth code.") return } // Grab the device token from storage - old, err := s.storage.GetDeviceToken(deviceReq.DeviceCode) + old, err := s.storage.GetDeviceToken(ctx, deviceReq.DeviceCode) if err != nil || s.now().After(old.Expiry) { errCode := http.StatusBadRequest if err != nil && err != storage.ErrNotFound { - s.logger.Errorf("failed to get device token: %v", err) + s.logger.ErrorContext(r.Context(), "failed to get device token", "err", err) errCode = http.StatusInternalServerError } s.renderError(r, w, errCode, "Invalid or expired device code.") @@ -361,7 +369,7 @@ func (s *Server) handleDeviceCallback(w http.ResponseWriter, r *http.Request) { } respStr, err := json.MarshalIndent(resp, "", " ") if err != nil { - s.logger.Errorf("failed to marshal device token response: %v", err) + s.logger.ErrorContext(r.Context(), "failed to marshal device token response", "err", err) s.renderError(r, w, http.StatusInternalServerError, "") return old, err } @@ -372,14 +380,14 @@ func (s *Server) handleDeviceCallback(w http.ResponseWriter, r *http.Request) { } // Update refresh token in the storage, store the token and mark as complete - if err := s.storage.UpdateDeviceToken(deviceReq.DeviceCode, updater); err != nil { - s.logger.Errorf("failed to update device token: %v", err) + if err := s.storage.UpdateDeviceToken(ctx, deviceReq.DeviceCode, updater); err != nil { + s.logger.ErrorContext(r.Context(), "failed to update device token", "err", err) s.renderError(r, w, http.StatusBadRequest, "") return } if err := s.templates.deviceSuccess(r, w, client.Name); err != nil { - s.logger.Errorf("Server template error: %v", err) + s.logger.ErrorContext(r.Context(), "Server template error", "err", err) s.renderError(r, w, http.StatusNotFound, "Page not found") } @@ -390,11 +398,12 @@ func (s *Server) handleDeviceCallback(w http.ResponseWriter, r *http.Request) { } func (s *Server) verifyUserCode(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() switch r.Method { case http.MethodPost: err := r.ParseForm() if err != nil { - s.logger.Warnf("Could not parse user code verification request body : %v", err) + s.logger.Warn("could not parse user code verification request body", "err", err) s.renderError(r, w, http.StatusBadRequest, "") return } @@ -408,13 +417,13 @@ func (s *Server) verifyUserCode(w http.ResponseWriter, r *http.Request) { userCode = strings.ToUpper(userCode) // Find the user code in the available requests - deviceRequest, err := s.storage.GetDeviceRequest(userCode) + deviceRequest, err := s.storage.GetDeviceRequest(ctx, userCode) if err != nil || s.now().After(deviceRequest.Expiry) { if err != nil && err != storage.ErrNotFound { - s.logger.Errorf("failed to get device request: %v", err) + s.logger.ErrorContext(r.Context(), "failed to get device request", "err", err) } if err := s.templates.device(r, w, s.getDeviceVerificationURI(), userCode, true); err != nil { - s.logger.Errorf("Server template error: %v", err) + s.logger.ErrorContext(r.Context(), "Server template error", "err", err) s.renderError(r, w, http.StatusNotFound, "Page not found") } return diff --git a/server/deviceflowhandlers_test.go b/server/deviceflowhandlers_test.go index 9a9f28584e..3f3ea81efc 100644 --- a/server/deviceflowhandlers_test.go +++ b/server/deviceflowhandlers_test.go @@ -2,7 +2,6 @@ package server import ( "bytes" - "context" "encoding/json" "io" "net/http" @@ -20,10 +19,8 @@ func TestDeviceVerificationURI(t *testing.T) { t0 := time.Now() now := func() time.Time { return t0 } - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() // Setup a dex server. - httpServer, s := newTestServer(ctx, t, func(c *Config) { + httpServer, s := newTestServer(t, func(c *Config) { c.Issuer += "/non-root-path" c.Now = now }) @@ -90,14 +87,19 @@ func TestHandleDeviceCode(t *testing.T) { expectedResponseCode: http.StatusBadRequest, expectedContentType: "application/json", }, + { + testName: "New Code without scope", + clientID: "test", + requestType: "POST", + scopes: []string{}, + expectedResponseCode: http.StatusOK, + expectedContentType: "application/json", + }, } for _, tc := range tests { t.Run(tc.testName, func(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - // Setup a dex server. - httpServer, s := newTestServer(ctx, t, func(c *Config) { + httpServer, s := newTestServer(t, func(c *Config) { c.Issuer += "/non-root-path" c.Now = now }) @@ -356,25 +358,24 @@ func TestDeviceCallback(t *testing.T) { } for _, tc := range tests { t.Run(tc.testName, func(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() // Setup a dex server. - httpServer, s := newTestServer(ctx, t, func(c *Config) { + httpServer, s := newTestServer(t, func(c *Config) { // c.Issuer = c.Issuer + "/non-root-path" c.Now = now }) defer httpServer.Close() - if err := s.storage.CreateAuthCode(tc.testAuthCode); err != nil { + if err := s.storage.CreateAuthCode(ctx, tc.testAuthCode); err != nil { t.Fatalf("failed to create auth code: %v", err) } - if err := s.storage.CreateDeviceRequest(tc.testDeviceRequest); err != nil { + if err := s.storage.CreateDeviceRequest(ctx, tc.testDeviceRequest); err != nil { t.Fatalf("failed to create device request: %v", err) } - if err := s.storage.CreateDeviceToken(tc.testDeviceToken); err != nil { + if err := s.storage.CreateDeviceToken(ctx, tc.testDeviceToken); err != nil { t.Fatalf("failed to create device token: %v", err) } @@ -383,7 +384,7 @@ func TestDeviceCallback(t *testing.T) { Secret: "", RedirectURIs: []string{deviceCallbackURI}, } - if err := s.storage.CreateClient(client); err != nil { + if err := s.storage.CreateClient(ctx, client); err != nil { t.Fatalf("failed to create client: %v", err) } @@ -459,7 +460,7 @@ func TestDeviceTokenResponse(t *testing.T) { }, testDeviceCode: "f00bar", expectedServerResponse: deviceTokenPending, - expectedResponseCode: http.StatusUnauthorized, + expectedResponseCode: http.StatusBadRequest, }, { testName: "Invalid Grant Type", @@ -508,7 +509,7 @@ func TestDeviceTokenResponse(t *testing.T) { expectedResponseCode: http.StatusBadRequest, }, { - testName: "Test Non-existent Device Code", + testName: "Test Nonexistent Device Code", testDeviceRequest: baseDeviceRequest, testDeviceToken: storage.DeviceToken{ DeviceCode: "foo", @@ -650,21 +651,20 @@ func TestDeviceTokenResponse(t *testing.T) { } for _, tc := range tests { t.Run(tc.testName, func(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() // Setup a dex server. - httpServer, s := newTestServer(ctx, t, func(c *Config) { + httpServer, s := newTestServer(t, func(c *Config) { c.Issuer += "/non-root-path" c.Now = now }) defer httpServer.Close() - if err := s.storage.CreateDeviceRequest(tc.testDeviceRequest); err != nil { + if err := s.storage.CreateDeviceRequest(ctx, tc.testDeviceRequest); err != nil { t.Fatalf("Failed to store device token %v", err) } - if err := s.storage.CreateDeviceToken(tc.testDeviceToken); err != nil { + if err := s.storage.CreateDeviceToken(ctx, tc.testDeviceToken); err != nil { t.Fatalf("Failed to store device token %v", err) } @@ -707,7 +707,7 @@ func TestDeviceTokenResponse(t *testing.T) { } func expectJSONErrorResponse(testCase string, body []byte, expectedError string, t *testing.T) { - jsonMap := make(map[string]interface{}) + jsonMap := make(map[string]any) err := json.Unmarshal(body, &jsonMap) if err != nil { t.Errorf("Unexpected error unmarshalling response: %v", err) @@ -784,17 +784,16 @@ func TestVerifyCodeResponse(t *testing.T) { } for _, tc := range tests { t.Run(tc.testName, func(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() // Setup a dex server. - httpServer, s := newTestServer(ctx, t, func(c *Config) { + httpServer, s := newTestServer(t, func(c *Config) { c.Issuer += "/non-root-path" c.Now = now }) defer httpServer.Close() - if err := s.storage.CreateDeviceRequest(tc.testDeviceRequest); err != nil { + if err := s.storage.CreateDeviceRequest(ctx, tc.testDeviceRequest); err != nil { t.Fatalf("Failed to store device token %v", err) } diff --git a/server/handlers.go b/server/handlers.go old mode 100755 new mode 100644 index 5f8caf11af..f8d0ed64c3 --- a/server/handlers.go +++ b/server/handlers.go @@ -1,6 +1,8 @@ package server import ( + "context" + "crypto/hmac" "crypto/sha256" "crypto/subtle" "encoding/base64" @@ -16,8 +18,8 @@ import ( "time" "github.com/coreos/go-oidc/v3/oidc" + "github.com/go-jose/go-jose/v4" "github.com/gorilla/mux" - jose "gopkg.in/square/go-jose.v2" "github.com/dexidp/dex/connector" "github.com/dexidp/dex/server/internal" @@ -30,16 +32,17 @@ const ( ) func (s *Server) handlePublicKeys(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() // TODO(ericchiang): Cache this. - keys, err := s.storage.GetKeys() + keys, err := s.storage.GetKeys(ctx) if err != nil { - s.logger.Errorf("failed to get keys: %v", err) + s.logger.ErrorContext(r.Context(), "failed to get keys", "err", err) s.renderError(r, w, http.StatusInternalServerError, "Internal server error.") return } if keys.SigningKeyPub == nil { - s.logger.Errorf("No public keys found.") + s.logger.ErrorContext(r.Context(), "no public keys found.") s.renderError(r, w, http.StatusInternalServerError, "Internal server error.") return } @@ -54,7 +57,7 @@ func (s *Server) handlePublicKeys(w http.ResponseWriter, r *http.Request) { data, err := json.MarshalIndent(jwks, "", " ") if err != nil { - s.logger.Errorf("failed to marshal discovery data: %v", err) + s.logger.ErrorContext(r.Context(), "failed to marshal discovery data", "err", err) s.renderError(r, w, http.StatusInternalServerError, "Internal server error.") return } @@ -76,6 +79,7 @@ type discovery struct { Keys string `json:"jwks_uri"` UserInfo string `json:"userinfo_endpoint"` DeviceEndpoint string `json:"device_authorization_endpoint"` + Introspect string `json:"introspection_endpoint"` GrantTypes []string `json:"grant_types_supported"` ResponseTypes []string `json:"response_types_supported"` Subjects []string `json:"subject_types_supported"` @@ -87,6 +91,21 @@ type discovery struct { } func (s *Server) discoveryHandler() (http.HandlerFunc, error) { + d := s.constructDiscovery() + + data, err := json.MarshalIndent(d, "", " ") + if err != nil { + return nil, fmt.Errorf("failed to marshal discovery data: %v", err) + } + + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.Header().Set("Content-Length", strconv.Itoa(len(data))) + w.Write(data) + }), nil +} + +func (s *Server) constructDiscovery() discovery { d := discovery{ Issuer: s.issuerURL.String(), Auth: s.absURL("/auth"), @@ -94,6 +113,7 @@ func (s *Server) discoveryHandler() (http.HandlerFunc, error) { Keys: s.absURL("/keys"), UserInfo: s.absURL("/userinfo"), DeviceEndpoint: s.absURL("/device/code"), + Introspect: s.absURL("/token/introspect"), Subjects: []string{"public"}, IDTokenAlgs: []string{string(jose.RS256)}, CodeChallengeAlgs: []string{codeChallengeMethodS256, codeChallengeMethodPlain}, @@ -111,34 +131,24 @@ func (s *Server) discoveryHandler() (http.HandlerFunc, error) { sort.Strings(d.ResponseTypes) d.GrantTypes = s.supportedGrantTypes - - data, err := json.MarshalIndent(d, "", " ") - if err != nil { - return nil, fmt.Errorf("failed to marshal discovery data: %v", err) - } - - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - w.Header().Set("Content-Length", strconv.Itoa(len(data))) - w.Write(data) - }), nil + return d } // handleAuthorization handles the OAuth2 auth endpoint. func (s *Server) handleAuthorization(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() // Extract the arguments if err := r.ParseForm(); err != nil { - s.logger.Errorf("Failed to parse arguments: %v", err) + s.logger.ErrorContext(r.Context(), "failed to parse arguments", "err", err) s.renderError(r, w, http.StatusBadRequest, err.Error()) return } connectorID := r.Form.Get("connector_id") - - connectors, err := s.storage.ListConnectors() + connectors, err := s.storage.ListConnectors(ctx) if err != nil { - s.logger.Errorf("Failed to get list of connectors: %v", err) + s.logger.ErrorContext(r.Context(), "failed to get list of connectors", "err", err) s.renderError(r, w, http.StatusInternalServerError, "Failed to retrieve connector list.") return } @@ -181,14 +191,15 @@ func (s *Server) handleAuthorization(w http.ResponseWriter, r *http.Request) { } if err := s.templates.login(r, w, connectorInfos); err != nil { - s.logger.Errorf("Server template error: %v", err) + s.logger.ErrorContext(r.Context(), "server template error", "err", err) } } func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() authReq, err := s.parseAuthorizationRequest(r) if err != nil { - s.logger.Errorf("Failed to parse authorization request: %v", err) + s.logger.ErrorContext(r.Context(), "failed to parse authorization request", "err", err) switch authErr := err.(type) { case *redirectedAuthErr: @@ -204,22 +215,22 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) { connID, err := url.PathUnescape(mux.Vars(r)["connector"]) if err != nil { - s.logger.Errorf("Failed to parse connector: %v", err) + s.logger.ErrorContext(r.Context(), "failed to parse connector", "err", err) s.renderError(r, w, http.StatusBadRequest, "Requested resource does not exist") return } - conn, err := s.getConnector(connID) + conn, err := s.getConnector(ctx, connID) if err != nil { - s.logger.Errorf("Failed to get connector: %v", err) - s.renderError(r, w, http.StatusBadRequest, "Requested resource does not exist") + s.logger.ErrorContext(r.Context(), "Failed to get connector", "err", err) + s.renderError(r, w, http.StatusBadRequest, "Connector failed to initialize") return } // Set the connector being used for the login. if authReq.ConnectorID != "" && authReq.ConnectorID != connID { - s.logger.Errorf("Mismatched connector ID in auth request: %s vs %s", - authReq.ConnectorID, connID) + s.logger.ErrorContext(r.Context(), "mismatched connector ID in auth request", + "auth_request_connector_id", authReq.ConnectorID, "connector_id", connID) s.renderError(r, w, http.StatusBadRequest, "Bad connector ID") return } @@ -228,8 +239,8 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) { // Actually create the auth request authReq.Expiry = s.now().Add(s.authRequestsValidFor) - if err := s.storage.CreateAuthRequest(*authReq); err != nil { - s.logger.Errorf("Failed to create authorization request: %v", err) + if err := s.storage.CreateAuthRequest(ctx, *authReq); err != nil { + s.logger.ErrorContext(r.Context(), "failed to create authorization request", "err", err) s.renderError(r, w, http.StatusInternalServerError, "Failed to connect to the database.") return } @@ -255,7 +266,7 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) { // TODO(ericchiang): Is this appropriate or should we also be using a nonce? callbackURL, err := conn.LoginURL(scopes, s.absURL("/callback"), authReq.ID) if err != nil { - s.logger.Errorf("Connector %q returned error when creating callback: %v", connID, err) + s.logger.ErrorContext(r.Context(), "connector returned error when creating callback", "connector_id", connID, "err", err) s.renderError(r, w, http.StatusInternalServerError, "Login error.") return } @@ -273,7 +284,7 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) { case connector.SAMLConnector: action, value, err := conn.POSTData(scopes, authReq.ID) if err != nil { - s.logger.Errorf("Creating SAML data: %v", err) + s.logger.ErrorContext(r.Context(), "creating SAML data", "err", err) s.renderError(r, w, http.StatusInternalServerError, "Connector Login Error") return } @@ -304,6 +315,7 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) { } func (s *Server) handlePasswordLogin(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() authID := r.URL.Query().Get("state") if authID == "" { s.renderError(r, w, http.StatusBadRequest, "User session error.") @@ -312,39 +324,39 @@ func (s *Server) handlePasswordLogin(w http.ResponseWriter, r *http.Request) { backLink := r.URL.Query().Get("back") - authReq, err := s.storage.GetAuthRequest(authID) + authReq, err := s.storage.GetAuthRequest(ctx, authID) if err != nil { if err == storage.ErrNotFound { - s.logger.Errorf("Invalid 'state' parameter provided: %v", err) + s.logger.ErrorContext(r.Context(), "invalid 'state' parameter provided", "err", err) s.renderError(r, w, http.StatusBadRequest, "Requested resource does not exist.") return } - s.logger.Errorf("Failed to get auth request: %v", err) + s.logger.ErrorContext(r.Context(), "failed to get auth request", "err", err) s.renderError(r, w, http.StatusInternalServerError, "Database error.") return } connID, err := url.PathUnescape(mux.Vars(r)["connector"]) if err != nil { - s.logger.Errorf("Failed to parse connector: %v", err) + s.logger.ErrorContext(r.Context(), "failed to parse connector", "err", err) s.renderError(r, w, http.StatusBadRequest, "Requested resource does not exist") return } else if connID != "" && connID != authReq.ConnectorID { - s.logger.Errorf("Connector mismatch: authentication started with id %q, but password login for id %q was triggered", authReq.ConnectorID, connID) + s.logger.ErrorContext(r.Context(), "connector mismatch: password login triggered for different connector from authentication start", "start_connector_id", authReq.ConnectorID, "password_connector_id", connID) s.renderError(r, w, http.StatusInternalServerError, "Requested resource does not exist.") return } - conn, err := s.getConnector(authReq.ConnectorID) + conn, err := s.getConnector(ctx, authReq.ConnectorID) if err != nil { - s.logger.Errorf("Failed to get connector with id %q : %v", authReq.ConnectorID, err) - s.renderError(r, w, http.StatusInternalServerError, "Requested resource does not exist.") + s.logger.ErrorContext(r.Context(), "failed to get connector", "connector_id", authReq.ConnectorID, "err", err) + s.renderError(r, w, http.StatusInternalServerError, "Connector failed to initialize.") return } pwConn, ok := conn.Connector.(connector.PasswordConnector) if !ok { - s.logger.Errorf("Expected password connector in handlePasswordLogin(), but got %v", pwConn) + s.logger.ErrorContext(r.Context(), "expected password connector in handlePasswordLogin()", "password_connector", pwConn) s.renderError(r, w, http.StatusInternalServerError, "Requested resource does not exist.") return } @@ -352,7 +364,7 @@ func (s *Server) handlePasswordLogin(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: if err := s.templates.password(r, w, r.URL.String(), "", usernamePrompt(pwConn), false, backLink); err != nil { - s.logger.Errorf("Server template error: %v", err) + s.logger.ErrorContext(r.Context(), "server template error", "err", err) } case http.MethodPost: username := r.FormValue("login") @@ -361,23 +373,35 @@ func (s *Server) handlePasswordLogin(w http.ResponseWriter, r *http.Request) { identity, ok, err := pwConn.Login(r.Context(), scopes, username, password) if err != nil { - s.logger.Errorf("Failed to login user: %v", err) + s.logger.ErrorContext(r.Context(), "failed to login user", "err", err) s.renderError(r, w, http.StatusInternalServerError, fmt.Sprintf("Login error: %v", err)) return } if !ok { if err := s.templates.password(r, w, r.URL.String(), username, usernamePrompt(pwConn), true, backLink); err != nil { - s.logger.Errorf("Server template error: %v", err) + s.logger.ErrorContext(r.Context(), "server template error", "err", err) } + s.logger.ErrorContext(r.Context(), "failed login attempt: Invalid credentials.", "user", username) return } - redirectURL, err := s.finalizeLogin(identity, authReq, conn.Connector) + redirectURL, canSkipApproval, err := s.finalizeLogin(r.Context(), identity, authReq, conn.Connector) if err != nil { - s.logger.Errorf("Failed to finalize login: %v", err) + s.logger.ErrorContext(r.Context(), "failed to finalize login", "err", err) s.renderError(r, w, http.StatusInternalServerError, "Login error.") return } + if canSkipApproval { + authReq, err = s.storage.GetAuthRequest(ctx, authReq.ID) + if err != nil { + s.logger.ErrorContext(r.Context(), "failed to get finalized auth request", "err", err) + s.renderError(r, w, http.StatusInternalServerError, "Login error.") + return + } + s.sendCodeResponse(w, r, authReq) + return + } + http.Redirect(w, r, redirectURL, http.StatusSeeOther) default: s.renderError(r, w, http.StatusBadRequest, "Unsupported request method.") @@ -385,6 +409,7 @@ func (s *Server) handlePasswordLogin(w http.ResponseWriter, r *http.Request) { } func (s *Server) handleConnectorCallback(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() var authID string switch r.Method { case http.MethodGet: // OAuth2 callback @@ -402,32 +427,32 @@ func (s *Server) handleConnectorCallback(w http.ResponseWriter, r *http.Request) return } - authReq, err := s.storage.GetAuthRequest(authID) + authReq, err := s.storage.GetAuthRequest(ctx, authID) if err != nil { if err == storage.ErrNotFound { - s.logger.Errorf("Invalid 'state' parameter provided: %v", err) + s.logger.ErrorContext(r.Context(), "invalid 'state' parameter provided", "err", err) s.renderError(r, w, http.StatusBadRequest, "Requested resource does not exist.") return } - s.logger.Errorf("Failed to get auth request: %v", err) + s.logger.ErrorContext(r.Context(), "failed to get auth request", "err", err) s.renderError(r, w, http.StatusInternalServerError, "Database error.") return } connID, err := url.PathUnescape(mux.Vars(r)["connector"]) if err != nil { - s.logger.Errorf("Failed to get connector with id %q : %v", authReq.ConnectorID, err) + s.logger.ErrorContext(r.Context(), "failed to get connector", "connector_id", authReq.ConnectorID, "err", err) s.renderError(r, w, http.StatusInternalServerError, "Requested resource does not exist.") return } else if connID != "" && connID != authReq.ConnectorID { - s.logger.Errorf("Connector mismatch: authentication started with id %q, but callback for id %q was triggered", authReq.ConnectorID, connID) + s.logger.ErrorContext(r.Context(), "connector mismatch: callback triggered for different connector than authentication start", "authentication_start_connector_id", authReq.ConnectorID, "connector_id", connID) s.renderError(r, w, http.StatusInternalServerError, "Requested resource does not exist.") return } - conn, err := s.getConnector(authReq.ConnectorID) + conn, err := s.getConnector(ctx, authReq.ConnectorID) if err != nil { - s.logger.Errorf("Failed to get connector with id %q : %v", authReq.ConnectorID, err) + s.logger.ErrorContext(r.Context(), "failed to get connector", "connector_id", authReq.ConnectorID, "err", err) s.renderError(r, w, http.StatusInternalServerError, "Requested resource does not exist.") return } @@ -436,14 +461,14 @@ func (s *Server) handleConnectorCallback(w http.ResponseWriter, r *http.Request) switch conn := conn.Connector.(type) { case connector.CallbackConnector: if r.Method != http.MethodGet { - s.logger.Errorf("SAML request mapped to OAuth2 connector") + s.logger.ErrorContext(r.Context(), "SAML request mapped to OAuth2 connector") s.renderError(r, w, http.StatusBadRequest, "Invalid request") return } identity, err = conn.HandleCallback(parseScopes(authReq.Scopes), r) case connector.SAMLConnector: if r.Method != http.MethodPost { - s.logger.Errorf("OAuth2 request mapped to SAML connector") + s.logger.ErrorContext(r.Context(), "OAuth2 request mapped to SAML connector") s.renderError(r, w, http.StatusBadRequest, "Invalid request") return } @@ -454,24 +479,35 @@ func (s *Server) handleConnectorCallback(w http.ResponseWriter, r *http.Request) } if err != nil { - s.logger.Errorf("Failed to authenticate: %v", err) + s.logger.ErrorContext(r.Context(), "failed to authenticate", "err", err) s.renderError(r, w, http.StatusInternalServerError, fmt.Sprintf("Failed to authenticate: %v", err)) return } - redirectURL, err := s.finalizeLogin(identity, authReq, conn.Connector) + redirectURL, canSkipApproval, err := s.finalizeLogin(ctx, identity, authReq, conn.Connector) if err != nil { - s.logger.Errorf("Failed to finalize login: %v", err) + s.logger.ErrorContext(r.Context(), "failed to finalize login", "err", err) s.renderError(r, w, http.StatusInternalServerError, "Login error.") return } + if canSkipApproval { + authReq, err = s.storage.GetAuthRequest(ctx, authReq.ID) + if err != nil { + s.logger.ErrorContext(r.Context(), "failed to get finalized auth request", "err", err) + s.renderError(r, w, http.StatusInternalServerError, "Login error.") + return + } + s.sendCodeResponse(w, r, authReq) + return + } + http.Redirect(w, r, redirectURL, http.StatusSeeOther) } // finalizeLogin associates the user's identity with the current AuthRequest, then returns // the approval page's path. -func (s *Server) finalizeLogin(identity connector.Identity, authReq storage.AuthRequest, conn connector.Connector) (string, error) { +func (s *Server) finalizeLogin(ctx context.Context, identity connector.Identity, authReq storage.AuthRequest, conn connector.Connector) (string, bool, error) { claims := storage.Claims{ UserID: identity.UserID, Username: identity.Username, @@ -487,8 +523,8 @@ func (s *Server) finalizeLogin(identity connector.Identity, authReq storage.Auth a.ConnectorData = identity.ConnectorData return a, nil } - if err := s.storage.UpdateAuthRequest(authReq.ID, updater); err != nil { - return "", fmt.Errorf("failed to update auth request: %v", err) + if err := s.storage.UpdateAuthRequest(ctx, authReq.ID, updater); err != nil { + return "", false, fmt.Errorf("failed to update auth request: %v", err) } email := claims.Email @@ -496,80 +532,114 @@ func (s *Server) finalizeLogin(identity connector.Identity, authReq storage.Auth email += " (unverified)" } - s.logger.Infof("login successful: connector %q, username=%q, preferred_username=%q, email=%q, groups=%q", - authReq.ConnectorID, claims.Username, claims.PreferredUsername, email, claims.Groups) + s.logger.InfoContext(ctx, "login successful", + "connector_id", authReq.ConnectorID, "username", claims.Username, + "preferred_username", claims.PreferredUsername, "email", email, "groups", claims.Groups) - returnURL := path.Join(s.issuerURL.Path, "/approval") + "?req=" + authReq.ID - _, ok := conn.(connector.RefreshConnector) - if !ok { - return returnURL, nil + offlineAccessRequested := false + for _, scope := range authReq.Scopes { + if scope == scopeOfflineAccess { + offlineAccessRequested = true + break + } } + _, canRefresh := conn.(connector.RefreshConnector) - // Try to retrieve an existing OfflineSession object for the corresponding user. - session, err := s.storage.GetOfflineSessions(identity.UserID, authReq.ConnectorID) - if err != nil { - if err != storage.ErrNotFound { - s.logger.Errorf("failed to get offline session: %v", err) - return "", err - } - offlineSessions := storage.OfflineSessions{ - UserID: identity.UserID, - ConnID: authReq.ConnectorID, - Refresh: make(map[string]*storage.RefreshTokenRef), - ConnectorData: identity.ConnectorData, - } + if offlineAccessRequested && canRefresh { + // Try to retrieve an existing OfflineSession object for the corresponding user. + session, err := s.storage.GetOfflineSessions(ctx, identity.UserID, authReq.ConnectorID) + switch { + case err != nil && err == storage.ErrNotFound: + offlineSessions := storage.OfflineSessions{ + UserID: identity.UserID, + ConnID: authReq.ConnectorID, + Refresh: make(map[string]*storage.RefreshTokenRef), + ConnectorData: identity.ConnectorData, + } - // Create a new OfflineSession object for the user and add a reference object for - // the newly received refreshtoken. - if err := s.storage.CreateOfflineSessions(offlineSessions); err != nil { - s.logger.Errorf("failed to create offline session: %v", err) - return "", err + // Create a new OfflineSession object for the user and add a reference object for + // the newly received refreshtoken. + if err := s.storage.CreateOfflineSessions(ctx, offlineSessions); err != nil { + s.logger.ErrorContext(ctx, "failed to create offline session", "err", err) + return "", false, err + } + case err == nil: + // Update existing OfflineSession obj with new RefreshTokenRef. + if err := s.storage.UpdateOfflineSessions(ctx, session.UserID, session.ConnID, func(old storage.OfflineSessions) (storage.OfflineSessions, error) { + if len(identity.ConnectorData) > 0 { + old.ConnectorData = identity.ConnectorData + } + return old, nil + }); err != nil { + s.logger.ErrorContext(ctx, "failed to update offline session", "err", err) + return "", false, err + } + default: + s.logger.ErrorContext(ctx, "failed to get offline session", "err", err) + return "", false, err } - - return returnURL, nil } - // Update existing OfflineSession obj with new RefreshTokenRef. - if err := s.storage.UpdateOfflineSessions(session.UserID, session.ConnID, func(old storage.OfflineSessions) (storage.OfflineSessions, error) { - if len(identity.ConnectorData) > 0 { - old.ConnectorData = identity.ConnectorData - } - return old, nil - }); err != nil { - s.logger.Errorf("failed to update offline session: %v", err) - return "", err + // we can skip the redirect to /approval and go ahead and send code if it's not required + if s.skipApproval && !authReq.ForceApprovalPrompt { + return "", true, nil } - return returnURL, nil + // an HMAC is used here to ensure that the request ID is unpredictable, ensuring that an attacker who intercepted the original + // flow would be unable to poll for the result at the /approval endpoint + h := hmac.New(sha256.New, authReq.HMACKey) + h.Write([]byte(authReq.ID)) + mac := h.Sum(nil) + + returnURL := path.Join(s.issuerURL.Path, "/approval") + "?req=" + authReq.ID + "&hmac=" + base64.RawURLEncoding.EncodeToString(mac) + return returnURL, false, nil } func (s *Server) handleApproval(w http.ResponseWriter, r *http.Request) { - authReq, err := s.storage.GetAuthRequest(r.FormValue("req")) + ctx := r.Context() + macEncoded := r.FormValue("hmac") + if macEncoded == "" { + s.renderError(r, w, http.StatusUnauthorized, "Unauthorized request") + return + } + mac, err := base64.RawURLEncoding.DecodeString(macEncoded) + if err != nil { + s.renderError(r, w, http.StatusUnauthorized, "Unauthorized request") + return + } + + authReq, err := s.storage.GetAuthRequest(ctx, r.FormValue("req")) if err != nil { - s.logger.Errorf("Failed to get auth request: %v", err) + s.logger.ErrorContext(r.Context(), "failed to get auth request", "err", err) s.renderError(r, w, http.StatusInternalServerError, "Database error.") return } if !authReq.LoggedIn { - s.logger.Errorf("Auth request does not have an identity for approval") + s.logger.ErrorContext(r.Context(), "auth request does not have an identity for approval") s.renderError(r, w, http.StatusInternalServerError, "Login process not yet finalized.") return } + // build expected hmac with secret key + h := hmac.New(sha256.New, authReq.HMACKey) + h.Write([]byte(authReq.ID)) + expectedMAC := h.Sum(nil) + // constant time comparison + if !hmac.Equal(mac, expectedMAC) { + s.renderError(r, w, http.StatusUnauthorized, "Unauthorized request") + return + } + switch r.Method { case http.MethodGet: - if s.skipApproval { - s.sendCodeResponse(w, r, authReq) - return - } - client, err := s.storage.GetClient(authReq.ClientID) + client, err := s.storage.GetClient(ctx, authReq.ClientID) if err != nil { - s.logger.Errorf("Failed to get client %q: %v", authReq.ClientID, err) + s.logger.ErrorContext(r.Context(), "Failed to get client", "client_id", authReq.ClientID, "err", err) s.renderError(r, w, http.StatusInternalServerError, "Failed to retrieve client.") return } if err := s.templates.approval(r, w, authReq.ID, authReq.Claims.Username, client.Name, authReq.Scopes); err != nil { - s.logger.Errorf("Server template error: %v", err) + s.logger.ErrorContext(r.Context(), "server template error", "err", err) } case http.MethodPost: if r.FormValue("approval") != "approve" { @@ -581,14 +651,15 @@ func (s *Server) handleApproval(w http.ResponseWriter, r *http.Request) { } func (s *Server) sendCodeResponse(w http.ResponseWriter, r *http.Request, authReq storage.AuthRequest) { + ctx := r.Context() if s.now().After(authReq.Expiry) { s.renderError(r, w, http.StatusBadRequest, "User session has expired.") return } - if err := s.storage.DeleteAuthRequest(authReq.ID); err != nil { + if err := s.storage.DeleteAuthRequest(ctx, authReq.ID); err != nil { if err != storage.ErrNotFound { - s.logger.Errorf("Failed to delete authorization request: %v", err) + s.logger.ErrorContext(r.Context(), "Failed to delete authorization request", "err", err) s.renderError(r, w, http.StatusInternalServerError, "Internal server error.") } else { s.renderError(r, w, http.StatusBadRequest, "User session error.") @@ -633,8 +704,8 @@ func (s *Server) sendCodeResponse(w http.ResponseWriter, r *http.Request, authRe ConnectorData: authReq.ConnectorData, PKCE: authReq.PKCE, } - if err := s.storage.CreateAuthCode(code); err != nil { - s.logger.Errorf("Failed to create auth code: %v", err) + if err := s.storage.CreateAuthCode(ctx, code); err != nil { + s.logger.ErrorContext(r.Context(), "Failed to create auth code", "err", err) s.renderError(r, w, http.StatusInternalServerError, "Internal server error.") return } @@ -643,26 +714,27 @@ func (s *Server) sendCodeResponse(w http.ResponseWriter, r *http.Request, authRe // rejected earlier. If we got here we're using the code flow. if authReq.RedirectURI == redirectURIOOB { if err := s.templates.oob(r, w, code.ID); err != nil { - s.logger.Errorf("Server template error: %v", err) + s.logger.ErrorContext(r.Context(), "server template error", "err", err) } return } case responseTypeToken: implicitOrHybrid = true - case responseTypeIDToken: - implicitOrHybrid = true var err error - accessToken, err = s.newAccessToken(authReq.ClientID, authReq.Claims, authReq.Scopes, authReq.Nonce, authReq.ConnectorID) + accessToken, _, err = s.newAccessToken(r.Context(), authReq.ClientID, authReq.Claims, authReq.Scopes, authReq.Nonce, authReq.ConnectorID) if err != nil { - s.logger.Errorf("failed to create new access token: %v", err) + s.logger.ErrorContext(r.Context(), "failed to create new access token", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) return } + case responseTypeIDToken: + implicitOrHybrid = true + var err error - idToken, idTokenExpiry, err = s.newIDToken(authReq.ClientID, authReq.Claims, authReq.Scopes, authReq.Nonce, accessToken, code.ID, authReq.ConnectorID) + idToken, idTokenExpiry, err = s.newIDToken(r.Context(), authReq.ClientID, authReq.Claims, authReq.Scopes, authReq.Nonce, accessToken, code.ID, authReq.ConnectorID) if err != nil { - s.logger.Errorf("failed to create ID token: %v", err) + s.logger.ErrorContext(r.Context(), "failed to create ID token", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) return } @@ -671,12 +743,10 @@ func (s *Server) sendCodeResponse(w http.ResponseWriter, r *http.Request, authRe if implicitOrHybrid { v := url.Values{} - v.Set("access_token", accessToken) - v.Set("token_type", "bearer") - v.Set("state", authReq.State) - if idToken != "" { - v.Set("id_token", idToken) - // The hybrid flow with only "code token" or "code id_token" doesn't return an + if accessToken != "" { + v.Set("access_token", accessToken) + v.Set("token_type", "bearer") + // The hybrid flow with "code token" or "code id_token token" doesn't return an // "expires_in" value. If "code" wasn't provided, indicating the implicit flow, // don't add it. // @@ -685,6 +755,10 @@ func (s *Server) sendCodeResponse(w http.ResponseWriter, r *http.Request, authRe v.Set("expires_in", strconv.Itoa(int(idTokenExpiry.Sub(s.now()).Seconds()))) } } + v.Set("state", authReq.State) + if idToken != "" { + v.Set("id_token", idToken) + } if code.ID != "" { v.Set("code", code.ID) } @@ -718,6 +792,7 @@ func (s *Server) sendCodeResponse(w http.ResponseWriter, r *http.Request, authRe } func (s *Server) withClientFromStorage(w http.ResponseWriter, r *http.Request, handler func(http.ResponseWriter, *http.Request, storage.Client)) { + ctx := r.Context() clientID, clientSecret, ok := r.BasicAuth() if ok { var err error @@ -734,10 +809,10 @@ func (s *Server) withClientFromStorage(w http.ResponseWriter, r *http.Request, h clientSecret = r.PostFormValue("client_secret") } - client, err := s.storage.GetClient(clientID) + client, err := s.storage.GetClient(ctx, clientID) if err != nil { if err != storage.ErrNotFound { - s.logger.Errorf("failed to get client: %v", err) + s.logger.ErrorContext(r.Context(), "failed to get client", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) } else { s.tokenErrHelper(w, errInvalidClient, "Invalid client credentials.", http.StatusUnauthorized) @@ -747,9 +822,9 @@ func (s *Server) withClientFromStorage(w http.ResponseWriter, r *http.Request, h if subtle.ConstantTimeCompare([]byte(client.Secret), []byte(clientSecret)) != 1 { if clientSecret == "" { - s.logger.Infof("missing client_secret on token request for client: %s", client.ID) + s.logger.InfoContext(r.Context(), "missing client_secret on token request", "client_id", client.ID) } else { - s.logger.Infof("invalid client_secret on token request for client: %s", client.ID) + s.logger.InfoContext(r.Context(), "invalid client_secret on token request", "client_id", client.ID) } s.tokenErrHelper(w, errInvalidClient, "Invalid client credentials.", http.StatusUnauthorized) return @@ -767,12 +842,17 @@ func (s *Server) handleToken(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { - s.logger.Errorf("Could not parse request body: %v", err) + s.logger.ErrorContext(r.Context(), "could not parse request body", "err", err) s.tokenErrHelper(w, errInvalidRequest, "", http.StatusBadRequest) return } grantType := r.PostFormValue("grant_type") + if !contains(s.supportedGrantTypes, grantType) { + s.logger.ErrorContext(r.Context(), "unsupported grant type", "grant_type", grantType) + s.tokenErrHelper(w, errUnsupportedGrantType, "", http.StatusBadRequest) + return + } switch grantType { case grantTypeDeviceCode: s.handleDeviceToken(w, r) @@ -782,6 +862,8 @@ func (s *Server) handleToken(w http.ResponseWriter, r *http.Request) { s.withClientFromStorage(w, r, s.handleRefreshToken) case grantTypePassword: s.withClientFromStorage(w, r, s.handlePasswordGrant) + case grantTypeTokenExchange: + s.withClientFromStorage(w, r, s.handleTokenExchange) default: s.tokenErrHelper(w, errUnsupportedGrantType, "", http.StatusBadRequest) } @@ -801,6 +883,7 @@ func (s *Server) calculateCodeChallenge(codeVerifier, codeChallengeMethod string // handle an access token request https://tools.ietf.org/html/rfc6749#section-4.1.3 func (s *Server) handleAuthCode(w http.ResponseWriter, r *http.Request, client storage.Client) { + ctx := r.Context() code := r.PostFormValue("code") redirectURI := r.PostFormValue("redirect_uri") @@ -809,10 +892,10 @@ func (s *Server) handleAuthCode(w http.ResponseWriter, r *http.Request, client s return } - authCode, err := s.storage.GetAuthCode(code) + authCode, err := s.storage.GetAuthCode(ctx, code) if err != nil || s.now().After(authCode.Expiry) || authCode.ClientID != client.ID { if err != storage.ErrNotFound { - s.logger.Errorf("failed to get auth code: %v", err) + s.logger.ErrorContext(r.Context(), "failed to get auth code", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) } else { s.tokenErrHelper(w, errInvalidGrant, "Invalid or expired code parameter.", http.StatusBadRequest) @@ -828,7 +911,7 @@ func (s *Server) handleAuthCode(w http.ResponseWriter, r *http.Request, client s case providedCodeVerifier != "" && codeChallengeFromStorage != "": calculatedCodeChallenge, err := s.calculateCodeChallenge(providedCodeVerifier, authCode.PKCE.CodeChallengeMethod) if err != nil { - s.logger.Error(err) + s.logger.ErrorContext(r.Context(), "failed to calculate code challenge", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) return } @@ -851,7 +934,7 @@ func (s *Server) handleAuthCode(w http.ResponseWriter, r *http.Request, client s return } - tokenResponse, err := s.exchangeAuthCode(w, authCode, client) + tokenResponse, err := s.exchangeAuthCode(ctx, w, authCode, client) if err != nil { s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) return @@ -859,23 +942,23 @@ func (s *Server) handleAuthCode(w http.ResponseWriter, r *http.Request, client s s.writeAccessToken(w, tokenResponse) } -func (s *Server) exchangeAuthCode(w http.ResponseWriter, authCode storage.AuthCode, client storage.Client) (*accessTokenResponse, error) { - accessToken, err := s.newAccessToken(client.ID, authCode.Claims, authCode.Scopes, authCode.Nonce, authCode.ConnectorID) +func (s *Server) exchangeAuthCode(ctx context.Context, w http.ResponseWriter, authCode storage.AuthCode, client storage.Client) (*accessTokenResponse, error) { + accessToken, _, err := s.newAccessToken(ctx, client.ID, authCode.Claims, authCode.Scopes, authCode.Nonce, authCode.ConnectorID) if err != nil { - s.logger.Errorf("failed to create new access token: %v", err) + s.logger.ErrorContext(ctx, "failed to create new access token", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) return nil, err } - idToken, expiry, err := s.newIDToken(client.ID, authCode.Claims, authCode.Scopes, authCode.Nonce, accessToken, authCode.ID, authCode.ConnectorID) + idToken, expiry, err := s.newIDToken(ctx, client.ID, authCode.Claims, authCode.Scopes, authCode.Nonce, accessToken, authCode.ID, authCode.ConnectorID) if err != nil { - s.logger.Errorf("failed to create ID token: %v", err) + s.logger.ErrorContext(ctx, "failed to create ID token", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) return nil, err } - if err := s.storage.DeleteAuthCode(authCode.ID); err != nil { - s.logger.Errorf("failed to delete auth code: %v", err) + if err := s.storage.DeleteAuthCode(ctx, authCode.ID); err != nil { + s.logger.ErrorContext(ctx, "failed to delete auth code", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) return nil, err } @@ -884,9 +967,9 @@ func (s *Server) exchangeAuthCode(w http.ResponseWriter, authCode storage.AuthCo // Ensure the connector supports refresh tokens. // // Connectors like `saml` do not implement RefreshConnector. - conn, err := s.getConnector(authCode.ConnectorID) + conn, err := s.getConnector(ctx, authCode.ConnectorID) if err != nil { - s.logger.Errorf("connector with ID %q not found: %v", authCode.ConnectorID, err) + s.logger.ErrorContext(ctx, "connector not found", "connector_id", authCode.ConnectorID, "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) return false } @@ -922,13 +1005,13 @@ func (s *Server) exchangeAuthCode(w http.ResponseWriter, authCode storage.AuthCo Token: refresh.Token, } if refreshToken, err = internal.Marshal(token); err != nil { - s.logger.Errorf("failed to marshal refresh token: %v", err) + s.logger.ErrorContext(ctx, "failed to marshal refresh token", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) return nil, err } - if err := s.storage.CreateRefresh(refresh); err != nil { - s.logger.Errorf("failed to create refresh token: %v", err) + if err := s.storage.CreateRefresh(ctx, refresh); err != nil { + s.logger.ErrorContext(ctx, "failed to create refresh token", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) return nil, err } @@ -940,8 +1023,8 @@ func (s *Server) exchangeAuthCode(w http.ResponseWriter, authCode storage.AuthCo defer func() { if deleteToken { // Delete newly created refresh token from storage. - if err := s.storage.DeleteRefresh(refresh.ID); err != nil { - s.logger.Errorf("failed to delete refresh token: %v", err) + if err := s.storage.DeleteRefresh(ctx, refresh.ID); err != nil { + s.logger.ErrorContext(ctx, "failed to delete refresh token", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) return } @@ -956,9 +1039,9 @@ func (s *Server) exchangeAuthCode(w http.ResponseWriter, authCode storage.AuthCo } // Try to retrieve an existing OfflineSession object for the corresponding user. - if session, err := s.storage.GetOfflineSessions(refresh.Claims.UserID, refresh.ConnectorID); err != nil { + if session, err := s.storage.GetOfflineSessions(ctx, refresh.Claims.UserID, refresh.ConnectorID); err != nil { if err != storage.ErrNotFound { - s.logger.Errorf("failed to get offline session: %v", err) + s.logger.ErrorContext(ctx, "failed to get offline session", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) deleteToken = true return nil, err @@ -972,8 +1055,8 @@ func (s *Server) exchangeAuthCode(w http.ResponseWriter, authCode storage.AuthCo // Create a new OfflineSession object for the user and add a reference object for // the newly received refreshtoken. - if err := s.storage.CreateOfflineSessions(offlineSessions); err != nil { - s.logger.Errorf("failed to create offline session: %v", err) + if err := s.storage.CreateOfflineSessions(ctx, offlineSessions); err != nil { + s.logger.ErrorContext(ctx, "failed to create offline session", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) deleteToken = true return nil, err @@ -981,8 +1064,8 @@ func (s *Server) exchangeAuthCode(w http.ResponseWriter, authCode storage.AuthCo } else { if oldTokenRef, ok := session.Refresh[tokenRef.ClientID]; ok { // Delete old refresh token from storage. - if err := s.storage.DeleteRefresh(oldTokenRef.ID); err != nil && err != storage.ErrNotFound { - s.logger.Errorf("failed to delete refresh token: %v", err) + if err := s.storage.DeleteRefresh(ctx, oldTokenRef.ID); err != nil && err != storage.ErrNotFound { + s.logger.ErrorContext(ctx, "failed to delete refresh token", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) deleteToken = true return nil, err @@ -990,11 +1073,11 @@ func (s *Server) exchangeAuthCode(w http.ResponseWriter, authCode storage.AuthCo } // Update existing OfflineSession obj with new RefreshTokenRef. - if err := s.storage.UpdateOfflineSessions(session.UserID, session.ConnID, func(old storage.OfflineSessions) (storage.OfflineSessions, error) { + if err := s.storage.UpdateOfflineSessions(ctx, session.UserID, session.ConnID, func(old storage.OfflineSessions) (storage.OfflineSessions, error) { old.Refresh[tokenRef.ClientID] = &tokenRef return old, nil }); err != nil { - s.logger.Errorf("failed to update offline session: %v", err) + s.logger.ErrorContext(ctx, "failed to update offline session", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) deleteToken = true return nil, err @@ -1005,6 +1088,7 @@ func (s *Server) exchangeAuthCode(w http.ResponseWriter, authCode storage.AuthCo } func (s *Server) handleUserInfo(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() const prefix = "Bearer " auth := r.Header.Get("authorization") @@ -1016,7 +1100,7 @@ func (s *Server) handleUserInfo(w http.ResponseWriter, r *http.Request) { rawIDToken := auth[len(prefix):] verifier := oidc.NewVerifier(s.issuerURL.String(), &storageKeySet{s.storage}, &oidc.Config{SkipClientIDCheck: true}) - idToken, err := verifier.Verify(r.Context(), rawIDToken) + idToken, err := verifier.Verify(ctx, rawIDToken) if err != nil { s.tokenErrHelper(w, errAccessDenied, err.Error(), http.StatusForbidden) return @@ -1033,6 +1117,7 @@ func (s *Server) handleUserInfo(w http.ResponseWriter, r *http.Request) { } func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, client storage.Client) { + ctx := r.Context() // Parse the fields if err := r.ParseForm(); err != nil { s.tokenErrHelper(w, errInvalidRequest, "Couldn't parse data", http.StatusBadRequest) @@ -1062,7 +1147,7 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli continue } - isTrusted, err := s.validateCrossClientTrust(client.ID, peerID) + isTrusted, err := s.validateCrossClientTrust(ctx, client.ID, peerID) if err != nil { s.tokenErrHelper(w, errInvalidClient, fmt.Sprintf("Error validating cross client trust %v.", err), http.StatusBadRequest) return @@ -1087,7 +1172,7 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli // Which connector connID := s.passwordConnector - conn, err := s.getConnector(connID) + conn, err := s.getConnector(ctx, connID) if err != nil { s.tokenErrHelper(w, errInvalidRequest, "Requested connector does not exist.", http.StatusBadRequest) return @@ -1102,9 +1187,9 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli // Login username := q.Get("username") password := q.Get("password") - identity, ok, err := passwordConnector.Login(r.Context(), parseScopes(scopes), username, password) + identity, ok, err := passwordConnector.Login(ctx, parseScopes(scopes), username, password) if err != nil { - s.logger.Errorf("Failed to login user: %v", err) + s.logger.ErrorContext(r.Context(), "failed to login user", "err", err) s.tokenErrHelper(w, errInvalidRequest, "Could not login user", http.StatusBadRequest) return } @@ -1123,16 +1208,16 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli Groups: identity.Groups, } - accessToken, err := s.newAccessToken(client.ID, claims, scopes, nonce, connID) + accessToken, _, err := s.newAccessToken(ctx, client.ID, claims, scopes, nonce, connID) if err != nil { - s.logger.Errorf("password grant failed to create new access token: %v", err) + s.logger.ErrorContext(r.Context(), "password grant failed to create new access token", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) return } - idToken, expiry, err := s.newIDToken(client.ID, claims, scopes, nonce, accessToken, "", connID) + idToken, expiry, err := s.newIDToken(ctx, client.ID, claims, scopes, nonce, accessToken, "", connID) if err != nil { - s.logger.Errorf("password grant failed to create new ID token: %v", err) + s.logger.ErrorContext(r.Context(), "password grant failed to create new ID token", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) return } @@ -1172,13 +1257,13 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli Token: refresh.Token, } if refreshToken, err = internal.Marshal(token); err != nil { - s.logger.Errorf("failed to marshal refresh token: %v", err) + s.logger.ErrorContext(r.Context(), "failed to marshal refresh token", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) return } - if err := s.storage.CreateRefresh(refresh); err != nil { - s.logger.Errorf("failed to create refresh token: %v", err) + if err := s.storage.CreateRefresh(ctx, refresh); err != nil { + s.logger.ErrorContext(r.Context(), "failed to create refresh token", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) return } @@ -1190,8 +1275,8 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli defer func() { if deleteToken { // Delete newly created refresh token from storage. - if err := s.storage.DeleteRefresh(refresh.ID); err != nil { - s.logger.Errorf("failed to delete refresh token: %v", err) + if err := s.storage.DeleteRefresh(ctx, refresh.ID); err != nil { + s.logger.ErrorContext(r.Context(), "failed to delete refresh token", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) return } @@ -1206,9 +1291,9 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli } // Try to retrieve an existing OfflineSession object for the corresponding user. - if session, err := s.storage.GetOfflineSessions(refresh.Claims.UserID, refresh.ConnectorID); err != nil { + if session, err := s.storage.GetOfflineSessions(ctx, refresh.Claims.UserID, refresh.ConnectorID); err != nil { if err != storage.ErrNotFound { - s.logger.Errorf("failed to get offline session: %v", err) + s.logger.ErrorContext(r.Context(), "failed to get offline session", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) deleteToken = true return @@ -1223,8 +1308,8 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli // Create a new OfflineSession object for the user and add a reference object for // the newly received refreshtoken. - if err := s.storage.CreateOfflineSessions(offlineSessions); err != nil { - s.logger.Errorf("failed to create offline session: %v", err) + if err := s.storage.CreateOfflineSessions(ctx, offlineSessions); err != nil { + s.logger.ErrorContext(r.Context(), "failed to create offline session", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) deleteToken = true return @@ -1232,11 +1317,11 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli } else { if oldTokenRef, ok := session.Refresh[tokenRef.ClientID]; ok { // Delete old refresh token from storage. - if err := s.storage.DeleteRefresh(oldTokenRef.ID); err != nil { + if err := s.storage.DeleteRefresh(ctx, oldTokenRef.ID); err != nil { if err == storage.ErrNotFound { - s.logger.Warnf("database inconsistent, refresh token missing: %v", oldTokenRef.ID) + s.logger.Warn("database inconsistent, refresh token missing", "token_id", oldTokenRef.ID) } else { - s.logger.Errorf("failed to delete refresh token: %v", err) + s.logger.ErrorContext(r.Context(), "failed to delete refresh token", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) deleteToken = true return @@ -1245,12 +1330,12 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli } // Update existing OfflineSession obj with new RefreshTokenRef. - if err := s.storage.UpdateOfflineSessions(session.UserID, session.ConnID, func(old storage.OfflineSessions) (storage.OfflineSessions, error) { + if err := s.storage.UpdateOfflineSessions(ctx, session.UserID, session.ConnID, func(old storage.OfflineSessions) (storage.OfflineSessions, error) { old.Refresh[tokenRef.ClientID] = &tokenRef old.ConnectorData = identity.ConnectorData return old, nil }); err != nil { - s.logger.Errorf("failed to update offline session: %v", err) + s.logger.ErrorContext(r.Context(), "failed to update offline session", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) deleteToken = true return @@ -1262,28 +1347,117 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli s.writeAccessToken(w, resp) } +func (s *Server) handleTokenExchange(w http.ResponseWriter, r *http.Request, client storage.Client) { + ctx := r.Context() + + if err := r.ParseForm(); err != nil { + s.logger.ErrorContext(r.Context(), "could not parse request body", "err", err) + s.tokenErrHelper(w, errInvalidRequest, "", http.StatusBadRequest) + return + } + q := r.Form + + scopes := strings.Fields(q.Get("scope")) // OPTIONAL, map to issued token scope + requestedTokenType := q.Get("requested_token_type") // OPTIONAL, default to access token + if requestedTokenType == "" { + requestedTokenType = tokenTypeAccess + } + subjectToken := q.Get("subject_token") // REQUIRED + subjectTokenType := q.Get("subject_token_type") // REQUIRED + connID := q.Get("connector_id") // REQUIRED, not in RFC + + switch subjectTokenType { + case tokenTypeID, tokenTypeAccess: // ok, continue + default: + s.tokenErrHelper(w, errRequestNotSupported, "Invalid subject_token_type.", http.StatusBadRequest) + return + } + + if subjectToken == "" { + s.tokenErrHelper(w, errInvalidRequest, "Missing subject_token", http.StatusBadRequest) + return + } + + conn, err := s.getConnector(ctx, connID) + if err != nil { + s.logger.ErrorContext(r.Context(), "failed to get connector", "err", err) + s.tokenErrHelper(w, errInvalidRequest, "Requested connector does not exist.", http.StatusBadRequest) + return + } + teConn, ok := conn.Connector.(connector.TokenIdentityConnector) + if !ok { + s.logger.ErrorContext(r.Context(), "connector doesn't implement token exchange", "connector_id", connID) + s.tokenErrHelper(w, errInvalidRequest, "Requested connector does not exist.", http.StatusBadRequest) + return + } + identity, err := teConn.TokenIdentity(ctx, subjectTokenType, subjectToken) + if err != nil { + s.logger.ErrorContext(r.Context(), "failed to verify subject token", "err", err) + s.tokenErrHelper(w, errAccessDenied, "", http.StatusUnauthorized) + return + } + + claims := storage.Claims{ + UserID: identity.UserID, + Username: identity.Username, + PreferredUsername: identity.PreferredUsername, + Email: identity.Email, + EmailVerified: identity.EmailVerified, + Groups: identity.Groups, + } + resp := accessTokenResponse{ + IssuedTokenType: requestedTokenType, + TokenType: "bearer", + } + var expiry time.Time + switch requestedTokenType { + case tokenTypeID: + resp.AccessToken, expiry, err = s.newIDToken(r.Context(), client.ID, claims, scopes, "", "", "", connID) + case tokenTypeAccess: + resp.AccessToken, expiry, err = s.newAccessToken(r.Context(), client.ID, claims, scopes, "", connID) + default: + s.tokenErrHelper(w, errRequestNotSupported, "Invalid requested_token_type.", http.StatusBadRequest) + return + } + if err != nil { + s.logger.ErrorContext(r.Context(), "token exchange failed to create new token", "requested_token_type", requestedTokenType, "err", err) + s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) + return + } + resp.ExpiresIn = int(time.Until(expiry).Seconds()) + + // Token response must include cache headers https://tools.ietf.org/html/rfc6749#section-5.1 + w.Header().Set("Cache-Control", "no-store") + w.Header().Set("Pragma", "no-cache") + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(resp) +} + type accessTokenResponse struct { - AccessToken string `json:"access_token"` - TokenType string `json:"token_type"` - ExpiresIn int `json:"expires_in"` - RefreshToken string `json:"refresh_token,omitempty"` - IDToken string `json:"id_token"` + AccessToken string `json:"access_token"` + IssuedTokenType string `json:"issued_token_type,omitempty"` + TokenType string `json:"token_type"` + ExpiresIn int `json:"expires_in,omitempty"` + RefreshToken string `json:"refresh_token,omitempty"` + IDToken string `json:"id_token,omitempty"` + Scope string `json:"scope,omitempty"` } func (s *Server) toAccessTokenResponse(idToken, accessToken, refreshToken string, expiry time.Time) *accessTokenResponse { return &accessTokenResponse{ - accessToken, - "bearer", - int(expiry.Sub(s.now()).Seconds()), - refreshToken, - idToken, + AccessToken: accessToken, + TokenType: "bearer", + ExpiresIn: int(expiry.Sub(s.now()).Seconds()), + RefreshToken: refreshToken, + IDToken: idToken, } } func (s *Server) writeAccessToken(w http.ResponseWriter, resp *accessTokenResponse) { data, err := json.Marshal(resp) if err != nil { - s.logger.Errorf("failed to marshal access token response: %v", err) + // TODO(nabokihms): error with context + s.logger.Error("failed to marshal access token response", "err", err) s.tokenErrHelper(w, errServerError, "", http.StatusInternalServerError) return } @@ -1298,13 +1472,14 @@ func (s *Server) writeAccessToken(w http.ResponseWriter, resp *accessTokenRespon func (s *Server) renderError(r *http.Request, w http.ResponseWriter, status int, description string) { if err := s.templates.err(r, w, status, description); err != nil { - s.logger.Errorf("Server template error: %v", err) + s.logger.ErrorContext(r.Context(), "server template error", "err", err) } } func (s *Server) tokenErrHelper(w http.ResponseWriter, typ string, description string, statusCode int) { if err := tokenErr(w, typ, description, statusCode); err != nil { - s.logger.Errorf("token error response: %v", err) + // TODO(nabokihms): error with context + s.logger.Error("token error response", "err", err) } } diff --git a/server/handlers_test.go b/server/handlers_test.go index fb1a05064f..114712ba79 100644 --- a/server/handlers_test.go +++ b/server/handlers_test.go @@ -5,10 +5,12 @@ import ( "context" "encoding/json" "errors" + "fmt" "net/http" "net/http/httptest" "net/url" "path" + "strings" "testing" "time" @@ -22,10 +24,7 @@ import ( ) func TestHandleHealth(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - httpServer, server := newTestServer(ctx, t, nil) + httpServer, server := newTestServer(t, nil) defer httpServer.Close() rr := httptest.NewRecorder() @@ -35,11 +34,75 @@ func TestHandleHealth(t *testing.T) { } } -func TestHandleHealthFailure(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() +func TestHandleDiscovery(t *testing.T) { + httpServer, server := newTestServer(t, nil) + defer httpServer.Close() + + rr := httptest.NewRecorder() + server.ServeHTTP(rr, httptest.NewRequest("GET", "/.well-known/openid-configuration", nil)) + if rr.Code != http.StatusOK { + t.Errorf("expected 200 got %d", rr.Code) + } + + var res discovery + err := json.NewDecoder(rr.Result().Body).Decode(&res) + require.NoError(t, err) + require.Equal(t, discovery{ + Issuer: httpServer.URL, + Auth: fmt.Sprintf("%s/auth", httpServer.URL), + Token: fmt.Sprintf("%s/token", httpServer.URL), + Keys: fmt.Sprintf("%s/keys", httpServer.URL), + UserInfo: fmt.Sprintf("%s/userinfo", httpServer.URL), + DeviceEndpoint: fmt.Sprintf("%s/device/code", httpServer.URL), + Introspect: fmt.Sprintf("%s/token/introspect", httpServer.URL), + GrantTypes: []string{ + "authorization_code", + "refresh_token", + "urn:ietf:params:oauth:grant-type:device_code", + "urn:ietf:params:oauth:grant-type:token-exchange", + }, + ResponseTypes: []string{ + "code", + }, + Subjects: []string{ + "public", + }, + IDTokenAlgs: []string{ + "RS256", + }, + CodeChallengeAlgs: []string{ + "S256", + "plain", + }, + Scopes: []string{ + "openid", + "email", + "groups", + "profile", + "offline_access", + }, + AuthMethods: []string{ + "client_secret_basic", + "client_secret_post", + }, + Claims: []string{ + "iss", + "sub", + "aud", + "iat", + "exp", + "email", + "email_verified", + "locale", + "name", + "preferred_username", + "at_hash", + }, + }, res) +} - httpServer, server := newTestServer(ctx, t, func(c *Config) { +func TestHandleHealthFailure(t *testing.T) { + httpServer, server := newTestServer(t, func(c *Config) { c.HealthChecker = gosundheit.New() c.HealthChecker.RegisterCheck( @@ -66,15 +129,12 @@ type emptyStorage struct { storage.Storage } -func (*emptyStorage) GetAuthRequest(string) (storage.AuthRequest, error) { +func (*emptyStorage) GetAuthRequest(context.Context, string) (storage.AuthRequest, error) { return storage.AuthRequest{}, storage.ErrNotFound } func TestHandleInvalidOAuth2Callbacks(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - httpServer, server := newTestServer(ctx, t, func(c *Config) { + httpServer, server := newTestServer(t, func(c *Config) { c.Storage = &emptyStorage{c.Storage} }) defer httpServer.Close() @@ -99,10 +159,7 @@ func TestHandleInvalidOAuth2Callbacks(t *testing.T) { } func TestHandleInvalidSAMLCallbacks(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - httpServer, server := newTestServer(ctx, t, func(c *Config) { + httpServer, server := newTestServer(t, func(c *Config) { c.Storage = &emptyStorage{c.Storage} }) defer httpServer.Close() @@ -179,10 +236,9 @@ func TestHandleAuthCode(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() - httpServer, s := newTestServer(ctx, t, func(c *Config) { c.Issuer += "/non-root-path" }) + httpServer, s := newTestServer(t, func(c *Config) { c.Issuer += "/non-root-path" }) defer httpServer.Close() p, err := oidc.NewProvider(ctx, httpServer.URL) @@ -211,7 +267,7 @@ func TestHandleAuthCode(t *testing.T) { Secret: "testclientsecret", RedirectURIs: []string{redirectURL}, } - err = s.storage.CreateClient(client) + err = s.storage.CreateClient(ctx, client) require.NoError(t, err) oauth2Client.config = &oauth2.Config{ @@ -231,6 +287,7 @@ func TestHandleAuthCode(t *testing.T) { } func mockConnectorDataTestStorage(t *testing.T, s storage.Storage) { + ctx := t.Context() c := storage.Client{ ID: "test", Secret: "barfoo", @@ -239,7 +296,7 @@ func mockConnectorDataTestStorage(t *testing.T, s storage.Storage) { LogoURL: "https://goo.gl/JIyzIC", } - err := s.CreateClient(c) + err := s.CreateClient(ctx, c) require.NoError(t, err) c1 := storage.Connector{ @@ -252,7 +309,7 @@ func mockConnectorDataTestStorage(t *testing.T, s storage.Storage) { }`), } - err = s.CreateConnector(c1) + err = s.CreateConnector(ctx, c1) require.NoError(t, err) c2 := storage.Connector{ @@ -261,52 +318,487 @@ func mockConnectorDataTestStorage(t *testing.T, s storage.Storage) { Name: "mockURLID", } - err = s.CreateConnector(c2) + err = s.CreateConnector(ctx, c2) require.NoError(t, err) } -func TestPasswordConnectorDataNotEmpty(t *testing.T) { - t0 := time.Now() +func TestHandlePassword(t *testing.T) { + ctx := t.Context() + + tests := []struct { + name string + scopes string + offlineSessionCreated bool + }{ + { + name: "Password login, request refresh token", + scopes: "openid offline_access email", + offlineSessionCreated: true, + }, + { + name: "Password login", + scopes: "openid email", + offlineSessionCreated: false, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + // Setup a dex server. + httpServer, s := newTestServer(t, func(c *Config) { + c.PasswordConnector = "test" + c.Now = time.Now + }) + defer httpServer.Close() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + mockConnectorDataTestStorage(t, s.storage) - // Setup a dex server. - httpServer, s := newTestServer(ctx, t, func(c *Config) { - c.PasswordConnector = "test" - c.Now = func() time.Time { return t0 } - }) - defer httpServer.Close() + makeReq := func(username, password string) *httptest.ResponseRecorder { + u, err := url.Parse(s.issuerURL.String()) + require.NoError(t, err) - mockConnectorDataTestStorage(t, s.storage) + u.Path = path.Join(u.Path, "/token") + v := url.Values{} + v.Add("scope", tc.scopes) + v.Add("grant_type", "password") + v.Add("username", username) + v.Add("password", password) - u, err := url.Parse(s.issuerURL.String()) - require.NoError(t, err) + req, _ := http.NewRequest("POST", u.String(), bytes.NewBufferString(v.Encode())) + req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value") + req.SetBasicAuth("test", "barfoo") - u.Path = path.Join(u.Path, "/token") - v := url.Values{} - v.Add("scope", "openid offline_access email") - v.Add("grant_type", "password") - v.Add("username", "test") - v.Add("password", "test") + rr := httptest.NewRecorder() + s.ServeHTTP(rr, req) - req, _ := http.NewRequest("POST", u.String(), bytes.NewBufferString(v.Encode())) - req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value") - req.SetBasicAuth("test", "barfoo") + return rr + } - rr := httptest.NewRecorder() - s.ServeHTTP(rr, req) + // Check unauthorized error + { + rr := makeReq("test", "invalid") + require.Equal(t, 401, rr.Code) + } - require.Equal(t, 200, rr.Code) + // Check that we received expected refresh token + { + rr := makeReq("test", "test") + require.Equal(t, 200, rr.Code) - // Check that we received expected refresh token - var ref struct { - Token string `json:"refresh_token"` + var ref struct { + Token string `json:"refresh_token"` + } + err := json.Unmarshal(rr.Body.Bytes(), &ref) + require.NoError(t, err) + + newSess, err := s.storage.GetOfflineSessions(ctx, "0-385-28089-0", "test") + if tc.offlineSessionCreated { + require.NoError(t, err) + require.Equal(t, `{"test": "true"}`, string(newSess.ConnectorData)) + } else { + require.Error(t, storage.ErrNotFound, err) + } + } + }) } - err = json.Unmarshal(rr.Body.Bytes(), &ref) - require.NoError(t, err) +} - newSess, err := s.storage.GetOfflineSessions("0-385-28089-0", "test") - require.NoError(t, err) - require.Equal(t, `{"test": "true"}`, string(newSess.ConnectorData)) +func TestHandlePasswordLoginWithSkipApproval(t *testing.T) { + ctx := t.Context() + + connID := "mockPw" + authReqID := "test" + expiry := time.Now().Add(100 * time.Second) + resTypes := []string{responseTypeCode} + + tests := []struct { + name string + skipApproval bool + authReq storage.AuthRequest + expectedRes string + offlineSessionCreated bool + }{ + { + name: "Force approval", + skipApproval: false, + authReq: storage.AuthRequest{ + ID: authReqID, + ConnectorID: connID, + RedirectURI: "cb", + Expiry: expiry, + ResponseTypes: resTypes, + ForceApprovalPrompt: true, + }, + expectedRes: "/approval", + offlineSessionCreated: false, + }, + { + name: "Skip approval by server config", + skipApproval: true, + authReq: storage.AuthRequest{ + ID: authReqID, + ConnectorID: connID, + RedirectURI: "cb", + Expiry: expiry, + ResponseTypes: resTypes, + ForceApprovalPrompt: true, + }, + expectedRes: "/approval", + offlineSessionCreated: false, + }, + { + name: "No skip", + skipApproval: false, + authReq: storage.AuthRequest{ + ID: authReqID, + ConnectorID: connID, + RedirectURI: "cb", + Expiry: expiry, + ResponseTypes: resTypes, + ForceApprovalPrompt: false, + }, + expectedRes: "/approval", + offlineSessionCreated: false, + }, + { + name: "Skip approval", + skipApproval: true, + authReq: storage.AuthRequest{ + ID: authReqID, + ConnectorID: connID, + RedirectURI: "cb", + Expiry: expiry, + ResponseTypes: resTypes, + ForceApprovalPrompt: false, + }, + expectedRes: "/auth/mockPw/cb", + offlineSessionCreated: false, + }, + { + name: "Force approval, request refresh token", + skipApproval: false, + authReq: storage.AuthRequest{ + ID: authReqID, + ConnectorID: connID, + RedirectURI: "cb", + Expiry: expiry, + ResponseTypes: resTypes, + ForceApprovalPrompt: true, + Scopes: []string{"offline_access"}, + }, + expectedRes: "/approval", + offlineSessionCreated: true, + }, + { + name: "Skip approval, request refresh token", + skipApproval: true, + authReq: storage.AuthRequest{ + ID: authReqID, + ConnectorID: connID, + RedirectURI: "cb", + Expiry: expiry, + ResponseTypes: resTypes, + ForceApprovalPrompt: false, + Scopes: []string{"offline_access"}, + }, + expectedRes: "/auth/mockPw/cb", + offlineSessionCreated: true, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + httpServer, s := newTestServer(t, func(c *Config) { + c.SkipApprovalScreen = tc.skipApproval + c.Now = time.Now + }) + defer httpServer.Close() + + sc := storage.Connector{ + ID: connID, + Type: "mockPassword", + Name: "MockPassword", + ResourceVersion: "1", + Config: []byte("{\"username\": \"foo\", \"password\": \"password\"}"), + } + if err := s.storage.CreateConnector(ctx, sc); err != nil { + t.Fatalf("create connector: %v", err) + } + if _, err := s.OpenConnector(sc); err != nil { + t.Fatalf("open connector: %v", err) + } + if err := s.storage.CreateAuthRequest(ctx, tc.authReq); err != nil { + t.Fatalf("failed to create AuthRequest: %v", err) + } + + rr := httptest.NewRecorder() + + path := fmt.Sprintf("/auth/%s/login?state=%s&back=&login=foo&password=password", connID, authReqID) + s.handlePasswordLogin(rr, httptest.NewRequest("POST", path, nil)) + + require.Equal(t, 303, rr.Code) + + resp := rr.Result() + + defer resp.Body.Close() + + cb, _ := url.Parse(resp.Header.Get("Location")) + require.Equal(t, tc.expectedRes, cb.Path) + + offlineSession, err := s.storage.GetOfflineSessions(ctx, "0-385-28089-0", connID) + if tc.offlineSessionCreated { + require.NoError(t, err) + require.NotEmpty(t, offlineSession) + } else { + require.Error(t, storage.ErrNotFound, err) + } + }) + } +} + +func TestHandleConnectorCallbackWithSkipApproval(t *testing.T) { + ctx := t.Context() + + connID := "mock" + authReqID := "test" + expiry := time.Now().Add(100 * time.Second) + resTypes := []string{responseTypeCode} + + tests := []struct { + name string + skipApproval bool + authReq storage.AuthRequest + expectedRes string + offlineSessionCreated bool + }{ + { + name: "Force approval", + skipApproval: false, + authReq: storage.AuthRequest{ + ID: authReqID, + ConnectorID: connID, + RedirectURI: "cb", + Expiry: expiry, + ResponseTypes: resTypes, + ForceApprovalPrompt: true, + }, + expectedRes: "/approval", + offlineSessionCreated: false, + }, + { + name: "Skip approval by server config", + skipApproval: true, + authReq: storage.AuthRequest{ + ID: authReqID, + ConnectorID: connID, + RedirectURI: "cb", + Expiry: expiry, + ResponseTypes: resTypes, + ForceApprovalPrompt: true, + }, + expectedRes: "/approval", + offlineSessionCreated: false, + }, + { + name: "Skip approval by auth request", + skipApproval: false, + authReq: storage.AuthRequest{ + ID: authReqID, + ConnectorID: connID, + RedirectURI: "cb", + Expiry: expiry, + ResponseTypes: resTypes, + ForceApprovalPrompt: false, + }, + expectedRes: "/approval", + offlineSessionCreated: false, + }, + { + name: "Skip approval", + skipApproval: true, + authReq: storage.AuthRequest{ + ID: authReqID, + ConnectorID: connID, + RedirectURI: "cb", + Expiry: expiry, + ResponseTypes: resTypes, + ForceApprovalPrompt: false, + }, + expectedRes: "/callback/cb", + offlineSessionCreated: false, + }, + { + name: "Force approval, request refresh token", + skipApproval: false, + authReq: storage.AuthRequest{ + ID: authReqID, + ConnectorID: connID, + RedirectURI: "cb", + Expiry: expiry, + ResponseTypes: resTypes, + ForceApprovalPrompt: true, + Scopes: []string{"offline_access"}, + }, + expectedRes: "/approval", + offlineSessionCreated: true, + }, + { + name: "Skip approval, request refresh token", + skipApproval: true, + authReq: storage.AuthRequest{ + ID: authReqID, + ConnectorID: connID, + RedirectURI: "cb", + Expiry: expiry, + ResponseTypes: resTypes, + ForceApprovalPrompt: false, + Scopes: []string{"offline_access"}, + }, + expectedRes: "/callback/cb", + offlineSessionCreated: false, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + httpServer, s := newTestServer(t, func(c *Config) { + c.SkipApprovalScreen = tc.skipApproval + c.Now = time.Now + }) + defer httpServer.Close() + + if err := s.storage.CreateAuthRequest(ctx, tc.authReq); err != nil { + t.Fatalf("failed to create AuthRequest: %v", err) + } + rr := httptest.NewRecorder() + + path := fmt.Sprintf("/callback/%s?state=%s", connID, authReqID) + s.handleConnectorCallback(rr, httptest.NewRequest("GET", path, nil)) + + require.Equal(t, 303, rr.Code) + + resp := rr.Result() + defer resp.Body.Close() + + cb, _ := url.Parse(resp.Header.Get("Location")) + require.Equal(t, tc.expectedRes, cb.Path) + + offlineSession, err := s.storage.GetOfflineSessions(ctx, "0-385-28089-0", connID) + if tc.offlineSessionCreated { + require.NoError(t, err) + require.NotEmpty(t, offlineSession) + } else { + require.Error(t, storage.ErrNotFound, err) + } + }) + } +} + +func TestHandleTokenExchange(t *testing.T) { + tests := []struct { + name string + scope string + requestedTokenType string + subjectTokenType string + subjectToken string + + expectedCode int + expectedTokenType string + }{ + { + "id-for-acccess", + "openid", + tokenTypeAccess, + tokenTypeID, + "foobar", + http.StatusOK, + tokenTypeAccess, + }, + { + "id-for-id", + "openid", + tokenTypeID, + tokenTypeID, + "foobar", + http.StatusOK, + tokenTypeID, + }, + { + "id-for-default", + "openid", + "", + tokenTypeID, + "foobar", + http.StatusOK, + tokenTypeAccess, + }, + { + "access-for-access", + "openid", + tokenTypeAccess, + tokenTypeAccess, + "foobar", + http.StatusOK, + tokenTypeAccess, + }, + { + "missing-subject_token_type", + "openid", + tokenTypeAccess, + "", + "foobar", + http.StatusBadRequest, + "", + }, + { + "missing-subject_token", + "openid", + tokenTypeAccess, + tokenTypeAccess, + "", + http.StatusBadRequest, + "", + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + ctx := t.Context() + httpServer, s := newTestServer(t, func(c *Config) { + c.Storage.CreateClient(ctx, storage.Client{ + ID: "client_1", + Secret: "secret_1", + }) + }) + defer httpServer.Close() + vals := make(url.Values) + vals.Set("grant_type", grantTypeTokenExchange) + setNonEmpty(vals, "connector_id", "mock") + setNonEmpty(vals, "scope", tc.scope) + setNonEmpty(vals, "requested_token_type", tc.requestedTokenType) + setNonEmpty(vals, "subject_token_type", tc.subjectTokenType) + setNonEmpty(vals, "subject_token", tc.subjectToken) + setNonEmpty(vals, "client_id", "client_1") + setNonEmpty(vals, "client_secret", "secret_1") + + rr := httptest.NewRecorder() + req := httptest.NewRequest(http.MethodPost, httpServer.URL+"/token", strings.NewReader(vals.Encode())) + req.Header.Set("content-type", "application/x-www-form-urlencoded") + + s.handleToken(rr, req) + + require.Equal(t, tc.expectedCode, rr.Code, rr.Body.String()) + require.Equal(t, "application/json", rr.Result().Header.Get("content-type")) + if tc.expectedCode == http.StatusOK { + var res accessTokenResponse + err := json.NewDecoder(rr.Result().Body).Decode(&res) + require.NoError(t, err) + require.Equal(t, tc.expectedTokenType, res.IssuedTokenType) + } + }) + } +} + +func setNonEmpty(vals url.Values, key, value string) { + if value != "" { + vals.Set(key, value) + } } diff --git a/server/internal/types.pb.go b/server/internal/types.pb.go index 379c556a93..cabbea2e8f 100644 --- a/server/internal/types.pb.go +++ b/server/internal/types.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.15.6 +// protoc-gen-go v1.36.5 +// protoc v5.29.3 // source: server/internal/types.proto // Package internal holds protobuf types used by the server. @@ -13,6 +13,7 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -24,21 +25,18 @@ const ( // RefreshToken is a message that holds refresh token data used by dex. type RefreshToken struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + RefreshId string `protobuf:"bytes,1,opt,name=refresh_id,json=refreshId,proto3" json:"refresh_id,omitempty"` + Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` unknownFields protoimpl.UnknownFields - - RefreshId string `protobuf:"bytes,1,opt,name=refresh_id,json=refreshId,proto3" json:"refresh_id,omitempty"` - Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` + sizeCache protoimpl.SizeCache } func (x *RefreshToken) Reset() { *x = RefreshToken{} - if protoimpl.UnsafeEnabled { - mi := &file_server_internal_types_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_server_internal_types_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *RefreshToken) String() string { @@ -49,7 +47,7 @@ func (*RefreshToken) ProtoMessage() {} func (x *RefreshToken) ProtoReflect() protoreflect.Message { mi := &file_server_internal_types_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -81,21 +79,18 @@ func (x *RefreshToken) GetToken() string { // IDTokenSubject represents both the userID and connID which is returned // as the "sub" claim in the ID Token. type IDTokenSubject struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + ConnId string `protobuf:"bytes,2,opt,name=conn_id,json=connId,proto3" json:"conn_id,omitempty"` unknownFields protoimpl.UnknownFields - - UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` - ConnId string `protobuf:"bytes,2,opt,name=conn_id,json=connId,proto3" json:"conn_id,omitempty"` + sizeCache protoimpl.SizeCache } func (x *IDTokenSubject) Reset() { *x = IDTokenSubject{} - if protoimpl.UnsafeEnabled { - mi := &file_server_internal_types_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_server_internal_types_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *IDTokenSubject) String() string { @@ -106,7 +101,7 @@ func (*IDTokenSubject) ProtoMessage() {} func (x *IDTokenSubject) ProtoReflect() protoreflect.Message { mi := &file_server_internal_types_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -137,7 +132,7 @@ func (x *IDTokenSubject) GetConnId() string { var File_server_internal_types_proto protoreflect.FileDescriptor -var file_server_internal_types_proto_rawDesc = []byte{ +var file_server_internal_types_proto_rawDesc = string([]byte{ 0x0a, 0x1b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x22, 0x43, 0x0a, 0x0c, 0x52, 0x65, 0x66, 0x72, 0x65, @@ -153,22 +148,22 @@ var file_server_internal_types_proto_rawDesc = []byte{ 0x65, 0x78, 0x69, 0x64, 0x70, 0x2f, 0x64, 0x65, 0x78, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} +}) var ( file_server_internal_types_proto_rawDescOnce sync.Once - file_server_internal_types_proto_rawDescData = file_server_internal_types_proto_rawDesc + file_server_internal_types_proto_rawDescData []byte ) func file_server_internal_types_proto_rawDescGZIP() []byte { file_server_internal_types_proto_rawDescOnce.Do(func() { - file_server_internal_types_proto_rawDescData = protoimpl.X.CompressGZIP(file_server_internal_types_proto_rawDescData) + file_server_internal_types_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_server_internal_types_proto_rawDesc), len(file_server_internal_types_proto_rawDesc))) }) return file_server_internal_types_proto_rawDescData } var file_server_internal_types_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_server_internal_types_proto_goTypes = []interface{}{ +var file_server_internal_types_proto_goTypes = []any{ (*RefreshToken)(nil), // 0: internal.RefreshToken (*IDTokenSubject)(nil), // 1: internal.IDTokenSubject } @@ -185,37 +180,11 @@ func file_server_internal_types_proto_init() { if File_server_internal_types_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_server_internal_types_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RefreshToken); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_server_internal_types_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IDTokenSubject); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_server_internal_types_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_server_internal_types_proto_rawDesc), len(file_server_internal_types_proto_rawDesc)), NumEnums: 0, NumMessages: 2, NumExtensions: 0, @@ -226,7 +195,6 @@ func file_server_internal_types_proto_init() { MessageInfos: file_server_internal_types_proto_msgTypes, }.Build() File_server_internal_types_proto = out.File - file_server_internal_types_proto_rawDesc = nil file_server_internal_types_proto_goTypes = nil file_server_internal_types_proto_depIdxs = nil } diff --git a/server/introspectionhandler.go b/server/introspectionhandler.go new file mode 100644 index 0000000000..42ad1b3c70 --- /dev/null +++ b/server/introspectionhandler.go @@ -0,0 +1,348 @@ +package server + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "net/http" + + "github.com/coreos/go-oidc/v3/oidc" + + "github.com/dexidp/dex/server/internal" +) + +// Introspection contains an access token's session data as specified by +// [IETF RFC 7662](https://tools.ietf.org/html/rfc7662) +type Introspection struct { + // Boolean indicator of whether or not the presented token + // is currently active. The specifics of a token's "active" state + // will vary depending on the implementation of the authorization + // server and the information it keeps about its tokens, but a "true" + // value return for the "active" property will generally indicate + // that a given token has been issued by this authorization server, + // has not been revoked by the resource owner, and is within its + // given time window of validity (e.g., after its issuance time and + // before its expiration time). + Active bool `json:"active"` + + // JSON string containing a space-separated list of + // scopes associated with this token. + Scope string `json:"scope,omitempty"` + + // Client identifier for the OAuth 2.0 client that + // requested this token. + ClientID string `json:"client_id"` + + // Subject of the token, as defined in JWT [RFC7519]. + // Usually a machine-readable identifier of the resource owner who + // authorized this token. + Subject string `json:"sub"` + + // Integer timestamp, measured in the number of seconds + // since January 1 1970 UTC, indicating when this token will expire. + Expiry int64 `json:"exp"` + + // Integer timestamp, measured in the number of seconds + // since January 1 1970 UTC, indicating when this token was + // originally issued. + IssuedAt int64 `json:"iat"` + + // Integer timestamp, measured in the number of seconds + // since January 1 1970 UTC, indicating when this token is not to be + // used before. + NotBefore int64 `json:"nbf"` + + // Human-readable identifier for the resource owner who + // authorized this token. + Username string `json:"username,omitempty"` + + // Service-specific string identifier or list of string + // identifiers representing the intended audience for this token, as + // defined in JWT + Audience audience `json:"aud"` + + // String representing the issuer of this token, as + // defined in JWT + Issuer string `json:"iss"` + + // String identifier for the token, as defined in JWT [RFC7519]. + JwtTokenID string `json:"jti,omitempty"` + + // TokenType is the introspected token's type, typically `bearer`. + TokenType string `json:"token_type"` + + // TokenUse is the introspected token's use, for example `access_token` or `refresh_token`. + TokenUse string `json:"token_use"` + + // Extra is arbitrary data set from the token claims. + Extra IntrospectionExtra `json:"ext,omitempty"` +} + +type IntrospectionExtra struct { + AuthorizingParty string `json:"azp,omitempty"` + + Email string `json:"email,omitempty"` + EmailVerified *bool `json:"email_verified,omitempty"` + + Groups []string `json:"groups,omitempty"` + + Name string `json:"name,omitempty"` + PreferredUsername string `json:"preferred_username,omitempty"` + + FederatedIDClaims *federatedIDClaims `json:"federated_claims,omitempty"` +} + +type TokenTypeEnum int + +const ( + AccessToken TokenTypeEnum = iota + RefreshToken +) + +func (t TokenTypeEnum) String() string { + switch t { + case AccessToken: + return "access_token" + case RefreshToken: + return "refresh_token" + default: + return fmt.Sprintf("TokenTypeEnum(%d)", t) + } +} + +type introspectionError struct { + typ string + code int + desc string +} + +func (e *introspectionError) Error() string { + return fmt.Sprintf("introspection error: status %d, %q %s", e.code, e.typ, e.desc) +} + +func (e *introspectionError) Is(tgt error) bool { + target, ok := tgt.(*introspectionError) + if !ok { + return false + } + + return e.typ == target.typ && + e.code == target.code && + e.desc == target.desc +} + +func newIntrospectInactiveTokenError() *introspectionError { + return &introspectionError{typ: errInactiveToken, desc: "", code: http.StatusUnauthorized} +} + +func newIntrospectInternalServerError() *introspectionError { + return &introspectionError{typ: errServerError, desc: "", code: http.StatusInternalServerError} +} + +func newIntrospectBadRequestError(desc string) *introspectionError { + return &introspectionError{typ: errInvalidRequest, desc: desc, code: http.StatusBadRequest} +} + +func (s *Server) guessTokenType(ctx context.Context, token string) (TokenTypeEnum, error) { + // We skip every checks, we only want to know if it's a valid JWT + verifierConfig := oidc.Config{ + SkipClientIDCheck: true, + SkipExpiryCheck: true, + SkipIssuerCheck: true, + + // We skip signature checks to avoid database calls; + InsecureSkipSignatureCheck: true, + } + + verifier := oidc.NewVerifier(s.issuerURL.String(), nil, &verifierConfig) + if _, err := verifier.Verify(ctx, token); err != nil { + // If it's not an access token, let's assume it's a refresh token; + return RefreshToken, nil + } + + // If it's a valid JWT, it's an access token. + return AccessToken, nil +} + +func (s *Server) getTokenFromRequest(r *http.Request) (string, TokenTypeEnum, error) { + if r.Method != "POST" { + return "", 0, newIntrospectBadRequestError(fmt.Sprintf("HTTP method is \"%s\", expected \"POST\".", r.Method)) + } else if err := r.ParseForm(); err != nil { + return "", 0, newIntrospectBadRequestError("Unable to parse HTTP body, make sure to send a properly formatted form request body.") + } else if len(r.PostForm) == 0 { + return "", 0, newIntrospectBadRequestError("The POST body can not be empty.") + } else if !r.PostForm.Has("token") { + return "", 0, newIntrospectBadRequestError("The POST body doesn't contain 'token' parameter.") + } + + token := r.PostForm.Get("token") + tokenType, err := s.guessTokenType(r.Context(), token) + if err != nil { + s.logger.ErrorContext(r.Context(), "failed to guess token type", "err", err) + return "", 0, newIntrospectInternalServerError() + } + + requestTokenType := r.PostForm.Get("token_type_hint") + if requestTokenType != "" { + if tokenType.String() != requestTokenType { + s.logger.Warn("token type hint doesn't match token type", "request_token_type", requestTokenType, "token_type", tokenType) + } + } + + return token, tokenType, nil +} + +func (s *Server) introspectRefreshToken(ctx context.Context, token string) (*Introspection, error) { + rToken := new(internal.RefreshToken) + if err := internal.Unmarshal(token, rToken); err != nil { + // For backward compatibility, assume the refresh_token is a raw refresh token ID + // if it fails to decode. + // + // Because refresh_token values that aren't unmarshable were generated by servers + // that don't have a Token value, we'll still reject any attempts to claim a + // refresh_token twice. + rToken = &internal.RefreshToken{RefreshId: token, Token: ""} + } + + rCtx, err := s.getRefreshTokenFromStorage(ctx, nil, rToken) + if err != nil { + if errors.Is(err, invalidErr) || errors.Is(err, expiredErr) { + return nil, newIntrospectInactiveTokenError() + } + + s.logger.ErrorContext(ctx, "failed to get refresh token", "err", err) + return nil, newIntrospectInternalServerError() + } + + subjectString, sErr := genSubject(rCtx.storageToken.Claims.UserID, rCtx.storageToken.ConnectorID) + if sErr != nil { + s.logger.ErrorContext(ctx, "failed to marshal offline session ID", "err", err) + return nil, newIntrospectInternalServerError() + } + + return &Introspection{ + Active: true, + ClientID: rCtx.storageToken.ClientID, + IssuedAt: rCtx.storageToken.CreatedAt.Unix(), + NotBefore: rCtx.storageToken.CreatedAt.Unix(), + Expiry: rCtx.storageToken.CreatedAt.Add(s.refreshTokenPolicy.absoluteLifetime).Unix(), + Subject: subjectString, + Username: rCtx.storageToken.Claims.PreferredUsername, + Audience: getAudience(rCtx.storageToken.ClientID, rCtx.scopes), + Issuer: s.issuerURL.String(), + + Extra: IntrospectionExtra{ + Email: rCtx.storageToken.Claims.Email, + EmailVerified: &rCtx.storageToken.Claims.EmailVerified, + Groups: rCtx.storageToken.Claims.Groups, + Name: rCtx.storageToken.Claims.Username, + PreferredUsername: rCtx.storageToken.Claims.PreferredUsername, + }, + TokenType: "Bearer", + TokenUse: "refresh_token", + }, nil +} + +func (s *Server) introspectAccessToken(ctx context.Context, token string) (*Introspection, error) { + verifier := oidc.NewVerifier(s.issuerURL.String(), &storageKeySet{s.storage}, &oidc.Config{SkipClientIDCheck: true}) + idToken, err := verifier.Verify(ctx, token) + if err != nil { + return nil, newIntrospectInactiveTokenError() + } + + var claims IntrospectionExtra + if err := idToken.Claims(&claims); err != nil { + s.logger.ErrorContext(ctx, "error while fetching token claims", "err", err.Error()) + return nil, newIntrospectInternalServerError() + } + + clientID, err := getClientID(idToken.Audience, claims.AuthorizingParty) + if err != nil { + s.logger.ErrorContext(ctx, "error while fetching client_id from token:", "err", err.Error()) + return nil, newIntrospectInternalServerError() + } + + client, err := s.storage.GetClient(ctx, clientID) + if err != nil { + s.logger.ErrorContext(ctx, "error while fetching client from storage", "err", err.Error()) + return nil, newIntrospectInternalServerError() + } + + return &Introspection{ + Active: true, + ClientID: client.ID, + IssuedAt: idToken.IssuedAt.Unix(), + NotBefore: idToken.IssuedAt.Unix(), + Expiry: idToken.Expiry.Unix(), + Subject: idToken.Subject, + Username: claims.PreferredUsername, + Audience: idToken.Audience, + Issuer: s.issuerURL.String(), + + Extra: claims, + TokenType: "Bearer", + TokenUse: "access_token", + }, nil +} + +func (s *Server) handleIntrospect(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + var introspect *Introspection + token, tokenType, err := s.getTokenFromRequest(r) + if err == nil { + switch tokenType { + case AccessToken: + introspect, err = s.introspectAccessToken(ctx, token) + case RefreshToken: + introspect, err = s.introspectRefreshToken(ctx, token) + default: + // Token type is neither handled token types. + s.logger.ErrorContext(r.Context(), "unknown token type", "token_type", tokenType) + introspectInactiveErr(w) + return + } + } + + if err != nil { + if intErr, ok := err.(*introspectionError); ok { + s.introspectErrHelper(w, intErr.typ, intErr.desc, intErr.code) + } else { + s.logger.ErrorContext(r.Context(), "an unknown error occurred", "err", err.Error()) + s.introspectErrHelper(w, errServerError, "An unknown error occurred", http.StatusInternalServerError) + } + + return + } + + rawJSON, jsonErr := json.Marshal(introspect) + if jsonErr != nil { + s.introspectErrHelper(w, errServerError, jsonErr.Error(), 500) + } + + w.Header().Set("Content-Type", "application/json") + w.Write(rawJSON) +} + +func (s *Server) introspectErrHelper(w http.ResponseWriter, typ string, description string, statusCode int) { + if typ == errInactiveToken { + introspectInactiveErr(w) + return + } + + if err := tokenErr(w, typ, description, statusCode); err != nil { + // TODO(nabokihms): error with context + s.logger.Error("introspect error response", "err", err) + } +} + +func introspectInactiveErr(w http.ResponseWriter) { + w.Header().Set("Cache-Control", "no-store") + w.Header().Set("Pragma", "no-cache") + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + json.NewEncoder(w).Encode(struct { + Active bool `json:"active"` + }{Active: false}) +} diff --git a/server/introspectionhandler_test.go b/server/introspectionhandler_test.go new file mode 100644 index 0000000000..6f18d0561b --- /dev/null +++ b/server/introspectionhandler_test.go @@ -0,0 +1,408 @@ +package server + +import ( + "bytes" + "encoding/json" + "io" + "net/http" + "net/http/httptest" + "net/url" + "path" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/dexidp/dex/server/internal" + "github.com/dexidp/dex/storage" +) + +func toJSON(a interface{}) string { + b, err := json.Marshal(a) + if err != nil { + return "" + } + + return string(b) +} + +func mockTestStorage(t *testing.T, s storage.Storage) { + ctx := t.Context() + c := storage.Client{ + ID: "test", + Secret: "barfoo", + RedirectURIs: []string{"foo://bar.com/", "https://auth.example.com"}, + Name: "dex client", + LogoURL: "https://goo.gl/JIyzIC", + } + + err := s.CreateClient(ctx, c) + require.NoError(t, err) + + c1 := storage.Connector{ + ID: "test", + Type: "mockPassword", + Name: "mockPassword", + Config: []byte(`{ +"username": "test", +"password": "test" +}`), + } + + err = s.CreateConnector(ctx, c1) + require.NoError(t, err) + + err = s.CreateRefresh(ctx, storage.RefreshToken{ + ID: "test", + Token: "bar", + ObsoleteToken: "", + Nonce: "foo", + ClientID: "test", + ConnectorID: "test", + Scopes: []string{"openid", "email", "profile"}, + CreatedAt: time.Now().UTC().Round(time.Millisecond), + LastUsed: time.Now().UTC().Round(time.Millisecond), + Claims: storage.Claims{ + UserID: "1", + Username: "jane", + Email: "jane.doe@example.com", + EmailVerified: true, + Groups: []string{"a", "b"}, + }, + ConnectorData: []byte(`{"some":"data"}`), + }) + require.NoError(t, err) + + err = s.CreateRefresh(ctx, storage.RefreshToken{ + ID: "expired", + Token: "bar", + ObsoleteToken: "", + Nonce: "foo", + ClientID: "test", + ConnectorID: "test", + Scopes: []string{"openid", "email", "profile"}, + CreatedAt: time.Now().AddDate(-1, 0, 0).UTC().Round(time.Millisecond), + LastUsed: time.Now().AddDate(-1, 0, 0).UTC().Round(time.Millisecond), + Claims: storage.Claims{ + UserID: "1", + Username: "jane", + Email: "jane.doe@example.com", + EmailVerified: true, + Groups: []string{"a", "b"}, + }, + ConnectorData: []byte(`{"some":"data"}`), + }) + require.NoError(t, err) + + err = s.CreateOfflineSessions(ctx, storage.OfflineSessions{ + UserID: "1", + ConnID: "test", + Refresh: map[string]*storage.RefreshTokenRef{ + "test": {ID: "test", ClientID: "test"}, + "expired": {ID: "expired", ClientID: "test"}, + }, + ConnectorData: nil, + }) + require.NoError(t, err) +} + +func getIntrospectionValue(issuerURL url.URL, issuedAt time.Time, expiry time.Time, tokenUse string) *Introspection { + trueValue := true + return &Introspection{ + Active: true, + ClientID: "test", + Subject: "CgExEgR0ZXN0", + Expiry: expiry.Unix(), + IssuedAt: issuedAt.Unix(), + NotBefore: issuedAt.Unix(), + Audience: []string{ + "test", + }, + Issuer: issuerURL.String(), + TokenType: "Bearer", + TokenUse: tokenUse, + Extra: IntrospectionExtra{ + Email: "jane.doe@example.com", + EmailVerified: &trueValue, + Groups: []string{ + "a", + "b", + }, + Name: "jane", + }, + } +} + +func TestGetTokenFromRequestSuccess(t *testing.T) { + t0 := time.Now() + + now := func() time.Time { return t0 } + // Setup a dex server. + httpServer, s := newTestServer(t, func(c *Config) { + c.Issuer += "/non-root-path" + c.Now = now + }) + defer httpServer.Close() + + tests := []struct { + testName string + expectedToken string + expectedTokenType TokenTypeEnum + }{ + // Access Token + { + testName: "Access Token", + expectedToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c", + expectedTokenType: AccessToken, + }, + // Refresh Token + { + testName: "Refresh token", + expectedToken: "CgR0ZXN0EgNiYXI", + expectedTokenType: RefreshToken, + }, + // Unknown token + { + testName: "Unknown token", + expectedToken: "AaAaAaA", + expectedTokenType: RefreshToken, + }, + } + + for _, tc := range tests { + t.Run(tc.testName, func(t *testing.T) { + data := url.Values{} + data.Set("token", tc.expectedToken) + req := httptest.NewRequest(http.MethodPost, "https://test.tech/token/introspect", bytes.NewBufferString(data.Encode())) + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + + token, tokenType, err := s.getTokenFromRequest(req) + if err != nil { + t.Fatalf("Error returned: %s", err.Error()) + } + + if token != tc.expectedToken { + t.Fatalf("Wrong token returned. Expected %v got %v", tc.expectedToken, token) + } + + if tokenType != tc.expectedTokenType { + t.Fatalf("Wrong token type returned. Expected %v got %v", tc.expectedTokenType, tokenType) + } + }) + } +} + +func TestGetTokenFromRequestFailure(t *testing.T) { + t0 := time.Now() + + now := func() time.Time { return t0 } + + // Setup a dex server. + httpServer, s := newTestServer(t, func(c *Config) { + c.Issuer += "/non-root-path" + c.Now = now + }) + defer httpServer.Close() + + _, _, err := s.getTokenFromRequest(httptest.NewRequest(http.MethodGet, "https://test.tech/token/introspect", nil)) + require.ErrorIs(t, err, &introspectionError{ + typ: errInvalidRequest, + desc: "HTTP method is \"GET\", expected \"POST\".", + code: http.StatusBadRequest, + }) + + _, _, err = s.getTokenFromRequest(httptest.NewRequest(http.MethodPost, "https://test.tech/token/introspect", nil)) + require.ErrorIs(t, err, &introspectionError{ + typ: errInvalidRequest, + desc: "The POST body can not be empty.", + code: http.StatusBadRequest, + }) + + req := httptest.NewRequest(http.MethodPost, "https://test.tech/token/introspect", strings.NewReader("token_type_hint=access_token")) + req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + _, _, err = s.getTokenFromRequest(req) + require.ErrorIs(t, err, &introspectionError{ + typ: errInvalidRequest, + desc: "The POST body doesn't contain 'token' parameter.", + code: http.StatusBadRequest, + }) +} + +func TestHandleIntrospect(t *testing.T) { + t0 := time.Now() + + ctx := t.Context() + + // Setup a dex server. + now := func() time.Time { return t0 } + + logger := newLogger(t) + + refreshTokenPolicy, err := NewRefreshTokenPolicy(logger, false, "", "24h", "") + if err != nil { + t.Fatalf("failed to prepare rotation policy: %v", err) + } + refreshTokenPolicy.now = now + + httpServer, s := newTestServer(t, func(c *Config) { + c.Issuer += "/non-root-path" + c.RefreshTokenPolicy = refreshTokenPolicy + c.Now = now + }) + defer httpServer.Close() + + mockTestStorage(t, s.storage) + + activeAccessToken, expiry, err := s.newIDToken(ctx, "test", storage.Claims{ + UserID: "1", + Username: "jane", + Email: "jane.doe@example.com", + EmailVerified: true, + Groups: []string{"a", "b"}, + }, []string{"openid", "email", "profile", "groups"}, "foo", "", "", "test") + require.NoError(t, err) + + activeRefreshToken, err := internal.Marshal(&internal.RefreshToken{RefreshId: "test", Token: "bar"}) + require.NoError(t, err) + expiredRefreshToken, err := internal.Marshal(&internal.RefreshToken{RefreshId: "expired", Token: "bar"}) + require.NoError(t, err) + + inactiveResponse := "{\"active\":false}\n" + badRequestResponse := `{"error":"invalid_request","error_description":"The POST body can not be empty."}` + + tests := []struct { + testName string + token string + tokenType string + response string + responseStatusCode int + }{ + // No token + { + testName: "No token", + response: badRequestResponse, + responseStatusCode: 400, + }, + // Access token tests + { + testName: "Access Token: active", + token: activeAccessToken, + response: toJSON(getIntrospectionValue(s.issuerURL, time.Now(), expiry, "access_token")), + responseStatusCode: 200, + }, + { + testName: "Access Token: wrong", + token: "fake-token", + response: inactiveResponse, + responseStatusCode: 200, + }, + // Refresh token tests + { + testName: "Refresh Token: active", + token: activeRefreshToken, + response: toJSON(getIntrospectionValue(s.issuerURL, time.Now(), time.Now().Add(s.refreshTokenPolicy.absoluteLifetime), "refresh_token")), + responseStatusCode: 200, + }, + { + testName: "Refresh Token: expired", + token: expiredRefreshToken, + response: inactiveResponse, + responseStatusCode: 200, + }, + { + testName: "Refresh Token: active => false (wrong)", + token: "fake-token", + response: inactiveResponse, + responseStatusCode: 200, + }, + } + + for _, tc := range tests { + t.Run(tc.testName, func(t *testing.T) { + data := url.Values{} + if tc.token != "" { + data.Set("token", tc.token) + } + if tc.tokenType != "" { + data.Set("token_type_hint", tc.tokenType) + } + + u, err := url.Parse(s.issuerURL.String()) + if err != nil { + t.Fatalf("Could not parse issuer URL %v", err) + } + u.Path = path.Join(u.Path, "token", "introspect") + + req, _ := http.NewRequest("POST", u.String(), bytes.NewBufferString(data.Encode())) + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + + rr := httptest.NewRecorder() + s.ServeHTTP(rr, req) + + if rr.Code != tc.responseStatusCode { + t.Errorf("%s: Unexpected Response Type. Expected %v got %v", tc.testName, tc.responseStatusCode, rr.Code) + } + + result, _ := io.ReadAll(rr.Body) + if string(result) != tc.response { + t.Errorf("%s: Unexpected Response. Expected %q got %q", tc.testName, tc.response, result) + } + }) + } +} + +func TestIntrospectErrHelper(t *testing.T) { + t0 := time.Now() + + now := func() time.Time { return t0 } + + // Setup a dex server. + httpServer, s := newTestServer(t, func(c *Config) { + c.Issuer += "/non-root-path" + c.Now = now + }) + defer httpServer.Close() + + tests := []struct { + testName string + err *introspectionError + resStatusCode int + resBody string + }{ + { + testName: "Inactive Token", + err: newIntrospectInactiveTokenError(), + resStatusCode: http.StatusOK, + resBody: "{\"active\":false}\n", + }, + { + testName: "Bad Request", + err: newIntrospectBadRequestError("This is a bad request"), + resStatusCode: http.StatusBadRequest, + resBody: `{"error":"invalid_request","error_description":"This is a bad request"}`, + }, + { + testName: "Internal Server Error", + err: newIntrospectInternalServerError(), + resStatusCode: http.StatusInternalServerError, + resBody: `{"error":"server_error"}`, + }, + } + for _, tc := range tests { + t.Run(tc.testName, func(t *testing.T) { + w1 := httptest.NewRecorder() + + s.introspectErrHelper(w1, tc.err.typ, tc.err.desc, tc.err.code) + + res := w1.Result() + require.Equal(t, tc.resStatusCode, res.StatusCode) + require.Equal(t, "application/json", res.Header.Get("Content-Type")) + + data, err := io.ReadAll(res.Body) + defer res.Body.Close() + require.NoError(t, err) + require.Equal(t, tc.resBody, string(data)) + }) + } +} diff --git a/server/oauth2.go b/server/oauth2.go index 998bf02ae5..18cc3dd46d 100644 --- a/server/oauth2.go +++ b/server/oauth2.go @@ -2,6 +2,7 @@ package server import ( "context" + "crypto" "crypto/ecdsa" "crypto/elliptic" "crypto/rsa" @@ -20,7 +21,7 @@ import ( "strings" "time" - jose "gopkg.in/square/go-jose.v2" + "github.com/go-jose/go-jose/v4" "github.com/dexidp/dex/connector" "github.com/dexidp/dex/server/internal" @@ -92,7 +93,6 @@ func tokenErr(w http.ResponseWriter, typ, description string, statusCode int) er return nil } -// nolint const ( errInvalidRequest = "invalid_request" errUnauthorizedClient = "unauthorized_client" @@ -105,6 +105,7 @@ const ( errUnsupportedGrantType = "unsupported_grant_type" errInvalidGrant = "invalid_grant" errInvalidClient = "invalid_client" + errInactiveToken = "inactive_token" ) const ( @@ -131,12 +132,27 @@ const ( grantTypeImplicit = "implicit" grantTypePassword = "password" grantTypeDeviceCode = "urn:ietf:params:oauth:grant-type:device_code" + grantTypeTokenExchange = "urn:ietf:params:oauth:grant-type:token-exchange" ) const ( - responseTypeCode = "code" // "Regular" flow - responseTypeToken = "token" // Implicit flow for frontend apps. - responseTypeIDToken = "id_token" // ID Token in url fragment + // https://www.rfc-editor.org/rfc/rfc8693.html#section-3 + tokenTypeAccess = "urn:ietf:params:oauth:token-type:access_token" + tokenTypeRefresh = "urn:ietf:params:oauth:token-type:refresh_token" + tokenTypeID = "urn:ietf:params:oauth:token-type:id_token" + tokenTypeSAML1 = "urn:ietf:params:oauth:token-type:saml1" + tokenTypeSAML2 = "urn:ietf:params:oauth:token-type:saml2" + tokenTypeJWT = "urn:ietf:params:oauth:token-type:jwt" +) + +const ( + responseTypeCode = "code" // "Regular" flow + responseTypeToken = "token" // Implicit flow for frontend apps. + responseTypeIDToken = "id_token" // ID Token in url fragment + responseTypeCodeToken = "code token" // "Regular" flow + Implicit flow + responseTypeCodeIDToken = "code id_token" // "Regular" flow + ID Token + responseTypeIDTokenToken = "id_token token" // ID Token + Implicit flow + responseTypeCodeIDTokenToken = "code id_token token" // "Regular" flow + ID Token + Implicit flow ) const ( @@ -210,9 +226,9 @@ func signPayload(key *jose.JSONWebKey, alg jose.SignatureAlgorithm, payload []by // The hash algorithm for the at_hash is determined by the signing // algorithm used for the id_token. From the spec: // -// ...the hash algorithm used is the hash algorithm used in the alg Header -// Parameter of the ID Token's JOSE Header. For instance, if the alg is RS256, -// hash the access_token value with SHA-256 +// ...the hash algorithm used is the hash algorithm used in the alg Header +// Parameter of the ID Token's JOSE Header. For instance, if the alg is RS256, +// hash the access_token value with SHA-256 // // https://openid.net/specs/openid-connect-core-1_0.html#ImplicitIDToken var hashForSigAlg = map[jose.SignatureAlgorithm]func() hash.Hash{ @@ -287,15 +303,57 @@ type federatedIDClaims struct { UserID string `json:"user_id,omitempty"` } -func (s *Server) newAccessToken(clientID string, claims storage.Claims, scopes []string, nonce, connID string) (accessToken string, err error) { - idToken, _, err := s.newIDToken(clientID, claims, scopes, nonce, storage.NewID(), "", connID) - return idToken, err +func (s *Server) newAccessToken(ctx context.Context, clientID string, claims storage.Claims, scopes []string, nonce, connID string) (accessToken string, expiry time.Time, err error) { + return s.newIDToken(ctx, clientID, claims, scopes, nonce, storage.NewID(), "", connID) +} + +func getClientID(aud audience, azp string) (string, error) { + switch len(aud) { + case 0: + return "", fmt.Errorf("no audience is set, could not find ClientID") + case 1: + return aud[0], nil + default: + return azp, nil + } +} + +func getAudience(clientID string, scopes []string) audience { + var aud audience + + for _, scope := range scopes { + if peerID, ok := parseCrossClientScope(scope); ok { + aud = append(aud, peerID) + } + } + + if len(aud) == 0 { + // Client didn't ask for cross client audience. Set the current + // client as the audience. + aud = audience{clientID} + // Client asked for cross client audience: + // if the current client was not requested explicitly + } else if !aud.contains(clientID) { + // by default it becomes one of entries in Audience + aud = append(aud, clientID) + } + + return aud +} + +func genSubject(userID string, connID string) (string, error) { + sub := &internal.IDTokenSubject{ + UserId: userID, + ConnId: connID, + } + + return internal.Marshal(sub) } -func (s *Server) newIDToken(clientID string, claims storage.Claims, scopes []string, nonce, accessToken, code, connID string) (idToken string, expiry time.Time, err error) { - keys, err := s.storage.GetKeys() +func (s *Server) newIDToken(ctx context.Context, clientID string, claims storage.Claims, scopes []string, nonce, accessToken, code, connID string) (idToken string, expiry time.Time, err error) { + keys, err := s.storage.GetKeys(ctx) if err != nil { - s.logger.Errorf("Failed to get keys: %v", err) + s.logger.ErrorContext(ctx, "failed to get keys", "err", err) return "", expiry, err } @@ -311,14 +369,9 @@ func (s *Server) newIDToken(clientID string, claims storage.Claims, scopes []str issuedAt := s.now() expiry = issuedAt.Add(s.idTokensValidFor) - sub := &internal.IDTokenSubject{ - UserId: claims.UserID, - ConnId: connID, - } - - subjectString, err := internal.Marshal(sub) + subjectString, err := genSubject(claims.UserID, connID) if err != nil { - s.logger.Errorf("failed to marshal offline session ID: %v", err) + s.logger.ErrorContext(ctx, "failed to marshal offline session ID", "err", err) return "", expiry, fmt.Errorf("failed to marshal offline session ID: %v", err) } @@ -333,7 +386,7 @@ func (s *Server) newIDToken(clientID string, claims storage.Claims, scopes []str if accessToken != "" { atHash, err := accessTokenHash(signingAlg, accessToken) if err != nil { - s.logger.Errorf("error computing at_hash: %v", err) + s.logger.ErrorContext(ctx, "error computing at_hash", "err", err) return "", expiry, fmt.Errorf("error computing at_hash: %v", err) } tok.AccessTokenHash = atHash @@ -342,7 +395,7 @@ func (s *Server) newIDToken(clientID string, claims storage.Claims, scopes []str if code != "" { cHash, err := accessTokenHash(signingAlg, code) if err != nil { - s.logger.Errorf("error computing c_hash: %v", err) + s.logger.ErrorContext(ctx, "error computing c_hash", "err", err) return "", expiry, fmt.Errorf("error computing c_hash: #{err}") } tok.CodeHash = cHash @@ -370,7 +423,7 @@ func (s *Server) newIDToken(clientID string, claims storage.Claims, scopes []str // initial auth request. continue } - isTrusted, err := s.validateCrossClientTrust(clientID, peerID) + isTrusted, err := s.validateCrossClientTrust(ctx, clientID, peerID) if err != nil { return "", expiry, err } @@ -378,21 +431,11 @@ func (s *Server) newIDToken(clientID string, claims storage.Claims, scopes []str // TODO(ericchiang): propagate this error to the client. return "", expiry, fmt.Errorf("peer (%s) does not trust client", peerID) } - tok.Audience = append(tok.Audience, peerID) } } - if len(tok.Audience) == 0 { - // Client didn't ask for cross client audience. Set the current - // client as the audience. - tok.Audience = audience{clientID} - } else { - // Client asked for cross client audience: - // if the current client was not requested explicitly - if !tok.Audience.contains(clientID) { - // by default it becomes one of entries in Audience - tok.Audience = append(tok.Audience, clientID) - } + tok.Audience = getAudience(clientID, scopes) + if len(tok.Audience) > 1 { // The current client becomes the authorizing party. tok.AuthorizingParty = clientID } @@ -410,6 +453,7 @@ func (s *Server) newIDToken(clientID string, claims storage.Claims, scopes []str // parse the initial request from the OAuth2 client. func (s *Server) parseAuthorizationRequest(r *http.Request) (*storage.AuthRequest, error) { + ctx := r.Context() if err := r.ParseForm(); err != nil { return nil, newDisplayedErr(http.StatusBadRequest, "Failed to parse request.") } @@ -434,12 +478,12 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (*storage.AuthReques codeChallengeMethod = codeChallengeMethodPlain } - client, err := s.storage.GetClient(clientID) + client, err := s.storage.GetClient(ctx, clientID) if err != nil { if err == storage.ErrNotFound { return nil, newDisplayedErr(http.StatusNotFound, "Invalid client_id (%q).", clientID) } - s.logger.Errorf("Failed to get client: %v", err) + s.logger.ErrorContext(r.Context(), "failed to get client", "err", err) return nil, newDisplayedErr(http.StatusInternalServerError, "Database error.") } @@ -456,9 +500,9 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (*storage.AuthReques } if connectorID != "" { - connectors, err := s.storage.ListConnectors() + connectors, err := s.storage.ListConnectors(ctx) if err != nil { - s.logger.Errorf("Failed to list connectors: %v", err) + s.logger.ErrorContext(r.Context(), "failed to list connectors", "err", err) return nil, newRedirectedErr(errServerError, "Unable to retrieve connectors") } if !validateConnectorID(connectors, connectorID) { @@ -494,7 +538,7 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (*storage.AuthReques continue } - isTrusted, err := s.validateCrossClientTrust(clientID, peerID) + isTrusted, err := s.validateCrossClientTrust(r.Context(), clientID, peerID) if err != nil { return nil, newRedirectedErr(errServerError, "Internal server error.") } @@ -576,6 +620,7 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (*storage.AuthReques CodeChallenge: codeChallenge, CodeChallengeMethod: codeChallengeMethod, }, + HMACKey: storage.NewHMACKey(crypto.SHA256), }, nil } @@ -586,14 +631,14 @@ func parseCrossClientScope(scope string) (peerID string, ok bool) { return } -func (s *Server) validateCrossClientTrust(clientID, peerID string) (trusted bool, err error) { +func (s *Server) validateCrossClientTrust(ctx context.Context, clientID, peerID string) (trusted bool, err error) { if peerID == clientID { return true, nil } - peer, err := s.storage.GetClient(peerID) + peer, err := s.storage.GetClient(ctx, peerID) if err != nil { if err != storage.ErrNotFound { - s.logger.Errorf("Failed to get client: %v", err) + s.logger.ErrorContext(ctx, "failed to get client", "err", err) return false, err } return false, nil @@ -624,7 +669,8 @@ func validateRedirectURI(client storage.Client, redirectURI string) bool { return true } - // verify that the host is of form "http://localhost:(port)(path)" or "http://localhost(path)" + // verify that the host is of form "http://localhost:(port)(path)", "http://localhost(path)" or numeric form like + // "http://127.0.0.1:(port)(path)" u, err := url.Parse(redirectURI) if err != nil { return false @@ -632,11 +678,20 @@ func validateRedirectURI(client storage.Client, redirectURI string) bool { if u.Scheme != "http" { return false } - if u.Host == "localhost" { + return isHostLocal(u.Host) +} + +func isHostLocal(host string) bool { + if host == "localhost" || net.ParseIP(host).IsLoopback() { return true } - host, _, err := net.SplitHostPort(u.Host) - return err == nil && host == "localhost" + + host, _, err := net.SplitHostPort(host) + if err != nil { + return false + } + + return host == "localhost" || net.ParseIP(host).IsLoopback() } func validateConnectorID(connectors []storage.Connector, connectorID string) bool { @@ -653,8 +708,8 @@ type storageKeySet struct { storage.Storage } -func (s *storageKeySet) VerifySignature(_ context.Context, jwt string) (payload []byte, err error) { - jws, err := jose.ParseSigned(jwt) +func (s *storageKeySet) VerifySignature(ctx context.Context, jwt string) (payload []byte, err error) { + jws, err := jose.ParseSigned(jwt, []jose.SignatureAlgorithm{jose.RS256, jose.RS384, jose.RS512, jose.ES256, jose.ES384, jose.ES512}) if err != nil { return nil, err } @@ -665,7 +720,7 @@ func (s *storageKeySet) VerifySignature(_ context.Context, jwt string) (payload break } - skeys, err := s.Storage.GetKeys() + skeys, err := s.Storage.GetKeys(ctx) if err != nil { return nil, err } diff --git a/server/oauth2_test.go b/server/oauth2_test.go index 710382aa23..3dff30d636 100644 --- a/server/oauth2_test.go +++ b/server/oauth2_test.go @@ -1,7 +1,6 @@ package server import ( - "context" "crypto/rand" "crypto/rsa" "net/http" @@ -10,12 +9,44 @@ import ( "strings" "testing" - "gopkg.in/square/go-jose.v2" + "github.com/go-jose/go-jose/v4" + "github.com/stretchr/testify/require" "github.com/dexidp/dex/storage" "github.com/dexidp/dex/storage/memory" ) +func TestGetClientID(t *testing.T) { + cid, err := getClientID(audience{}, "") + require.Equal(t, "", cid) + require.Equal(t, "no audience is set, could not find ClientID", err.Error()) + + cid, err = getClientID(audience{"a"}, "") + require.Equal(t, "a", cid) + require.NoError(t, err) + + cid, err = getClientID(audience{"a", "b"}, "azp") + require.Equal(t, "azp", cid) + require.NoError(t, err) +} + +func TestGetAudience(t *testing.T) { + aud := getAudience("client-id", []string{}) + require.Equal(t, aud, audience{"client-id"}) + + aud = getAudience("client-id", []string{"ascope"}) + require.Equal(t, aud, audience{"client-id"}) + + aud = getAudience("client-id", []string{"ascope", "audience:server:client_id:aa", "audience:server:client_id:bb"}) + require.Equal(t, aud, audience{"aa", "bb", "client-id"}) +} + +func TestGetSubject(t *testing.T) { + sub, err := genSubject("foo", "bar") + require.Equal(t, "CgNmb28SA2Jhcg", sub) + require.NoError(t, err) +} + func TestParseAuthorizationRequest(t *testing.T) { tests := []struct { name string @@ -290,11 +321,8 @@ func TestParseAuthorizationRequest(t *testing.T) { } for _, tc := range tests { - func() { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - httpServer, server := newTestServerMultipleConnectors(ctx, t, func(c *Config) { + t.Run(tc.name, func(t *testing.T) { + httpServer, server := newTestServerMultipleConnectors(t, func(c *Config) { c.SupportedResponseTypes = tc.supportedResponseTypes c.Storage = storage.WithStaticClients(c.Storage, tc.clients) }) @@ -343,7 +371,7 @@ func TestParseAuthorizationRequest(t *testing.T) { t.Fatalf("%s: unsupported error type", tc.name) } } - }() + }) } } @@ -420,6 +448,27 @@ func TestValidRedirectURI(t *testing.T) { redirectURI: "http://localhost", wantValid: true, }, + { + client: storage.Client{ + Public: true, + }, + redirectURI: "http://127.0.0.1:8080/", + wantValid: true, + }, + { + client: storage.Client{ + Public: true, + }, + redirectURI: "http://127.0.0.1:991/bar", + wantValid: true, + }, + { + client: storage.Client{ + Public: true, + }, + redirectURI: "http://127.0.0.1", + wantValid: true, + }, // Both Public + RedirectURIs configured: Could e.g. be a PKCE-enabled web app. { client: storage.Client{ @@ -545,8 +594,9 @@ func TestValidRedirectURI(t *testing.T) { } func TestStorageKeySet(t *testing.T) { + logger := newLogger(t) s := memory.New(logger) - if err := s.UpdateKeys(func(keys storage.Keys) (storage.Keys, error) { + if err := s.UpdateKeys(t.Context(), func(keys storage.Keys) (storage.Keys, error) { keys.SigningKey = &jose.JSONWebKey{ Key: testKey, KeyID: "testkey", @@ -620,7 +670,7 @@ func TestStorageKeySet(t *testing.T) { keySet := &storageKeySet{s} - _, err = keySet.VerifySignature(context.Background(), jwt) + _, err = keySet.VerifySignature(t.Context(), jwt) if (err != nil && !tc.wantErr) || (err == nil && tc.wantErr) { t.Fatalf("wantErr = %v, but got err = %v", tc.wantErr, err) } diff --git a/server/refreshhandlers.go b/server/refreshhandlers.go index 0c9b1393d3..de8d9b7b8d 100644 --- a/server/refreshhandlers.go +++ b/server/refreshhandlers.go @@ -28,6 +28,10 @@ type refreshError struct { desc string } +func (r *refreshError) Error() string { + return fmt.Sprintf("refresh token error: status %d, %q %s", r.code, r.msg, r.desc) +} + func newInternalServerError() *refreshError { return &refreshError{msg: errInvalidRequest, desc: "", code: http.StatusInternalServerError} } @@ -36,6 +40,11 @@ func newBadRequestError(desc string) *refreshError { return &refreshError{msg: errInvalidRequest, desc: desc, code: http.StatusBadRequest} } +var ( + invalidErr = newBadRequestError("Refresh token is invalid or has already been claimed by another client.") + expiredErr = newBadRequestError("Refresh token expired.") +) + func (s *Server) refreshTokenErrHelper(w http.ResponseWriter, err *refreshError) { s.tokenErrHelper(w, err.msg, err.desc, err.code) } @@ -60,21 +69,33 @@ func (s *Server) extractRefreshTokenFromRequest(r *http.Request) (*internal.Refr return token, nil } +type refreshContext struct { + storageToken *storage.RefreshToken + requestToken *internal.RefreshToken + + connector Connector + connectorData []byte + + scopes []string +} + // getRefreshTokenFromStorage checks that refresh token is valid and exists in the storage and gets its info -func (s *Server) getRefreshTokenFromStorage(clientID string, token *internal.RefreshToken) (*storage.RefreshToken, *refreshError) { - invalidErr := newBadRequestError("Refresh token is invalid or has already been claimed by another client.") +func (s *Server) getRefreshTokenFromStorage(ctx context.Context, clientID *string, token *internal.RefreshToken) (*refreshContext, *refreshError) { + refreshCtx := refreshContext{requestToken: token} - refresh, err := s.storage.GetRefresh(token.RefreshId) + // Get RefreshToken + refresh, err := s.storage.GetRefresh(ctx, token.RefreshId) if err != nil { if err != storage.ErrNotFound { - s.logger.Errorf("failed to get refresh token: %v", err) + s.logger.ErrorContext(ctx, "failed to get refresh token", "err", err) return nil, newInternalServerError() } return nil, invalidErr } - if refresh.ClientID != clientID { - s.logger.Errorf("client %s trying to claim token for client %s", clientID, refresh.ClientID) + // Only check ClientID if it was provided; + if clientID != nil && (refresh.ClientID != *clientID) { + s.logger.ErrorContext(ctx, "trying to claim token for different client", "client_id", clientID, "refresh_client_id", refresh.ClientID) // According to https://datatracker.ietf.org/doc/html/rfc6749#section-5.2 Dex should respond with an // invalid grant error if token has already been claimed by another client. return nil, &refreshError{msg: errInvalidGrant, desc: invalidErr.desc, code: http.StatusBadRequest} @@ -87,23 +108,46 @@ func (s *Server) getRefreshTokenFromStorage(clientID string, token *internal.Ref case refresh.ObsoleteToken != token.Token: fallthrough case refresh.ObsoleteToken == "": - s.logger.Errorf("refresh token with id %s claimed twice", refresh.ID) + s.logger.ErrorContext(ctx, "refresh token claimed twice", "token_id", refresh.ID) return nil, invalidErr } } - expiredErr := newBadRequestError("Refresh token expired.") if s.refreshTokenPolicy.CompletelyExpired(refresh.CreatedAt) { - s.logger.Errorf("refresh token with id %s expired", refresh.ID) + s.logger.ErrorContext(ctx, "refresh token expired", "token_id", refresh.ID) return nil, expiredErr } if s.refreshTokenPolicy.ExpiredBecauseUnused(refresh.LastUsed) { - s.logger.Errorf("refresh token with id %s expired due to inactivity", refresh.ID) + s.logger.ErrorContext(ctx, "refresh token expired due to inactivity", "token_id", refresh.ID) return nil, expiredErr } - return &refresh, nil + refreshCtx.storageToken = &refresh + + // Get Connector + refreshCtx.connector, err = s.getConnector(ctx, refresh.ConnectorID) + if err != nil { + s.logger.ErrorContext(ctx, "connector not found", "connector_id", refresh.ConnectorID, "err", err) + return nil, newInternalServerError() + } + + // Get Connector Data + session, err := s.storage.GetOfflineSessions(ctx, refresh.Claims.UserID, refresh.ConnectorID) + switch { + case err != nil: + if err != storage.ErrNotFound { + s.logger.ErrorContext(ctx, "failed to get offline session", "err", err) + return nil, newInternalServerError() + } + case len(refresh.ConnectorData) > 0: + // Use the old connector data if it exists, should be deleted once used + refreshCtx.connectorData = refresh.ConnectorData + default: + refreshCtx.connectorData = session.ConnectorData + } + + return &refreshCtx, nil } func (s *Server) getRefreshScopes(r *http.Request, refresh *storage.RefreshToken) ([]string, *refreshError) { @@ -138,78 +182,50 @@ func (s *Server) getRefreshScopes(r *http.Request, refresh *storage.RefreshToken return requestedScopes, nil } -func (s *Server) refreshWithConnector(ctx context.Context, token *internal.RefreshToken, refresh *storage.RefreshToken, scopes []string) (connector.Identity, *refreshError) { - var connectorData []byte - - session, err := s.storage.GetOfflineSessions(refresh.Claims.UserID, refresh.ConnectorID) - switch { - case err != nil: - if err != storage.ErrNotFound { - s.logger.Errorf("failed to get offline session: %v", err) - return connector.Identity{}, newInternalServerError() - } - case len(refresh.ConnectorData) > 0: - // Use the old connector data if it exists, should be deleted once used - connectorData = refresh.ConnectorData - default: - connectorData = session.ConnectorData - } - - conn, err := s.getConnector(refresh.ConnectorID) - if err != nil { - s.logger.Errorf("connector with ID %q not found: %v", refresh.ConnectorID, err) - return connector.Identity{}, newInternalServerError() - } - - ident := connector.Identity{ - UserID: refresh.Claims.UserID, - Username: refresh.Claims.Username, - PreferredUsername: refresh.Claims.PreferredUsername, - Email: refresh.Claims.Email, - EmailVerified: refresh.Claims.EmailVerified, - Groups: refresh.Claims.Groups, - ConnectorData: connectorData, - } - - // user's token was previously updated by a connector and is allowed to reuse - // it is excessive to refresh identity in upstream - if s.refreshTokenPolicy.AllowedToReuse(refresh.LastUsed) && token.Token == refresh.ObsoleteToken { - return ident, nil - } - +func (s *Server) refreshWithConnector(ctx context.Context, rCtx *refreshContext, ident connector.Identity) (connector.Identity, *refreshError) { // Can the connector refresh the identity? If so, attempt to refresh the data // in the connector. // // TODO(ericchiang): We may want a strict mode where connectors that don't implement // this interface can't perform refreshing. - if refreshConn, ok := conn.Connector.(connector.RefreshConnector); ok { - newIdent, err := refreshConn.Refresh(ctx, parseScopes(scopes), ident) + if refreshConn, ok := rCtx.connector.Connector.(connector.RefreshConnector); ok { + // Set connector data to the one received from an offline session + ident.ConnectorData = rCtx.connectorData + s.logger.Debug("connector data before refresh", "connector_data", ident.ConnectorData) + + newIdent, err := refreshConn.Refresh(ctx, parseScopes(rCtx.scopes), ident) if err != nil { - s.logger.Errorf("failed to refresh identity: %v", err) - return connector.Identity{}, newInternalServerError() + s.logger.ErrorContext(ctx, "failed to refresh identity", "err", err) + return ident, newInternalServerError() } - ident = newIdent - } + return newIdent, nil + } return ident, nil } // updateOfflineSession updates offline session in the storage -func (s *Server) updateOfflineSession(refresh *storage.RefreshToken, ident connector.Identity, lastUsed time.Time) *refreshError { +func (s *Server) updateOfflineSession(ctx context.Context, refresh *storage.RefreshToken, ident connector.Identity, lastUsed time.Time) *refreshError { offlineSessionUpdater := func(old storage.OfflineSessions) (storage.OfflineSessions, error) { if old.Refresh[refresh.ClientID].ID != refresh.ID { return old, errors.New("refresh token invalid") } + old.Refresh[refresh.ClientID].LastUsed = lastUsed - old.ConnectorData = ident.ConnectorData + if len(ident.ConnectorData) > 0 { + old.ConnectorData = ident.ConnectorData + } + + s.logger.DebugContext(ctx, "saved connector data", "user_id", ident.UserID, "connector_data", ident.ConnectorData) + return old, nil } // Update LastUsed time stamp in refresh token reference object // in offline session for the user. - err := s.storage.UpdateOfflineSessions(refresh.Claims.UserID, refresh.ConnectorID, offlineSessionUpdater) + err := s.storage.UpdateOfflineSessions(ctx, refresh.Claims.UserID, refresh.ConnectorID, offlineSessionUpdater) if err != nil { - s.logger.Errorf("failed to update offline session: %v", err) + s.logger.ErrorContext(ctx, "failed to update offline session", "err", err) return newInternalServerError() } @@ -217,33 +233,74 @@ func (s *Server) updateOfflineSession(refresh *storage.RefreshToken, ident conne } // updateRefreshToken updates refresh token and offline session in the storage -func (s *Server) updateRefreshToken(token *internal.RefreshToken, refresh *storage.RefreshToken, ident connector.Identity) (*internal.RefreshToken, *refreshError) { - newToken := token - if s.refreshTokenPolicy.RotationEnabled() { - newToken = &internal.RefreshToken{ - RefreshId: refresh.ID, - Token: storage.NewID(), - } +func (s *Server) updateRefreshToken(ctx context.Context, rCtx *refreshContext) (*internal.RefreshToken, connector.Identity, *refreshError) { + var rerr *refreshError + + newToken := &internal.RefreshToken{ + Token: rCtx.requestToken.Token, + RefreshId: rCtx.requestToken.RefreshId, } lastUsed := s.now() + ident := connector.Identity{ + UserID: rCtx.storageToken.Claims.UserID, + Username: rCtx.storageToken.Claims.Username, + PreferredUsername: rCtx.storageToken.Claims.PreferredUsername, + Email: rCtx.storageToken.Claims.Email, + EmailVerified: rCtx.storageToken.Claims.EmailVerified, + Groups: rCtx.storageToken.Claims.Groups, + } + refreshTokenUpdater := func(old storage.RefreshToken) (storage.RefreshToken, error) { - if s.refreshTokenPolicy.RotationEnabled() { - if old.Token != token.Token { - if s.refreshTokenPolicy.AllowedToReuse(old.LastUsed) && old.ObsoleteToken == token.Token { - newToken.Token = old.Token - // Do not update last used time for offline session if token is allowed to be reused - lastUsed = old.LastUsed - return old, nil - } + rotationEnabled := s.refreshTokenPolicy.RotationEnabled() + reusingAllowed := s.refreshTokenPolicy.AllowedToReuse(old.LastUsed) + + switch { + case !rotationEnabled && reusingAllowed: + // If rotation is disabled and the offline session was updated not so long ago - skip further actions. + old.ConnectorData = nil + return old, nil + + case rotationEnabled && reusingAllowed: + if old.Token != rCtx.requestToken.Token && old.ObsoleteToken != rCtx.requestToken.Token { return old, errors.New("refresh token claimed twice") } + // Return previously generated token for all requests with an obsolete tokens + if old.ObsoleteToken == rCtx.requestToken.Token { + newToken.Token = old.Token + } + + // Do not update last used time for offline session if token is allowed to be reused + lastUsed = old.LastUsed + old.ConnectorData = nil + return old, nil + + case rotationEnabled && !reusingAllowed: + if old.Token != rCtx.requestToken.Token { + return old, errors.New("refresh token claimed twice") + } + + // Issue new refresh token old.ObsoleteToken = old.Token + newToken.Token = storage.NewID() } old.Token = newToken.Token + old.LastUsed = lastUsed + + // ConnectorData has been moved to OfflineSession + old.ConnectorData = nil + + // Call only once if there is a request which is not in the reuse interval. + // This is required to avoid multiple calls to the external IdP for concurrent requests. + // Dex will call the connector's Refresh method only once if request is not in reuse interval. + ident, rerr = s.refreshWithConnector(ctx, rCtx, ident) + if rerr != nil { + return old, rerr + } + // Update the claims of the refresh token. // // UserID intentionally ignored for now. @@ -252,26 +309,23 @@ func (s *Server) updateRefreshToken(token *internal.RefreshToken, refresh *stora old.Claims.Email = ident.Email old.Claims.EmailVerified = ident.EmailVerified old.Claims.Groups = ident.Groups - old.LastUsed = lastUsed - // ConnectorData has been moved to OfflineSession - old.ConnectorData = []byte{} return old, nil } // Update refresh token in the storage. - err := s.storage.UpdateRefreshToken(refresh.ID, refreshTokenUpdater) + err := s.storage.UpdateRefreshToken(ctx, rCtx.storageToken.ID, refreshTokenUpdater) if err != nil { - s.logger.Errorf("failed to update refresh token: %v", err) - return nil, newInternalServerError() + s.logger.ErrorContext(ctx, "failed to update refresh token", "err", err) + return nil, ident, newInternalServerError() } - rerr := s.updateOfflineSession(refresh, ident, lastUsed) + rerr = s.updateOfflineSession(ctx, rCtx.storageToken, ident, lastUsed) if rerr != nil { - return nil, rerr + return nil, ident, rerr } - return newToken, nil + return newToken, ident, nil } // handleRefreshToken handles a refresh token request https://tools.ietf.org/html/rfc6749#section-6 @@ -283,19 +337,19 @@ func (s *Server) handleRefreshToken(w http.ResponseWriter, r *http.Request, clie return } - refresh, rerr := s.getRefreshTokenFromStorage(client.ID, token) + rCtx, rerr := s.getRefreshTokenFromStorage(r.Context(), &client.ID, token) if rerr != nil { s.refreshTokenErrHelper(w, rerr) return } - scopes, rerr := s.getRefreshScopes(r, refresh) + rCtx.scopes, rerr = s.getRefreshScopes(r, rCtx.storageToken) if rerr != nil { s.refreshTokenErrHelper(w, rerr) return } - ident, rerr := s.refreshWithConnector(r.Context(), token, refresh, scopes) + newToken, ident, rerr := s.updateRefreshToken(r.Context(), rCtx) if rerr != nil { s.refreshTokenErrHelper(w, rerr) return @@ -310,29 +364,23 @@ func (s *Server) handleRefreshToken(w http.ResponseWriter, r *http.Request, clie Groups: ident.Groups, } - accessToken, err := s.newAccessToken(client.ID, claims, scopes, refresh.Nonce, refresh.ConnectorID) + accessToken, _, err := s.newAccessToken(r.Context(), client.ID, claims, rCtx.scopes, rCtx.storageToken.Nonce, rCtx.storageToken.ConnectorID) if err != nil { - s.logger.Errorf("failed to create new access token: %v", err) + s.logger.ErrorContext(r.Context(), "failed to create new access token", "err", err) s.refreshTokenErrHelper(w, newInternalServerError()) return } - idToken, expiry, err := s.newIDToken(client.ID, claims, scopes, refresh.Nonce, accessToken, "", refresh.ConnectorID) + idToken, expiry, err := s.newIDToken(r.Context(), client.ID, claims, rCtx.scopes, rCtx.storageToken.Nonce, accessToken, "", rCtx.storageToken.ConnectorID) if err != nil { - s.logger.Errorf("failed to create ID token: %v", err) + s.logger.ErrorContext(r.Context(), "failed to create ID token", "err", err) s.refreshTokenErrHelper(w, newInternalServerError()) return } - newToken, rerr := s.updateRefreshToken(token, refresh, ident) - if rerr != nil { - s.refreshTokenErrHelper(w, rerr) - return - } - rawNewToken, err := internal.Marshal(newToken) if err != nil { - s.logger.Errorf("failed to marshal refresh token: %v", err) + s.logger.ErrorContext(r.Context(), "failed to marshal refresh token", "err", err) s.refreshTokenErrHelper(w, newInternalServerError()) return } diff --git a/server/refreshhandlers_test.go b/server/refreshhandlers_test.go index c64c50b330..f937769ca1 100644 --- a/server/refreshhandlers_test.go +++ b/server/refreshhandlers_test.go @@ -2,7 +2,6 @@ package server import ( "bytes" - "context" "encoding/json" "net/http" "net/http/httptest" @@ -18,6 +17,7 @@ import ( ) func mockRefreshTokenTestStorage(t *testing.T, s storage.Storage, useObsolete bool) { + ctx := t.Context() c := storage.Client{ ID: "test", Secret: "barfoo", @@ -26,7 +26,7 @@ func mockRefreshTokenTestStorage(t *testing.T, s storage.Storage, useObsolete bo LogoURL: "https://goo.gl/JIyzIC", } - err := s.CreateClient(c) + err := s.CreateClient(ctx, c) require.NoError(t, err) c1 := storage.Connector{ @@ -36,7 +36,7 @@ func mockRefreshTokenTestStorage(t *testing.T, s storage.Storage, useObsolete bo Config: nil, } - err = s.CreateConnector(c1) + err = s.CreateConnector(ctx, c1) require.NoError(t, err) refresh := storage.RefreshToken{ @@ -64,7 +64,7 @@ func mockRefreshTokenTestStorage(t *testing.T, s storage.Storage, useObsolete bo refresh.ObsoleteToken = "bar" } - err = s.CreateRefresh(refresh) + err = s.CreateRefresh(ctx, refresh) require.NoError(t, err) offlineSessions := storage.OfflineSessions{ @@ -74,7 +74,7 @@ func mockRefreshTokenTestStorage(t *testing.T, s storage.Storage, useObsolete bo ConnectorData: nil, } - err = s.CreateOfflineSessions(offlineSessions) + err = s.CreateOfflineSessions(ctx, offlineSessions) require.NoError(t, err) } @@ -152,11 +152,8 @@ func TestRefreshTokenExpirationScenarios(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(*testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - // Setup a dex server. - httpServer, s := newTestServer(ctx, t, func(c *Config) { + httpServer, s := newTestServer(t, func(c *Config) { c.RefreshTokenPolicy = tc.policy c.Now = func() time.Time { return t0 } }) diff --git a/server/rotation.go b/server/rotation.go index 98489767e0..286b4b57af 100644 --- a/server/rotation.go +++ b/server/rotation.go @@ -8,11 +8,11 @@ import ( "errors" "fmt" "io" + "log/slog" "time" - "gopkg.in/square/go-jose.v2" + "github.com/go-jose/go-jose/v4" - "github.com/dexidp/dex/pkg/log" "github.com/dexidp/dex/storage" ) @@ -61,7 +61,7 @@ type keyRotator struct { strategy rotationStrategy now func() time.Time - logger log.Logger + logger *slog.Logger } // startKeyRotation begins key rotation in a new goroutine, closing once the context is canceled. @@ -74,9 +74,9 @@ func (s *Server) startKeyRotation(ctx context.Context, strategy rotationStrategy // Try to rotate immediately so properly configured storages will have keys. if err := rotator.rotate(); err != nil { if err == errAlreadyRotated { - s.logger.Infof("Key rotation not needed: %v", err) + s.logger.Info("key rotation not needed", "err", err) } else { - s.logger.Errorf("failed to rotate keys: %v", err) + s.logger.Error("failed to rotate keys", "err", err) } } @@ -87,7 +87,7 @@ func (s *Server) startKeyRotation(ctx context.Context, strategy rotationStrategy return case <-time.After(time.Second * 30): if err := rotator.rotate(); err != nil { - s.logger.Errorf("failed to rotate keys: %v", err) + s.logger.Error("failed to rotate keys", "err", err) } } } @@ -95,14 +95,14 @@ func (s *Server) startKeyRotation(ctx context.Context, strategy rotationStrategy } func (k keyRotator) rotate() error { - keys, err := k.GetKeys() + keys, err := k.GetKeys(context.Background()) if err != nil && err != storage.ErrNotFound { return fmt.Errorf("get keys: %v", err) } if k.now().Before(keys.NextRotation) { return nil } - k.logger.Infof("keys expired, rotating") + k.logger.Info("keys expired, rotating") // Generate the key outside of a storage transaction. key, err := k.strategy.key() @@ -128,7 +128,7 @@ func (k keyRotator) rotate() error { } var nextRotation time.Time - err = k.Storage.UpdateKeys(func(keys storage.Keys) (storage.Keys, error) { + err = k.Storage.UpdateKeys(context.Background(), func(keys storage.Keys) (storage.Keys, error) { tNow := k.now() // if you are running multiple instances of dex, another instance @@ -174,7 +174,7 @@ func (k keyRotator) rotate() error { if err != nil { return err } - k.logger.Infof("keys rotated, next rotation: %s", nextRotation) + k.logger.Info("keys rotated", "next_rotation", nextRotation) return nil } @@ -187,10 +187,10 @@ type RefreshTokenPolicy struct { now func() time.Time - logger log.Logger + logger *slog.Logger } -func NewRefreshTokenPolicy(logger log.Logger, rotation bool, validIfNotUsedFor, absoluteLifetime, reuseInterval string) (*RefreshTokenPolicy, error) { +func NewRefreshTokenPolicy(logger *slog.Logger, rotation bool, validIfNotUsedFor, absoluteLifetime, reuseInterval string) (*RefreshTokenPolicy, error) { r := RefreshTokenPolicy{now: time.Now, logger: logger} var err error @@ -199,7 +199,7 @@ func NewRefreshTokenPolicy(logger log.Logger, rotation bool, validIfNotUsedFor, if err != nil { return nil, fmt.Errorf("invalid config value %q for refresh token valid if not used for: %v", validIfNotUsedFor, err) } - logger.Infof("config refresh tokens valid if not used for: %v", validIfNotUsedFor) + logger.Info("config refresh tokens", "valid_if_not_used_for", validIfNotUsedFor) } if absoluteLifetime != "" { @@ -207,7 +207,7 @@ func NewRefreshTokenPolicy(logger log.Logger, rotation bool, validIfNotUsedFor, if err != nil { return nil, fmt.Errorf("invalid config value %q for refresh tokens absolute lifetime: %v", absoluteLifetime, err) } - logger.Infof("config refresh tokens absolute lifetime: %v", absoluteLifetime) + logger.Info("config refresh tokens", "absolute_lifetime", absoluteLifetime) } if reuseInterval != "" { @@ -215,11 +215,11 @@ func NewRefreshTokenPolicy(logger log.Logger, rotation bool, validIfNotUsedFor, if err != nil { return nil, fmt.Errorf("invalid config value %q for refresh tokens reuse interval: %v", reuseInterval, err) } - logger.Infof("config refresh tokens reuse interval: %v", reuseInterval) + logger.Info("config refresh tokens", "reuse_interval", reuseInterval) } r.rotateRefreshTokens = !rotation - logger.Infof("config refresh tokens rotation enabled: %v", r.rotateRefreshTokens) + logger.Info("config refresh tokens rotation", "enabled", r.rotateRefreshTokens) return &r, nil } diff --git a/server/rotation_test.go b/server/rotation_test.go index e279bf543e..c7e6bada2f 100644 --- a/server/rotation_test.go +++ b/server/rotation_test.go @@ -1,12 +1,12 @@ package server import ( - "os" + "context" + "log/slog" "sort" "testing" "time" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" "github.com/dexidp/dex/storage" @@ -14,7 +14,7 @@ import ( ) func signingKeyID(t *testing.T, s storage.Storage) string { - keys, err := s.GetKeys() + keys, err := s.GetKeys(context.TODO()) if err != nil { t.Fatal(err) } @@ -22,7 +22,7 @@ func signingKeyID(t *testing.T, s storage.Storage) string { } func verificationKeyIDs(t *testing.T, s storage.Storage) (ids []string) { - keys, err := s.GetKeys() + keys, err := s.GetKeys(context.TODO()) if err != nil { t.Fatal(err) } @@ -68,11 +68,7 @@ func TestKeyRotator(t *testing.T) { // Only the last 5 verification keys are expected to be kept around. maxVerificationKeys := 5 - l := &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, - } + l := slog.New(slog.DiscardHandler) r := &keyRotator{ Storage: memory.New(l), @@ -104,11 +100,7 @@ func TestKeyRotator(t *testing.T) { func TestRefreshTokenPolicy(t *testing.T) { lastTime := time.Now() - l := &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, - } + l := slog.New(slog.DiscardHandler) r, err := NewRefreshTokenPolicy(l, true, "1m", "1m", "1m") require.NoError(t, err) diff --git a/server/server.go b/server/server.go old mode 100755 new mode 100644 index df16e655cf..70e8ae755f --- a/server/server.go +++ b/server/server.go @@ -7,22 +7,25 @@ import ( "errors" "fmt" "io/fs" + "log/slog" + "net" "net/http" + "net/netip" "net/url" "os" "path" "sort" - "strconv" "strings" "sync" "sync/atomic" "time" gosundheit "github.com/AppsFlyer/go-sundheit" - "github.com/felixge/httpsnoop" + "github.com/google/uuid" "github.com/gorilla/handlers" "github.com/gorilla/mux" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" "golang.org/x/crypto/bcrypt" "github.com/dexidp/dex/connector" @@ -42,7 +45,6 @@ import ( "github.com/dexidp/dex/connector/oidc" "github.com/dexidp/dex/connector/openshift" "github.com/dexidp/dex/connector/saml" - "github.com/dexidp/dex/pkg/log" "github.com/dexidp/dex/storage" "github.com/dexidp/dex/web" ) @@ -66,15 +68,27 @@ type Config struct { // The backing persistence layer. Storage storage.Storage + AllowedGrantTypes []string + // Valid values are "code" to enable the code flow and "token" to enable the implicit // flow. If no response types are supplied this value defaults to "code". SupportedResponseTypes []string + // Headers is a map of headers to be added to the all responses. + Headers http.Header + + // Header to extract real ip from. + RealIPHeader string + TrustedRealIPCIDRs []netip.Prefix + // List of allowed origins for CORS requests on discovery, token and keys endpoint. // If none are indicated, CORS requests are disabled. Passing in "*" will allow any // domain. AllowedOrigins []string + // List of allowed headers for CORS requests on discovery, token, and keys endpoint. + AllowedHeaders []string + // If enabled, the server won't prompt the user to approve authorization requests. // Logging in implies approval. SkipApprovalScreen bool @@ -100,11 +114,15 @@ type Config struct { Web WebConfig - Logger log.Logger + Logger *slog.Logger PrometheusRegistry *prometheus.Registry HealthChecker gosundheit.Health + + // If enabled, the server will continue starting even if some connectors fail to initialize. + // This allows the server to operate with a subset of connectors if some are misconfigured. + ContinueOnConnectorFailure bool } // WebConfig holds the server's frontend templates and asset configuration. @@ -118,7 +136,7 @@ type WebConfig struct { // * themes/(theme) - Static static served at "( issuer URL )/theme". Dir string - // Alternative way to programatically configure static web assets. + // Alternative way to programmatically configure static web assets. // If Dir is specified, WebFS is ignored. // It's expected to contain the same files and directories as mentioned above. // @@ -181,7 +199,7 @@ type Server struct { refreshTokenPolicy *RefreshTokenPolicy - logger log.Logger + logger *slog.Logger } // NewServer constructs a server from the provided config. @@ -212,18 +230,26 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy) if len(c.SupportedResponseTypes) == 0 { c.SupportedResponseTypes = []string{responseTypeCode} } + if len(c.AllowedHeaders) == 0 { + c.AllowedHeaders = []string{"Authorization"} + } - supportedGrant := []string{grantTypeAuthorizationCode, grantTypeRefreshToken, grantTypeDeviceCode} // default + allSupportedGrants := map[string]bool{ + grantTypeAuthorizationCode: true, + grantTypeRefreshToken: true, + grantTypeDeviceCode: true, + grantTypeTokenExchange: true, + } supportedRes := make(map[string]bool) for _, respType := range c.SupportedResponseTypes { switch respType { - case responseTypeCode, responseTypeIDToken: + case responseTypeCode, responseTypeIDToken, responseTypeCodeIDToken: // continue - case responseTypeToken: + case responseTypeToken, responseTypeCodeToken, responseTypeIDTokenToken, responseTypeCodeIDTokenToken: // response_type=token is an implicit flow, let's add it to the discovery info // https://datatracker.ietf.org/doc/html/rfc6749#section-4.2.1 - supportedGrant = append(supportedGrant, grantTypeImplicit) + allSupportedGrants[grantTypeImplicit] = true default: return nil, fmt.Errorf("unsupported response_type %q", respType) } @@ -231,10 +257,22 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy) } if c.PasswordConnector != "" { - supportedGrant = append(supportedGrant, grantTypePassword) + allSupportedGrants[grantTypePassword] = true } - sort.Strings(supportedGrant) + var supportedGrants []string + if len(c.AllowedGrantTypes) > 0 { + for _, grant := range c.AllowedGrantTypes { + if allSupportedGrants[grant] { + supportedGrants = append(supportedGrants, grant) + } + } + } else { + for grant := range allSupportedGrants { + supportedGrants = append(supportedGrants, grant) + } + } + sort.Strings(supportedGrants) webFS := web.FS() if c.Web.Dir != "" { @@ -252,7 +290,7 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy) extra: c.Web.Extra, } - static, theme, tmpls, err := loadWebConfig(web) + static, theme, robots, tmpls, err := loadWebConfig(web) if err != nil { return nil, fmt.Errorf("server: failed to load web static: %v", err) } @@ -267,7 +305,7 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy) connectors: make(map[string]Connector), storage: newKeyCacher(c.Storage, now), supportedResponseTypes: supportedRes, - supportedGrantTypes: supportedGrant, + supportedGrantTypes: supportedGrants, idTokensValidFor: value(c.IDTokensValidFor, 24*time.Hour), authRequestsValidFor: value(c.AuthRequestsValidFor, 24*time.Hour), deviceRequestsValidFor: value(c.DeviceRequestsValidFor, 5*time.Minute), @@ -282,7 +320,7 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy) // Retrieves connector objects in backend storage. This list includes the static connectors // defined in the ConfigMap and dynamic connectors retrieved from the storage. - storageConnectors, err := c.Storage.ListConnectors() + storageConnectors, err := c.Storage.ListConnectors(ctx) if err != nil { return nil, fmt.Errorf("server: failed to list connector objects from storage: %v", err) } @@ -291,13 +329,23 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy) return nil, errors.New("server: no connectors specified") } + var failedCount int for _, conn := range storageConnectors { if _, err := s.OpenConnector(conn); err != nil { + failedCount++ + if c.ContinueOnConnectorFailure { + s.logger.Error("server: Failed to open connector", "id", conn.ID, "err", err) + continue + } return nil, fmt.Errorf("server: Failed to open connector %s: %v", conn.ID, err) } } - instrumentHandlerCounter := func(_ string, handler http.Handler) http.HandlerFunc { + if c.ContinueOnConnectorFailure && failedCount == len(storageConnectors) { + return nil, fmt.Errorf("server: failed to open all connectors (%d/%d)", failedCount, len(storageConnectors)) + } + + instrumentHandler := func(_ string, handler http.Handler) http.HandlerFunc { return handler.ServeHTTP } @@ -305,24 +353,84 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy) requestCounter := prometheus.NewCounterVec(prometheus.CounterOpts{ Name: "http_requests_total", Help: "Count of all HTTP requests.", - }, []string{"handler", "code", "method"}) + }, []string{"code", "method", "handler"}) + + durationHist := prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Name: "request_duration_seconds", + Help: "A histogram of latencies for requests.", + Buckets: []float64{.25, .5, 1, 2.5, 5, 10}, + }, []string{"code", "method", "handler"}) + + sizeHist := prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Name: "response_size_bytes", + Help: "A histogram of response sizes for requests.", + Buckets: []float64{200, 500, 900, 1500}, + }, []string{"code", "method", "handler"}) + + c.PrometheusRegistry.MustRegister(requestCounter, durationHist, sizeHist) + + instrumentHandler = func(handlerName string, handler http.Handler) http.HandlerFunc { + return promhttp.InstrumentHandlerDuration(durationHist.MustCurryWith(prometheus.Labels{"handler": handlerName}), + promhttp.InstrumentHandlerCounter(requestCounter.MustCurryWith(prometheus.Labels{"handler": handlerName}), + promhttp.InstrumentHandlerResponseSize(sizeHist.MustCurryWith(prometheus.Labels{"handler": handlerName}), handler), + ), + ) + } + } - err = c.PrometheusRegistry.Register(requestCounter) + parseRealIP := func(r *http.Request) (string, error) { + remoteAddr, _, err := net.SplitHostPort(r.RemoteAddr) if err != nil { - return nil, fmt.Errorf("server: Failed to register Prometheus HTTP metrics: %v", err) + return "", err + } + + remoteIP, err := netip.ParseAddr(remoteAddr) + if err != nil { + return "", err + } + + for _, n := range c.TrustedRealIPCIDRs { + if !n.Contains(remoteIP) { + return remoteAddr, nil // Fallback to the address from the request if the header is provided + } } - instrumentHandlerCounter = func(handlerName string, handler http.Handler) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - m := httpsnoop.CaptureMetrics(handler, w, r) - requestCounter.With(prometheus.Labels{"handler": handlerName, "code": strconv.Itoa(m.Code), "method": r.Method}).Inc() + ipVal := r.Header.Get(c.RealIPHeader) + if ipVal != "" { + ip, err := netip.ParseAddr(ipVal) + if err == nil { + return ip.String(), nil } } + + return remoteAddr, nil + } + + handlerWithHeaders := func(handlerName string, handler http.Handler) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + for k, v := range c.Headers { + w.Header()[k] = v + } + + // Context values are used for logging purposes with the log/slog logger. + rCtx := r.Context() + rCtx = WithRequestID(rCtx) + + if c.RealIPHeader != "" { + realIP, err := parseRealIP(r) + if err == nil { + rCtx = WithRemoteIP(rCtx, realIP) + } + } + + r = r.WithContext(rCtx) + instrumentHandler(handlerName, handler)(w, r) + } } r := mux.NewRouter().SkipClean(true).UseEncodedPath() handle := func(p string, h http.Handler) { - r.Handle(path.Join(issuerURL.Path, p), instrumentHandlerCounter(p, h)) + r.Handle(path.Join(issuerURL.Path, p), handlerWithHeaders(p, h)) } handleFunc := func(p string, h http.HandlerFunc) { handle(p, h) @@ -334,16 +442,13 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy) handleWithCORS := func(p string, h http.HandlerFunc) { var handler http.Handler = h if len(c.AllowedOrigins) > 0 { - allowedHeaders := []string{ - "Authorization", - } cors := handlers.CORS( handlers.AllowedOrigins(c.AllowedOrigins), - handlers.AllowedHeaders(allowedHeaders), + handlers.AllowedHeaders(c.AllowedHeaders), ) handler = cors(handler) } - r.Handle(path.Join(issuerURL.Path, p), instrumentHandlerCounter(p, handler)) + r.Handle(path.Join(issuerURL.Path, p), handlerWithHeaders(p, handler)) } r.NotFoundHandler = http.NotFoundHandler() @@ -352,11 +457,26 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy) return nil, err } handleWithCORS("/.well-known/openid-configuration", discoveryHandler) + // Handle the root path for the better user experience. + handleWithCORS("/", func(w http.ResponseWriter, r *http.Request) { + _, err := fmt.Fprintf(w, ` + Dex +

Dex IdP

+

A Federated OpenID Connect Provider

+

Discovery

`, + s.issuerURL.JoinPath(".well-known", "openid-configuration").String()) + if err != nil { + s.logger.Error("failed to write response", "err", err) + s.renderError(r, w, http.StatusInternalServerError, "Handling the / path error.") + return + } + }) // TODO(ericchiang): rate limit certain paths based on IP. handleWithCORS("/token", s.handleToken) handleWithCORS("/keys", s.handlePublicKeys) handleWithCORS("/userinfo", s.handleUserInfo) + handleWithCORS("/token/introspect", s.handleIntrospect) handleFunc("/auth", s.handleAuthorization) handleFunc("/auth/{connector}", s.handleConnectorLogin) handleFunc("/auth/{connector}/login", s.handlePasswordLogin) @@ -366,7 +486,7 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy) // TODO(nabokihms): "/device/token" endpoint is deprecated, consider using /token endpoint instead handleFunc("/device/token", s.handleDeviceTokenDeprecated) handleFunc(deviceCallbackURI, s.handleDeviceCallback) - r.HandleFunc(path.Join(issuerURL.Path, "/callback"), func(w http.ResponseWriter, r *http.Request) { + handleFunc("/callback", func(w http.ResponseWriter, r *http.Request) { // Strip the X-Remote-* headers to prevent security issues on // misconfigured authproxy connector setups. for key := range r.Header { @@ -390,6 +510,8 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy) handlePrefix("/static", static) handlePrefix("/theme", theme) + handleFunc("/robots.txt", robots) + s.mux = r s.startKeyRotation(ctx, rotationStrategy, now) @@ -427,7 +549,7 @@ type passwordDB struct { } func (db passwordDB) Login(ctx context.Context, s connector.Scopes, email, password string) (connector.Identity, bool, error) { - p, err := db.s.GetPassword(email) + p, err := db.s.GetPassword(ctx, email) if err != nil { if err != storage.ErrNotFound { return connector.Identity{}, false, fmt.Errorf("get password: %v", err) @@ -452,7 +574,7 @@ func (db passwordDB) Login(ctx context.Context, s connector.Scopes, email, passw func (db passwordDB) Refresh(ctx context.Context, s connector.Scopes, identity connector.Identity) (connector.Identity, error) { // If the user has been deleted, the refresh token will be rejected. - p, err := db.s.GetPassword(identity.Email) + p, err := db.s.GetPassword(ctx, identity.Email) if err != nil { if err == storage.ErrNotFound { return connector.Identity{}, errors.New("user not found") @@ -494,13 +616,13 @@ type keyCacher struct { keys atomic.Value // Always holds nil or type *storage.Keys. } -func (k *keyCacher) GetKeys() (storage.Keys, error) { +func (k *keyCacher) GetKeys(ctx context.Context) (storage.Keys, error) { keys, ok := k.keys.Load().(*storage.Keys) if ok && keys != nil && k.now().Before(keys.NextRotation) { return *keys, nil } - storageKeys, err := k.Storage.GetKeys() + storageKeys, err := k.Storage.GetKeys(ctx) if err != nil { return storageKeys, err } @@ -518,11 +640,12 @@ func (s *Server) startGarbageCollection(ctx context.Context, frequency time.Dura case <-ctx.Done(): return case <-time.After(frequency): - if r, err := s.storage.GarbageCollect(now()); err != nil { - s.logger.Errorf("garbage collection failed: %v", err) + if r, err := s.storage.GarbageCollect(ctx, now()); err != nil { + s.logger.ErrorContext(ctx, "garbage collection failed", "err", err) } else if !r.IsEmpty() { - s.logger.Infof("garbage collection run, delete auth requests=%d, auth codes=%d, device requests=%d, device tokens=%d", - r.AuthRequests, r.AuthCodes, r.DeviceRequests, r.DeviceTokens) + s.logger.InfoContext(ctx, "garbage collection run, delete auth", + "requests", r.AuthRequests, "auth_codes", r.AuthCodes, + "device_requests", r.DeviceRequests, "device_tokens", r.DeviceTokens) } } } @@ -531,7 +654,7 @@ func (s *Server) startGarbageCollection(ctx context.Context, frequency time.Dura // ConnectorConfig is a configuration that can open a connector. type ConnectorConfig interface { - Open(id string, logger log.Logger) (connector.Connector, error) + Open(id string, logger *slog.Logger) (connector.Connector, error) } // ConnectorsConfig variable provides an easy way to return a config struct @@ -559,7 +682,7 @@ var ConnectorsConfig = map[string]func() ConnectorConfig{ } // openConnector will parse the connector config and open the connector. -func openConnector(logger log.Logger, conn storage.Connector) (connector.Connector, error) { +func openConnector(logger *slog.Logger, conn storage.Connector) (connector.Connector, error) { var c connector.Connector f, ok := ConnectorsConfig[conn.Type] @@ -610,8 +733,8 @@ func (s *Server) OpenConnector(conn storage.Connector) (Connector, error) { // getConnector retrieves the connector object with the given id from the storage // and updates the connector list for server if necessary. -func (s *Server) getConnector(id string) (Connector, error) { - storageConnector, err := s.storage.GetConnector(id) +func (s *Server) getConnector(ctx context.Context, id string) (Connector, error) { + storageConnector, err := s.storage.GetConnector(ctx, id) if err != nil { return Connector{}, fmt.Errorf("failed to get connector object from storage: %v", err) } @@ -634,3 +757,18 @@ func (s *Server) getConnector(id string) (Connector, error) { return conn, nil } + +type logRequestKey string + +const ( + RequestKeyRequestID logRequestKey = "request_id" + RequestKeyRemoteIP logRequestKey = "client_remote_addr" +) + +func WithRequestID(ctx context.Context) context.Context { + return context.WithValue(ctx, RequestKeyRequestID, uuid.NewString()) +} + +func WithRemoteIP(ctx context.Context, ip string) context.Context { + return context.WithValue(ctx, RequestKeyRemoteIP, ip) +} diff --git a/server/server_test.go b/server/server_test.go index 828e7faf95..a922aa751c 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -13,7 +13,6 @@ import ( "net/http/httptest" "net/http/httputil" "net/url" - "os" "path" "reflect" "sort" @@ -23,13 +22,12 @@ import ( gosundheit "github.com/AppsFlyer/go-sundheit" "github.com/coreos/go-oidc/v3/oidc" + "github.com/go-jose/go-jose/v4" "github.com/kylelemons/godebug/pretty" "github.com/prometheus/client_golang/prometheus" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" "golang.org/x/crypto/bcrypt" "golang.org/x/oauth2" - jose "gopkg.in/square/go-jose.v2" "github.com/dexidp/dex/connector" "github.com/dexidp/dex/connector/mock" @@ -77,18 +75,15 @@ FDWV28nTP9sqbtsmU8Tem2jzMvZ7C/Q0AuDoKELFUpux8shm8wfIhyaPnXUGZoAZ Np4vUwMSYV5mopESLWOg3loBxKyLGFtgGKVCjGiQvy6zISQ4fQo= -----END RSA PRIVATE KEY-----`) -var logger = &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, -} - -func newTestServer(ctx context.Context, t *testing.T, updateConfig func(c *Config)) (*httptest.Server, *Server) { +func newTestServer(t *testing.T, updateConfig func(c *Config)) (*httptest.Server, *Server) { var server *Server s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { server.ServeHTTP(w, r) })) + logger := newLogger(t) + ctx := t.Context() + config := Config{ Issuer: s.URL, Storage: memory.New(logger), @@ -98,6 +93,15 @@ func newTestServer(ctx context.Context, t *testing.T, updateConfig func(c *Confi Logger: logger, PrometheusRegistry: prometheus.NewRegistry(), HealthChecker: gosundheit.New(), + SkipApprovalScreen: true, // Don't prompt for approval, just immediately redirect with code. + AllowedGrantTypes: []string{ // all implemented types + grantTypeDeviceCode, + grantTypeAuthorizationCode, + grantTypeRefreshToken, + grantTypeTokenExchange, + grantTypeImplicit, + grantTypePassword, + }, } if updateConfig != nil { updateConfig(&config) @@ -110,7 +114,7 @@ func newTestServer(ctx context.Context, t *testing.T, updateConfig func(c *Confi Name: "Mock", ResourceVersion: "1", } - if err := config.Storage.CreateConnector(connector); err != nil { + if err := config.Storage.CreateConnector(ctx, connector); err != nil { t.Fatalf("create connector: %v", err) } @@ -118,7 +122,6 @@ func newTestServer(ctx context.Context, t *testing.T, updateConfig func(c *Confi if server, err = newServer(ctx, config, staticRotationStrategy(testKey)); err != nil { t.Fatal(err) } - server.skipApproval = true // Don't prompt for approval, just immediately redirect with code. // Default rotation policy if server.refreshTokenPolicy == nil { @@ -132,12 +135,15 @@ func newTestServer(ctx context.Context, t *testing.T, updateConfig func(c *Confi return s, server } -func newTestServerMultipleConnectors(ctx context.Context, t *testing.T, updateConfig func(c *Config)) (*httptest.Server, *Server) { +func newTestServerMultipleConnectors(t *testing.T, updateConfig func(c *Config)) (*httptest.Server, *Server) { var server *Server s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { server.ServeHTTP(w, r) })) + logger := newLogger(t) + ctx := t.Context() + config := Config{ Issuer: s.URL, Storage: memory.New(logger), @@ -164,10 +170,10 @@ func newTestServerMultipleConnectors(ctx context.Context, t *testing.T, updateCo Name: "Mock", ResourceVersion: "1", } - if err := config.Storage.CreateConnector(connector); err != nil { + if err := config.Storage.CreateConnector(ctx, connector); err != nil { t.Fatalf("create connector: %v", err) } - if err := config.Storage.CreateConnector(connector2); err != nil { + if err := config.Storage.CreateConnector(ctx, connector2); err != nil { t.Fatalf("create connector: %v", err) } @@ -180,21 +186,16 @@ func newTestServerMultipleConnectors(ctx context.Context, t *testing.T, updateCo } func TestNewTestServer(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - newTestServer(ctx, t, nil) + newTestServer(t, nil) } func TestDiscovery(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - httpServer, _ := newTestServer(ctx, t, func(c *Config) { + httpServer, _ := newTestServer(t, func(c *Config) { c.Issuer += "/non-root-path" }) defer httpServer.Close() - p, err := oidc.NewProvider(ctx, httpServer.URL) + p, err := oidc.NewProvider(t.Context(), httpServer.URL) if err != nil { t.Fatalf("failed to get provider: %v", err) } @@ -731,11 +732,10 @@ func TestOAuth2CodeFlow(t *testing.T) { tests := makeOAuth2Tests(clientID, clientSecret, now) for _, tc := range tests.tests { t.Run(tc.name, func(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() // Setup a dex server. - httpServer, s := newTestServer(ctx, t, func(c *Config) { + httpServer, s := newTestServer(t, func(c *Config) { c.Issuer += "/non-root-path" c.Now = now c.IDTokensValidFor = idTokensValidFor @@ -829,11 +829,11 @@ func TestOAuth2CodeFlow(t *testing.T) { Secret: clientSecret, RedirectURIs: []string{redirectURL}, } - if err := s.storage.CreateClient(client); err != nil { + if err := s.storage.CreateClient(ctx, client); err != nil { t.Fatalf("failed to create client: %v", err) } - if err := s.storage.CreateRefresh(storage.RefreshToken{ + if err := s.storage.CreateRefresh(ctx, storage.RefreshToken{ ID: "existedrefrestoken", ClientID: "unexcistedclientid", }); err != nil { @@ -871,15 +871,25 @@ func TestOAuth2CodeFlow(t *testing.T) { if respDump, err = httputil.DumpResponse(resp, true); err != nil { t.Fatal(err) } + + tokens, err := s.storage.ListRefreshTokens(ctx) + if err != nil { + t.Fatalf("failed to get existed refresh token: %v", err) + } + + for _, token := range tokens { + if /* token was updated */ token.ObsoleteToken != "" && token.ConnectorData != nil { + t.Fatalf("token connectorData with id %q field is not nil: %s", token.ID, token.ConnectorData) + } + } }) } } func TestOAuth2ImplicitFlow(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() - httpServer, s := newTestServer(ctx, t, func(c *Config) { + httpServer, s := newTestServer(t, func(c *Config) { // Enable support for the implicit flow. c.SupportedResponseTypes = []string{"code", "token", "id_token"} }) @@ -936,7 +946,7 @@ func TestOAuth2ImplicitFlow(t *testing.T) { Secret: "testclientsecret", RedirectURIs: []string{redirectURL}, } - if err := s.storage.CreateClient(client); err != nil { + if err := s.storage.CreateClient(ctx, client); err != nil { t.Fatalf("failed to create client: %v", err) } @@ -1012,10 +1022,9 @@ func TestOAuth2ImplicitFlow(t *testing.T) { } func TestCrossClientScopes(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() - httpServer, s := newTestServer(ctx, t, func(c *Config) { + httpServer, s := newTestServer(t, func(c *Config) { c.Issuer += "/non-root-path" }) defer httpServer.Close() @@ -1094,7 +1103,7 @@ func TestCrossClientScopes(t *testing.T) { Secret: "testclientsecret", RedirectURIs: []string{redirectURL}, } - if err := s.storage.CreateClient(client); err != nil { + if err := s.storage.CreateClient(ctx, client); err != nil { t.Fatalf("failed to create client: %v", err) } @@ -1104,7 +1113,7 @@ func TestCrossClientScopes(t *testing.T) { TrustedPeers: []string{"testclient"}, } - if err := s.storage.CreateClient(peer); err != nil { + if err := s.storage.CreateClient(ctx, peer); err != nil { t.Fatalf("failed to create client: %v", err) } @@ -1135,10 +1144,9 @@ func TestCrossClientScopes(t *testing.T) { } func TestCrossClientScopesWithAzpInAudienceByDefault(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() - httpServer, s := newTestServer(ctx, t, func(c *Config) { + httpServer, s := newTestServer(t, func(c *Config) { c.Issuer += "/non-root-path" }) defer httpServer.Close() @@ -1217,7 +1225,7 @@ func TestCrossClientScopesWithAzpInAudienceByDefault(t *testing.T) { Secret: "testclientsecret", RedirectURIs: []string{redirectURL}, } - if err := s.storage.CreateClient(client); err != nil { + if err := s.storage.CreateClient(ctx, client); err != nil { t.Fatalf("failed to create client: %v", err) } @@ -1227,7 +1235,7 @@ func TestCrossClientScopesWithAzpInAudienceByDefault(t *testing.T) { TrustedPeers: []string{"testclient"}, } - if err := s.storage.CreateClient(peer); err != nil { + if err := s.storage.CreateClient(ctx, peer); err != nil { t.Fatalf("failed to create client: %v", err) } @@ -1257,6 +1265,9 @@ func TestCrossClientScopesWithAzpInAudienceByDefault(t *testing.T) { } func TestPasswordDB(t *testing.T) { + ctx := t.Context() + + logger := newLogger(t) s := memory.New(logger) conn := newPasswordDB(s) @@ -1267,7 +1278,7 @@ func TestPasswordDB(t *testing.T) { t.Fatal(err) } - s.CreatePassword(storage.Password{ + s.CreatePassword(ctx, storage.Password{ Email: "jane@example.com", Username: "jane", UserID: "foobar", @@ -1308,7 +1319,7 @@ func TestPasswordDB(t *testing.T) { } for _, tc := range tests { - ident, valid, err := conn.Login(context.Background(), connector.Scopes{}, tc.username, tc.password) + ident, valid, err := conn.Login(t.Context(), connector.Scopes{}, tc.username, tc.password) if err != nil { if !tc.wantErr { t.Errorf("%s: %v", tc.name, err) @@ -1340,6 +1351,7 @@ func TestPasswordDB(t *testing.T) { } func TestPasswordDBUsernamePrompt(t *testing.T) { + logger := newLogger(t) s := memory.New(logger) conn := newPasswordDB(s) @@ -1354,15 +1366,16 @@ type storageWithKeysTrigger struct { f func() } -func (s storageWithKeysTrigger) GetKeys() (storage.Keys, error) { +func (s storageWithKeysTrigger) GetKeys(ctx context.Context) (storage.Keys, error) { s.f() - return s.Storage.GetKeys() + return s.Storage.GetKeys(ctx) } func TestKeyCacher(t *testing.T) { tNow := time.Now() now := func() time.Time { return tNow } - + ctx := t.Context() + logger := newLogger(t) s := memory.New(logger) tests := []struct { @@ -1375,7 +1388,7 @@ func TestKeyCacher(t *testing.T) { }, { before: func() { - s.UpdateKeys(func(old storage.Keys) (storage.Keys, error) { + s.UpdateKeys(ctx, func(old storage.Keys) (storage.Keys, error) { old.NextRotation = tNow.Add(time.Minute) return old, nil }) @@ -1395,7 +1408,7 @@ func TestKeyCacher(t *testing.T) { { before: func() { tNow = tNow.Add(time.Hour) - s.UpdateKeys(func(old storage.Keys) (storage.Keys, error) { + s.UpdateKeys(ctx, func(old storage.Keys) (storage.Keys, error) { old.NextRotation = tNow.Add(time.Minute) return old, nil }) @@ -1413,7 +1426,7 @@ func TestKeyCacher(t *testing.T) { for i, tc := range tests { gotCall = false tc.before() - s.GetKeys() + s.GetKeys(t.Context()) if gotCall != tc.wantCallToStorage { t.Errorf("case %d: expected call to storage=%t got call to storage=%t", i, tc.wantCallToStorage, gotCall) } @@ -1455,10 +1468,10 @@ type oauth2Client struct { func TestRefreshTokenFlow(t *testing.T) { state := "state" now := time.Now - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - httpServer, s := newTestServer(ctx, t, func(c *Config) { + ctx := t.Context() + + httpServer, s := newTestServer(t, func(c *Config) { c.Now = now }) defer httpServer.Close() @@ -1515,7 +1528,7 @@ func TestRefreshTokenFlow(t *testing.T) { Secret: "testclientsecret", RedirectURIs: []string{redirectURL}, } - if err := s.storage.CreateClient(client); err != nil { + if err := s.storage.CreateClient(ctx, client); err != nil { t.Fatalf("failed to create client: %v", err) } @@ -1589,11 +1602,10 @@ func TestOAuth2DeviceFlow(t *testing.T) { for _, testCase := range testCases { for _, tc := range testCase.oauth2Tests.tests { t.Run(tc.name, func(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + ctx := t.Context() // Setup a dex server. - httpServer, s := newTestServer(ctx, t, func(c *Config) { + httpServer, s := newTestServer(t, func(c *Config) { c.Issuer += "/non-root-path" c.Now = now c.IDTokensValidFor = idTokensValidFor @@ -1614,11 +1626,11 @@ func TestOAuth2DeviceFlow(t *testing.T) { RedirectURIs: []string{deviceCallbackURI}, Public: true, } - if err := s.storage.CreateClient(client); err != nil { + if err := s.storage.CreateClient(ctx, client); err != nil { t.Fatalf("failed to create client: %v", err) } - if err := s.storage.CreateRefresh(storage.RefreshToken{ + if err := s.storage.CreateRefresh(ctx, storage.RefreshToken{ ID: "existedrefrestoken", ClientID: "unexcistedclientid", }); err != nil { @@ -1745,17 +1757,22 @@ func TestServerSupportedGrants(t *testing.T) { { name: "Simple", config: func(c *Config) {}, - resGrants: []string{grantTypeAuthorizationCode, grantTypeRefreshToken, grantTypeDeviceCode}, + resGrants: []string{grantTypeAuthorizationCode, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange}, + }, + { + name: "Minimal", + config: func(c *Config) { c.AllowedGrantTypes = []string{grantTypeTokenExchange} }, + resGrants: []string{grantTypeTokenExchange}, }, { name: "With password connector", config: func(c *Config) { c.PasswordConnector = "local" }, - resGrants: []string{grantTypeAuthorizationCode, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode}, + resGrants: []string{grantTypeAuthorizationCode, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange}, }, { name: "With token response", config: func(c *Config) { c.SupportedResponseTypes = append(c.SupportedResponseTypes, responseTypeToken) }, - resGrants: []string{grantTypeAuthorizationCode, grantTypeImplicit, grantTypeRefreshToken, grantTypeDeviceCode}, + resGrants: []string{grantTypeAuthorizationCode, grantTypeImplicit, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange}, }, { name: "All", @@ -1763,14 +1780,238 @@ func TestServerSupportedGrants(t *testing.T) { c.PasswordConnector = "local" c.SupportedResponseTypes = append(c.SupportedResponseTypes, responseTypeToken) }, - resGrants: []string{grantTypeAuthorizationCode, grantTypeImplicit, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode}, + resGrants: []string{grantTypeAuthorizationCode, grantTypeImplicit, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeTokenExchange}, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - _, srv := newTestServer(context.TODO(), t, tc.config) - require.Equal(t, srv.supportedGrantTypes, tc.resGrants) + _, srv := newTestServer(t, tc.config) + require.Equal(t, tc.resGrants, srv.supportedGrantTypes) + }) + } +} + +func TestHeaders(t *testing.T) { + ctx := t.Context() + + httpServer, _ := newTestServer(t, func(c *Config) { + c.Headers = map[string][]string{ + "Strict-Transport-Security": {"max-age=31536000; includeSubDomains"}, + } + }) + defer httpServer.Close() + + p, err := oidc.NewProvider(ctx, httpServer.URL) + if err != nil { + t.Fatalf("failed to get provider: %v", err) + } + + resp, err := http.Get(p.Endpoint().TokenURL) + require.NoError(t, err) + + require.Equal(t, "max-age=31536000; includeSubDomains", resp.Header.Get("Strict-Transport-Security")) +} + +func TestConnectorFailureHandling(t *testing.T) { + ctx := t.Context() + + tests := []struct { + name string + connectors []storage.Connector + continueOnConnectorFailure bool + wantErr bool + wantErrContains string + expectConnectors []string // IDs of connectors that should be loaded successfully + }{ + { + name: "all connectors succeed with flag enabled", + connectors: []storage.Connector{ + { + ID: "mock1", + Type: "mockCallback", + Name: "Mock1", + }, + { + ID: "mock2", + Type: "mockCallback", + Name: "Mock2", + }, + }, + continueOnConnectorFailure: true, + wantErr: false, + expectConnectors: []string{"mock1", "mock2"}, + }, + { + name: "all connectors succeed with flag disabled", + connectors: []storage.Connector{ + { + ID: "mock1", + Type: "mockCallback", + Name: "Mock1", + }, + { + ID: "mock2", + Type: "mockCallback", + Name: "Mock2", + }, + }, + continueOnConnectorFailure: false, + wantErr: false, + expectConnectors: []string{"mock1", "mock2"}, + }, + { + name: "partial connector failure with flag enabled", + connectors: []storage.Connector{ + { + ID: "mock-good", + Type: "mockCallback", + Name: "Good Mock", + }, + { + ID: "bad-connector", + Type: "nonexistent", + Name: "Bad Connector", + }, + { + ID: "mock-good2", + Type: "mockCallback", + Name: "Good Mock 2", + }, + }, + continueOnConnectorFailure: true, + wantErr: false, + expectConnectors: []string{"mock-good", "mock-good2"}, + }, + { + name: "partial connector failure with flag disabled", + connectors: []storage.Connector{ + { + ID: "mock-good", + Type: "mockCallback", + Name: "Good Mock", + }, + { + ID: "bad-connector", + Type: "nonexistent", + Name: "Bad Connector", + }, + { + ID: "mock-good2", + Type: "mockCallback", + Name: "Good Mock 2", + }, + }, + continueOnConnectorFailure: false, + wantErr: true, + wantErrContains: "Failed to open connector bad-connector", + expectConnectors: []string{}, // Server creation should fail + }, + { + name: "all connectors fail with flag enabled", + connectors: []storage.Connector{ + { + ID: "bad1", + Type: "nonexistent1", + Name: "Bad 1", + }, + { + ID: "bad2", + Type: "nonexistent2", + Name: "Bad 2", + }, + }, + continueOnConnectorFailure: true, + wantErr: true, + wantErrContains: "failed to open all connectors (2/2)", + }, + { + name: "all connectors fail with flag disabled", + connectors: []storage.Connector{ + { + ID: "bad1", + Type: "nonexistent1", + Name: "Bad 1", + }, + { + ID: "bad2", + Type: "nonexistent2", + Name: "Bad 2", + }, + }, + continueOnConnectorFailure: false, + wantErr: true, + wantErrContains: "Failed to open connector", + }, + { + name: "no connectors", + connectors: []storage.Connector{}, + continueOnConnectorFailure: true, + wantErr: true, + wantErrContains: "no connectors specified", + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + logger := newLogger(t) + + config := Config{ + Issuer: "http://localhost", + Storage: memory.New(logger), + Web: WebConfig{ + Dir: "../web", + }, + Logger: logger, + PrometheusRegistry: prometheus.NewRegistry(), + HealthChecker: gosundheit.New(), + ContinueOnConnectorFailure: tc.continueOnConnectorFailure, + } + + // Create connectors in storage + for _, conn := range tc.connectors { + if err := config.Storage.CreateConnector(ctx, conn); err != nil { + t.Fatalf("failed to create connector: %v", err) + } + } + + server, err := newServer(ctx, config, staticRotationStrategy(testKey)) + + if tc.wantErr { + if err == nil { + t.Errorf("expected error but got none") + } else if tc.wantErrContains != "" && !strings.Contains(err.Error(), tc.wantErrContains) { + t.Errorf("expected error containing %q, got %q", tc.wantErrContains, err.Error()) + } + } else { + if err != nil { + t.Errorf("unexpected error: %v", err) + } else { + // Verify expected connectors are loaded + for _, id := range tc.expectConnectors { + if _, exists := server.connectors[id]; !exists { + t.Errorf("expected connector %q to be loaded", id) + } + } + + // Verify failed connectors are not loaded + for _, conn := range tc.connectors { + _, shouldExist := false, false + for _, expectedID := range tc.expectConnectors { + if conn.ID == expectedID { + shouldExist = true + break + } + } + _, exists := server.connectors[conn.ID] + if shouldExist && !exists { + t.Errorf("connector %q should have been loaded but wasn't", conn.ID) + } else if !shouldExist && exists { + t.Errorf("connector %q should not have been loaded but was", conn.ID) + } + } + } + } }) } } diff --git a/server/templates.go b/server/templates.go index 33f00fda36..b77663e1f5 100644 --- a/server/templates.go +++ b/server/templates.go @@ -83,13 +83,12 @@ func getFuncMap(c webConfig) (template.FuncMap, error) { // // The directory layout is expected to be: // -// ( web directory ) -// |- static -// |- themes -// | |- (theme name) -// |- templates -// -func loadWebConfig(c webConfig) (http.Handler, http.Handler, *templates, error) { +// ( web directory ) +// |- static +// |- themes +// | |- (theme name) +// |- templates +func loadWebConfig(c webConfig) (http.Handler, http.Handler, http.HandlerFunc, *templates, error) { // fallback to the default theme if the legacy theme name is provided if c.theme == "coreos" || c.theme == "tectonic" { c.theme = "" @@ -106,18 +105,24 @@ func loadWebConfig(c webConfig) (http.Handler, http.Handler, *templates, error) staticFiles, err := fs.Sub(c.webFS, "static") if err != nil { - return nil, nil, nil, fmt.Errorf("read static dir: %v", err) + return nil, nil, nil, nil, fmt.Errorf("read static dir: %v", err) } themeFiles, err := fs.Sub(c.webFS, path.Join("themes", c.theme)) if err != nil { - return nil, nil, nil, fmt.Errorf("read themes dir: %v", err) + return nil, nil, nil, nil, fmt.Errorf("read themes dir: %v", err) + } + robotsContent, err := fs.ReadFile(c.webFS, "robots.txt") + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("read robots.txt dir: %v", err) } static := http.FileServer(http.FS(staticFiles)) theme := http.FileServer(http.FS(themeFiles)) + robots := func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, string(robotsContent)) } templates, err := loadTemplates(c, "templates") - return static, theme, templates, err + + return static, theme, robots, templates, err } // loadTemplates parses the expected templates from the provided directory. @@ -287,6 +292,9 @@ func (t *templates) login(r *http.Request, w http.ResponseWriter, connectors []c } func (t *templates) password(r *http.Request, w http.ResponseWriter, postURL, lastUsername, usernamePrompt string, lastWasInvalid bool, backLink string) error { + if lastWasInvalid { + w.WriteHeader(http.StatusUnauthorized) + } data := struct { PostURL string BackLink string diff --git a/storage/conformance/conformance.go b/storage/conformance/conformance.go index 9d9766ebd5..f9d219619d 100644 --- a/storage/conformance/conformance.go +++ b/storage/conformance/conformance.go @@ -2,14 +2,16 @@ package conformance import ( + "context" "reflect" "sort" "testing" "time" + jose "github.com/go-jose/go-jose/v4" "github.com/kylelemons/godebug/pretty" + "github.com/stretchr/testify/require" "golang.org/x/crypto/bcrypt" - jose "gopkg.in/square/go-jose.v2" "github.com/dexidp/dex/storage" ) @@ -22,10 +24,10 @@ type subTest struct { run func(t *testing.T, s storage.Storage) } -func runTests(t *testing.T, newStorage func() storage.Storage, tests []subTest) { +func runTests(t *testing.T, newStorage func(t *testing.T) storage.Storage, tests []subTest) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - s := newStorage() + s := newStorage(t) test.run(t, s) s.Close() }) @@ -35,7 +37,7 @@ func runTests(t *testing.T, newStorage func() storage.Storage, tests []subTest) // RunTests runs a set of conformance tests against a storage. newStorage should // return an initialized but empty storage. The storage will be closed at the // end of each test run. -func RunTests(t *testing.T, newStorage func() storage.Storage) { +func RunTests(t *testing.T, newStorage func(t *testing.T) storage.Storage) { runTests(t, newStorage, []subTest{ {"AuthCodeCRUD", testAuthCodeCRUD}, {"AuthRequestCRUD", testAuthRequestCRUD}, @@ -63,7 +65,7 @@ func mustLoadJWK(b string) *jose.JSONWebKey { func mustBeErrNotFound(t *testing.T, kind string, err error) { switch { case err == nil: - t.Errorf("deleting non-existent %s should return an error", kind) + t.Errorf("deleting nonexistent %s should return an error", kind) case err != storage.ErrNotFound: t.Errorf("deleting %s expected storage.ErrNotFound, got %v", kind, err) } @@ -79,6 +81,7 @@ func mustBeErrAlreadyExists(t *testing.T, kind string, err error) { } func testAuthRequestCRUD(t *testing.T, s storage.Storage) { + ctx := t.Context() codeChallenge := storage.PKCE{ CodeChallenge: "code_challenge_test", CodeChallengeMethod: "plain", @@ -104,17 +107,18 @@ func testAuthRequestCRUD(t *testing.T, s storage.Storage) { EmailVerified: true, Groups: []string{"a", "b"}, }, - PKCE: codeChallenge, + PKCE: codeChallenge, + HMACKey: []byte("hmac_key"), } identity := storage.Claims{Email: "foobar"} - if err := s.CreateAuthRequest(a1); err != nil { + if err := s.CreateAuthRequest(ctx, a1); err != nil { t.Fatalf("failed creating auth request: %v", err) } // Attempt to create same AuthRequest twice. - err := s.CreateAuthRequest(a1) + err := s.CreateAuthRequest(ctx, a1) mustBeErrAlreadyExists(t, "auth request", err) a2 := storage.AuthRequest{ @@ -137,13 +141,14 @@ func testAuthRequestCRUD(t *testing.T, s storage.Storage) { EmailVerified: true, Groups: []string{"a"}, }, + HMACKey: []byte("hmac_key"), } - if err := s.CreateAuthRequest(a2); err != nil { + if err := s.CreateAuthRequest(ctx, a2); err != nil { t.Fatalf("failed creating auth request: %v", err) } - if err := s.UpdateAuthRequest(a1.ID, func(old storage.AuthRequest) (storage.AuthRequest, error) { + if err := s.UpdateAuthRequest(ctx, a1.ID, func(old storage.AuthRequest) (storage.AuthRequest, error) { old.Claims = identity old.ConnectorID = "connID" return old, nil @@ -151,7 +156,7 @@ func testAuthRequestCRUD(t *testing.T, s storage.Storage) { t.Fatalf("failed to update auth request: %v", err) } - got, err := s.GetAuthRequest(a1.ID) + got, err := s.GetAuthRequest(ctx, a1.ID) if err != nil { t.Fatalf("failed to get auth req: %v", err) } @@ -163,19 +168,20 @@ func testAuthRequestCRUD(t *testing.T, s storage.Storage) { t.Fatalf("storage does not support PKCE, wanted challenge=%#v got %#v", codeChallenge, got.PKCE) } - if err := s.DeleteAuthRequest(a1.ID); err != nil { + if err := s.DeleteAuthRequest(ctx, a1.ID); err != nil { t.Fatalf("failed to delete auth request: %v", err) } - if err := s.DeleteAuthRequest(a2.ID); err != nil { + if err := s.DeleteAuthRequest(ctx, a2.ID); err != nil { t.Fatalf("failed to delete auth request: %v", err) } - _, err = s.GetAuthRequest(a1.ID) + _, err = s.GetAuthRequest(ctx, a1.ID) mustBeErrNotFound(t, "auth request", err) } func testAuthCodeCRUD(t *testing.T, s storage.Storage) { + ctx := t.Context() a1 := storage.AuthCode{ ID: storage.NewID(), ClientID: "client1", @@ -198,7 +204,7 @@ func testAuthCodeCRUD(t *testing.T, s storage.Storage) { }, } - if err := s.CreateAuthCode(a1); err != nil { + if err := s.CreateAuthCode(ctx, a1); err != nil { t.Fatalf("failed creating auth code: %v", err) } @@ -221,14 +227,14 @@ func testAuthCodeCRUD(t *testing.T, s storage.Storage) { } // Attempt to create same AuthCode twice. - err := s.CreateAuthCode(a1) + err := s.CreateAuthCode(ctx, a1) mustBeErrAlreadyExists(t, "auth code", err) - if err := s.CreateAuthCode(a2); err != nil { + if err := s.CreateAuthCode(ctx, a2); err != nil { t.Fatalf("failed creating auth code: %v", err) } - got, err := s.GetAuthCode(a1.ID) + got, err := s.GetAuthCode(ctx, a1.ID) if err != nil { t.Fatalf("failed to get auth code: %v", err) } @@ -240,19 +246,20 @@ func testAuthCodeCRUD(t *testing.T, s storage.Storage) { t.Errorf("auth code retrieved from storage did not match: %s", diff) } - if err := s.DeleteAuthCode(a1.ID); err != nil { + if err := s.DeleteAuthCode(ctx, a1.ID); err != nil { t.Fatalf("delete auth code: %v", err) } - if err := s.DeleteAuthCode(a2.ID); err != nil { + if err := s.DeleteAuthCode(ctx, a2.ID); err != nil { t.Fatalf("delete auth code: %v", err) } - _, err = s.GetAuthCode(a1.ID) + _, err = s.GetAuthCode(ctx, a1.ID) mustBeErrNotFound(t, "auth code", err) } func testClientCRUD(t *testing.T, s storage.Storage) { + ctx := t.Context() id1 := storage.NewID() c1 := storage.Client{ ID: id1, @@ -261,15 +268,15 @@ func testClientCRUD(t *testing.T, s storage.Storage) { Name: "dex client", LogoURL: "https://goo.gl/JIyzIC", } - err := s.DeleteClient(id1) + err := s.DeleteClient(ctx, id1) mustBeErrNotFound(t, "client", err) - if err := s.CreateClient(c1); err != nil { + if err := s.CreateClient(ctx, c1); err != nil { t.Fatalf("create client: %v", err) } // Attempt to create same Client twice. - err = s.CreateClient(c1) + err = s.CreateClient(ctx, c1) mustBeErrAlreadyExists(t, "client", err) id2 := storage.NewID() @@ -281,12 +288,12 @@ func testClientCRUD(t *testing.T, s storage.Storage) { LogoURL: "https://goo.gl/JIyzIC", } - if err := s.CreateClient(c2); err != nil { + if err := s.CreateClient(ctx, c2); err != nil { t.Fatalf("create client: %v", err) } getAndCompare := func(_ string, want storage.Client) { - gc, err := s.GetClient(id1) + gc, err := s.GetClient(ctx, id1) if err != nil { t.Errorf("get client: %v", err) return @@ -299,7 +306,7 @@ func testClientCRUD(t *testing.T, s storage.Storage) { getAndCompare(id1, c1) newSecret := "barfoo" - err = s.UpdateClient(id1, func(old storage.Client) (storage.Client, error) { + err = s.UpdateClient(ctx, id1, func(old storage.Client) (storage.Client, error) { old.Secret = newSecret return old, nil }) @@ -309,19 +316,20 @@ func testClientCRUD(t *testing.T, s storage.Storage) { c1.Secret = newSecret getAndCompare(id1, c1) - if err := s.DeleteClient(id1); err != nil { + if err := s.DeleteClient(ctx, id1); err != nil { t.Fatalf("delete client: %v", err) } - if err := s.DeleteClient(id2); err != nil { + if err := s.DeleteClient(ctx, id2); err != nil { t.Fatalf("delete client: %v", err) } - _, err = s.GetClient(id1) + _, err = s.GetClient(ctx, id1) mustBeErrNotFound(t, "client", err) } func testRefreshTokenCRUD(t *testing.T, s storage.Storage) { + ctx := t.Context() id := storage.NewID() refresh := storage.RefreshToken{ ID: id, @@ -342,16 +350,16 @@ func testRefreshTokenCRUD(t *testing.T, s storage.Storage) { }, ConnectorData: []byte(`{"some":"data"}`), } - if err := s.CreateRefresh(refresh); err != nil { + if err := s.CreateRefresh(ctx, refresh); err != nil { t.Fatalf("create refresh token: %v", err) } // Attempt to create same Refresh Token twice. - err := s.CreateRefresh(refresh) + err := s.CreateRefresh(ctx, refresh) mustBeErrAlreadyExists(t, "refresh token", err) getAndCompare := func(id string, want storage.RefreshToken) { - gr, err := s.GetRefresh(id) + gr, err := s.GetRefresh(ctx, id) if err != nil { t.Errorf("get refresh: %v", err) return @@ -398,7 +406,7 @@ func testRefreshTokenCRUD(t *testing.T, s storage.Storage) { ConnectorData: []byte(`{"some":"data"}`), } - if err := s.CreateRefresh(refresh2); err != nil { + if err := s.CreateRefresh(ctx, refresh2); err != nil { t.Fatalf("create second refresh token: %v", err) } @@ -411,7 +419,7 @@ func testRefreshTokenCRUD(t *testing.T, s storage.Storage) { r.LastUsed = updatedAt return r, nil } - if err := s.UpdateRefreshToken(id, updater); err != nil { + if err := s.UpdateRefreshToken(ctx, id, updater); err != nil { t.Errorf("failed to update refresh token: %v", err) } refresh.Token = "spam" @@ -421,15 +429,15 @@ func testRefreshTokenCRUD(t *testing.T, s storage.Storage) { // Ensure that updating the first token doesn't impact the second. Issue #847. getAndCompare(id2, refresh2) - if err := s.DeleteRefresh(id); err != nil { + if err := s.DeleteRefresh(ctx, id); err != nil { t.Fatalf("failed to delete refresh request: %v", err) } - if err := s.DeleteRefresh(id2); err != nil { + if err := s.DeleteRefresh(ctx, id2); err != nil { t.Fatalf("failed to delete refresh request: %v", err) } - _, err = s.GetRefresh(id) + _, err = s.GetRefresh(ctx, id) mustBeErrNotFound(t, "refresh token", err) } @@ -440,6 +448,7 @@ func (n byEmail) Less(i, j int) bool { return n[i].Email < n[j].Email } func (n byEmail) Swap(i, j int) { n[i], n[j] = n[j], n[i] } func testPasswordCRUD(t *testing.T, s storage.Storage) { + ctx := t.Context() // Use bcrypt.MinCost to keep the tests short. passwordHash1, err := bcrypt.GenerateFromPassword([]byte("secret"), bcrypt.MinCost) if err != nil { @@ -452,12 +461,12 @@ func testPasswordCRUD(t *testing.T, s storage.Storage) { Username: "jane", UserID: "foobar", } - if err := s.CreatePassword(password1); err != nil { + if err := s.CreatePassword(ctx, password1); err != nil { t.Fatalf("create password token: %v", err) } // Attempt to create same Password twice. - err = s.CreatePassword(password1) + err = s.CreatePassword(ctx, password1) mustBeErrAlreadyExists(t, "password", err) passwordHash2, err := bcrypt.GenerateFromPassword([]byte("password"), bcrypt.MinCost) @@ -471,12 +480,12 @@ func testPasswordCRUD(t *testing.T, s storage.Storage) { Username: "john", UserID: "barfoo", } - if err := s.CreatePassword(password2); err != nil { + if err := s.CreatePassword(ctx, password2); err != nil { t.Fatalf("create password token: %v", err) } getAndCompare := func(id string, want storage.Password) { - gr, err := s.GetPassword(id) + gr, err := s.GetPassword(ctx, id) if err != nil { t.Errorf("get password %q: %v", id, err) return @@ -489,7 +498,7 @@ func testPasswordCRUD(t *testing.T, s storage.Storage) { getAndCompare("jane@example.com", password1) getAndCompare("JANE@example.com", password1) // Emails should be case insensitive - if err := s.UpdatePassword(password1.Email, func(old storage.Password) (storage.Password, error) { + if err := s.UpdatePassword(ctx, password1.Email, func(old storage.Password) (storage.Password, error) { old.Username = "jane doe" return old, nil }); err != nil { @@ -503,7 +512,7 @@ func testPasswordCRUD(t *testing.T, s storage.Storage) { passwordList = append(passwordList, password1, password2) listAndCompare := func(want []storage.Password) { - passwords, err := s.ListPasswords() + passwords, err := s.ListPasswords(ctx) if err != nil { t.Errorf("list password: %v", err) return @@ -517,19 +526,20 @@ func testPasswordCRUD(t *testing.T, s storage.Storage) { listAndCompare(passwordList) - if err := s.DeletePassword(password1.Email); err != nil { + if err := s.DeletePassword(ctx, password1.Email); err != nil { t.Fatalf("failed to delete password: %v", err) } - if err := s.DeletePassword(password2.Email); err != nil { + if err := s.DeletePassword(ctx, password2.Email); err != nil { t.Fatalf("failed to delete password: %v", err) } - _, err = s.GetPassword(password1.Email) + _, err = s.GetPassword(ctx, password1.Email) mustBeErrNotFound(t, "password", err) } func testOfflineSessionCRUD(t *testing.T, s storage.Storage) { + ctx := t.Context() userID1 := storage.NewID() session1 := storage.OfflineSessions{ UserID: userID1, @@ -540,12 +550,12 @@ func testOfflineSessionCRUD(t *testing.T, s storage.Storage) { // Creating an OfflineSession with an empty Refresh list to ensure that // an empty map is translated as expected by the storage. - if err := s.CreateOfflineSessions(session1); err != nil { + if err := s.CreateOfflineSessions(ctx, session1); err != nil { t.Fatalf("create offline session with UserID = %s: %v", session1.UserID, err) } // Attempt to create same OfflineSession twice. - err := s.CreateOfflineSessions(session1) + err := s.CreateOfflineSessions(ctx, session1) mustBeErrAlreadyExists(t, "offline session", err) userID2 := storage.NewID() @@ -556,12 +566,12 @@ func testOfflineSessionCRUD(t *testing.T, s storage.Storage) { ConnectorData: []byte(`{"some":"data"}`), } - if err := s.CreateOfflineSessions(session2); err != nil { + if err := s.CreateOfflineSessions(ctx, session2); err != nil { t.Fatalf("create offline session with UserID = %s: %v", session2.UserID, err) } getAndCompare := func(userID string, connID string, want storage.OfflineSessions) { - gr, err := s.GetOfflineSessions(userID, connID) + gr, err := s.GetOfflineSessions(ctx, userID, connID) if err != nil { t.Errorf("get offline session: %v", err) return @@ -582,7 +592,7 @@ func testOfflineSessionCRUD(t *testing.T, s storage.Storage) { } session1.Refresh[tokenRef.ClientID] = &tokenRef - if err := s.UpdateOfflineSessions(session1.UserID, session1.ConnID, func(old storage.OfflineSessions) (storage.OfflineSessions, error) { + if err := s.UpdateOfflineSessions(ctx, session1.UserID, session1.ConnID, func(old storage.OfflineSessions) (storage.OfflineSessions, error) { old.Refresh[tokenRef.ClientID] = &tokenRef return old, nil }); err != nil { @@ -591,19 +601,20 @@ func testOfflineSessionCRUD(t *testing.T, s storage.Storage) { getAndCompare(userID1, "Conn1", session1) - if err := s.DeleteOfflineSessions(session1.UserID, session1.ConnID); err != nil { + if err := s.DeleteOfflineSessions(ctx, session1.UserID, session1.ConnID); err != nil { t.Fatalf("failed to delete offline session: %v", err) } - if err := s.DeleteOfflineSessions(session2.UserID, session2.ConnID); err != nil { + if err := s.DeleteOfflineSessions(ctx, session2.UserID, session2.ConnID); err != nil { t.Fatalf("failed to delete offline session: %v", err) } - _, err = s.GetOfflineSessions(session1.UserID, session1.ConnID) + _, err = s.GetOfflineSessions(ctx, session1.UserID, session1.ConnID) mustBeErrNotFound(t, "offline session", err) } func testConnectorCRUD(t *testing.T, s storage.Storage) { + ctx := t.Context() id1 := storage.NewID() config1 := []byte(`{"issuer": "https://accounts.google.com"}`) c1 := storage.Connector{ @@ -613,12 +624,12 @@ func testConnectorCRUD(t *testing.T, s storage.Storage) { Config: config1, } - if err := s.CreateConnector(c1); err != nil { + if err := s.CreateConnector(ctx, c1); err != nil { t.Fatalf("create connector with ID = %s: %v", c1.ID, err) } // Attempt to create same Connector twice. - err := s.CreateConnector(c1) + err := s.CreateConnector(ctx, c1) mustBeErrAlreadyExists(t, "connector", err) id2 := storage.NewID() @@ -630,12 +641,12 @@ func testConnectorCRUD(t *testing.T, s storage.Storage) { Config: config2, } - if err := s.CreateConnector(c2); err != nil { + if err := s.CreateConnector(ctx, c2); err != nil { t.Fatalf("create connector with ID = %s: %v", c2.ID, err) } getAndCompare := func(id string, want storage.Connector) { - gr, err := s.GetConnector(id) + gr, err := s.GetConnector(ctx, id) if err != nil { t.Errorf("get connector: %v", err) return @@ -649,7 +660,7 @@ func testConnectorCRUD(t *testing.T, s storage.Storage) { getAndCompare(id1, c1) - if err := s.UpdateConnector(c1.ID, func(old storage.Connector) (storage.Connector, error) { + if err := s.UpdateConnector(ctx, c1.ID, func(old storage.Connector) (storage.Connector, error) { old.Type = "oidc" return old, nil }); err != nil { @@ -661,7 +672,7 @@ func testConnectorCRUD(t *testing.T, s storage.Storage) { connectorList := []storage.Connector{c1, c2} listAndCompare := func(want []storage.Connector) { - connectors, err := s.ListConnectors() + connectors, err := s.ListConnectors(ctx) if err != nil { t.Errorf("list connectors: %v", err) return @@ -679,21 +690,23 @@ func testConnectorCRUD(t *testing.T, s storage.Storage) { } listAndCompare(connectorList) - if err := s.DeleteConnector(c1.ID); err != nil { + if err := s.DeleteConnector(ctx, c1.ID); err != nil { t.Fatalf("failed to delete connector: %v", err) } - if err := s.DeleteConnector(c2.ID); err != nil { + if err := s.DeleteConnector(ctx, c2.ID); err != nil { t.Fatalf("failed to delete connector: %v", err) } - _, err = s.GetConnector(c1.ID) + _, err = s.GetConnector(ctx, c1.ID) mustBeErrNotFound(t, "connector", err) } func testKeysCRUD(t *testing.T, s storage.Storage) { + ctx := context.TODO() + updateAndCompare := func(k storage.Keys) { - err := s.UpdateKeys(func(oldKeys storage.Keys) (storage.Keys, error) { + err := s.UpdateKeys(ctx, func(oldKeys storage.Keys) (storage.Keys, error) { return k, nil }) if err != nil { @@ -701,7 +714,7 @@ func testKeysCRUD(t *testing.T, s storage.Storage) { return } - if got, err := s.GetKeys(); err != nil { + if got, err := s.GetKeys(ctx); err != nil { t.Errorf("failed to get keys: %v", err) } else { got.NextRotation = got.NextRotation.UTC() @@ -741,6 +754,7 @@ func testKeysCRUD(t *testing.T, s storage.Storage) { } func testGC(t *testing.T, s storage.Storage) { + ctx := t.Context() est, err := time.LoadLocation("America/New_York") if err != nil { t.Fatal(err) @@ -769,29 +783,29 @@ func testGC(t *testing.T, s storage.Storage) { }, } - if err := s.CreateAuthCode(c); err != nil { + if err := s.CreateAuthCode(ctx, c); err != nil { t.Fatalf("failed creating auth code: %v", err) } for _, tz := range []*time.Location{time.UTC, est, pst} { - result, err := s.GarbageCollect(expiry.Add(-time.Hour).In(tz)) + result, err := s.GarbageCollect(ctx, expiry.Add(-time.Hour).In(tz)) if err != nil { t.Errorf("garbage collection failed: %v", err) } else if result.AuthCodes != 0 || result.AuthRequests != 0 { t.Errorf("expected no garbage collection results, got %#v", result) } - if _, err := s.GetAuthCode(c.ID); err != nil { + if _, err := s.GetAuthCode(ctx, c.ID); err != nil { t.Errorf("expected to be able to get auth code after GC: %v", err) } } - if r, err := s.GarbageCollect(expiry.Add(time.Hour)); err != nil { + if r, err := s.GarbageCollect(ctx, expiry.Add(time.Hour)); err != nil { t.Errorf("garbage collection failed: %v", err) } else if r.AuthCodes != 1 { t.Errorf("expected to garbage collect 1 objects, got %d", r.AuthCodes) } - if _, err := s.GetAuthCode(c.ID); err == nil { + if _, err := s.GetAuthCode(ctx, c.ID); err == nil { t.Errorf("expected auth code to be GC'd") } else if err != storage.ErrNotFound { t.Errorf("expected storage.ErrNotFound, got %v", err) @@ -817,31 +831,32 @@ func testGC(t *testing.T, s storage.Storage) { EmailVerified: true, Groups: []string{"a", "b"}, }, + HMACKey: []byte("hmac_key"), } - if err := s.CreateAuthRequest(a); err != nil { + if err := s.CreateAuthRequest(ctx, a); err != nil { t.Fatalf("failed creating auth request: %v", err) } for _, tz := range []*time.Location{time.UTC, est, pst} { - result, err := s.GarbageCollect(expiry.Add(-time.Hour).In(tz)) + result, err := s.GarbageCollect(ctx, expiry.Add(-time.Hour).In(tz)) if err != nil { t.Errorf("garbage collection failed: %v", err) } else if result.AuthCodes != 0 || result.AuthRequests != 0 { t.Errorf("expected no garbage collection results, got %#v", result) } - if _, err := s.GetAuthRequest(a.ID); err != nil { + if _, err := s.GetAuthRequest(ctx, a.ID); err != nil { t.Errorf("expected to be able to get auth request after GC: %v", err) } } - if r, err := s.GarbageCollect(expiry.Add(time.Hour)); err != nil { + if r, err := s.GarbageCollect(ctx, expiry.Add(time.Hour)); err != nil { t.Errorf("garbage collection failed: %v", err) } else if r.AuthRequests != 1 { t.Errorf("expected to garbage collect 1 objects, got %d", r.AuthRequests) } - if _, err := s.GetAuthRequest(a.ID); err == nil { + if _, err := s.GetAuthRequest(ctx, a.ID); err == nil { t.Errorf("expected auth request to be GC'd") } else if err != storage.ErrNotFound { t.Errorf("expected storage.ErrNotFound, got %v", err) @@ -856,28 +871,28 @@ func testGC(t *testing.T, s storage.Storage) { Expiry: expiry, } - if err := s.CreateDeviceRequest(d); err != nil { + if err := s.CreateDeviceRequest(ctx, d); err != nil { t.Fatalf("failed creating device request: %v", err) } for _, tz := range []*time.Location{time.UTC, est, pst} { - result, err := s.GarbageCollect(expiry.Add(-time.Hour).In(tz)) + result, err := s.GarbageCollect(ctx, expiry.Add(-time.Hour).In(tz)) if err != nil { t.Errorf("garbage collection failed: %v", err) } else if result.DeviceRequests != 0 { t.Errorf("expected no device garbage collection results, got %#v", result) } - if _, err := s.GetDeviceRequest(d.UserCode); err != nil { + if _, err := s.GetDeviceRequest(ctx, d.UserCode); err != nil { t.Errorf("expected to be able to get auth request after GC: %v", err) } } - if r, err := s.GarbageCollect(expiry.Add(time.Hour)); err != nil { + if r, err := s.GarbageCollect(ctx, expiry.Add(time.Hour)); err != nil { t.Errorf("garbage collection failed: %v", err) } else if r.DeviceRequests != 1 { t.Errorf("expected to garbage collect 1 device request, got %d", r.DeviceRequests) } - if _, err := s.GetDeviceRequest(d.UserCode); err == nil { + if _, err := s.GetDeviceRequest(ctx, d.UserCode); err == nil { t.Errorf("expected device request to be GC'd") } else if err != storage.ErrNotFound { t.Errorf("expected storage.ErrNotFound, got %v", err) @@ -896,28 +911,28 @@ func testGC(t *testing.T, s storage.Storage) { }, } - if err := s.CreateDeviceToken(dt); err != nil { + if err := s.CreateDeviceToken(ctx, dt); err != nil { t.Fatalf("failed creating device token: %v", err) } for _, tz := range []*time.Location{time.UTC, est, pst} { - result, err := s.GarbageCollect(expiry.Add(-time.Hour).In(tz)) + result, err := s.GarbageCollect(ctx, expiry.Add(-time.Hour).In(tz)) if err != nil { t.Errorf("garbage collection failed: %v", err) } else if result.DeviceTokens != 0 { t.Errorf("expected no device token garbage collection results, got %#v", result) } - if _, err := s.GetDeviceToken(dt.DeviceCode); err != nil { + if _, err := s.GetDeviceToken(ctx, dt.DeviceCode); err != nil { t.Errorf("expected to be able to get device token after GC: %v", err) } } - if r, err := s.GarbageCollect(expiry.Add(time.Hour)); err != nil { + if r, err := s.GarbageCollect(ctx, expiry.Add(time.Hour)); err != nil { t.Errorf("garbage collection failed: %v", err) } else if r.DeviceTokens != 1 { t.Errorf("expected to garbage collect 1 device token, got %d", r.DeviceTokens) } - if _, err := s.GetDeviceToken(dt.DeviceCode); err == nil { + if _, err := s.GetDeviceToken(ctx, dt.DeviceCode); err == nil { t.Errorf("expected device token to be GC'd") } else if err != storage.ErrNotFound { t.Errorf("expected storage.ErrNotFound, got %v", err) @@ -927,6 +942,7 @@ func testGC(t *testing.T, s storage.Storage) { // testTimezones tests that backends either fully support timezones or // do the correct standardization. func testTimezones(t *testing.T, s storage.Storage) { + ctx := t.Context() est, err := time.LoadLocation("America/New_York") if err != nil { t.Fatal(err) @@ -952,10 +968,10 @@ func testTimezones(t *testing.T, s storage.Storage) { Groups: []string{"a", "b"}, }, } - if err := s.CreateAuthCode(c); err != nil { + if err := s.CreateAuthCode(ctx, c); err != nil { t.Fatalf("failed creating auth code: %v", err) } - got, err := s.GetAuthCode(c.ID) + got, err := s.GetAuthCode(ctx, c.ID) if err != nil { t.Fatalf("failed to get auth code: %v", err) } @@ -971,28 +987,37 @@ func testTimezones(t *testing.T, s storage.Storage) { } func testDeviceRequestCRUD(t *testing.T, s storage.Storage) { + ctx := t.Context() d1 := storage.DeviceRequest{ UserCode: storage.NewUserCode(), DeviceCode: storage.NewID(), ClientID: "client1", ClientSecret: "secret1", Scopes: []string{"openid", "email"}, - Expiry: neverExpire, + Expiry: neverExpire.Round(time.Second), } - if err := s.CreateDeviceRequest(d1); err != nil { + if err := s.CreateDeviceRequest(ctx, d1); err != nil { t.Fatalf("failed creating device request: %v", err) } // Attempt to create same DeviceRequest twice. - err := s.CreateDeviceRequest(d1) + err := s.CreateDeviceRequest(ctx, d1) mustBeErrAlreadyExists(t, "device request", err) + got, err := s.GetDeviceRequest(ctx, d1.UserCode) + if err != nil { + t.Fatalf("failed to get device request: %v", err) + } + + require.Equal(t, d1, got) + // No manual deletes for device requests, will be handled by garbage collection routines // see testGC } func testDeviceTokenCRUD(t *testing.T, s storage.Storage) { + ctx := t.Context() codeChallenge := storage.PKCE{ CodeChallenge: "code_challenge_test", CodeChallengeMethod: "plain", @@ -1009,16 +1034,16 @@ func testDeviceTokenCRUD(t *testing.T, s storage.Storage) { PKCE: codeChallenge, } - if err := s.CreateDeviceToken(d1); err != nil { + if err := s.CreateDeviceToken(ctx, d1); err != nil { t.Fatalf("failed creating device token: %v", err) } // Attempt to create same Device Token twice. - err := s.CreateDeviceToken(d1) + err := s.CreateDeviceToken(ctx, d1) mustBeErrAlreadyExists(t, "device token", err) // Update the device token, simulate a redemption - if err := s.UpdateDeviceToken(d1.DeviceCode, func(old storage.DeviceToken) (storage.DeviceToken, error) { + if err := s.UpdateDeviceToken(ctx, d1.DeviceCode, func(old storage.DeviceToken) (storage.DeviceToken, error) { old.Token = "token data" old.Status = "complete" return old, nil @@ -1027,7 +1052,7 @@ func testDeviceTokenCRUD(t *testing.T, s storage.Storage) { } // Retrieve the device token - got, err := s.GetDeviceToken(d1.DeviceCode) + got, err := s.GetDeviceToken(ctx, d1.DeviceCode) if err != nil { t.Fatalf("failed to get device token: %v", err) } diff --git a/storage/conformance/gen_jwks.go b/storage/conformance/gen_jwks.go index 0447e32815..0029b9b881 100644 --- a/storage/conformance/gen_jwks.go +++ b/storage/conformance/gen_jwks.go @@ -1,3 +1,4 @@ +//go:build ignore // +build ignore // This file is used to generate static JWKs for tests. @@ -16,7 +17,7 @@ import ( "os" "text/template" - jose "gopkg.in/square/go-jose.v2" + "github.com/go-jose/go-jose/v4" ) func newUUID() string { @@ -36,7 +37,7 @@ var tmpl = template.Must(template.New("jwks.go").Parse(` package conformance -import jose "gopkg.in/square/go-jose.v2" +import jose "github.com/go-jose/go-jose/v4" type keyPair struct { Public *jose.JSONWebKey diff --git a/storage/conformance/jwks.go b/storage/conformance/jwks.go index 0f05703e1b..28ce5f7255 100644 --- a/storage/conformance/jwks.go +++ b/storage/conformance/jwks.go @@ -2,7 +2,7 @@ package conformance -import jose "gopkg.in/square/go-jose.v2" +import "github.com/go-jose/go-jose/v4" type keyPair struct { Public *jose.JSONWebKey diff --git a/storage/conformance/transactions.go b/storage/conformance/transactions.go index 2fc6755b09..a67a6d7d78 100644 --- a/storage/conformance/transactions.go +++ b/storage/conformance/transactions.go @@ -1,6 +1,7 @@ package conformance import ( + "context" "testing" "time" @@ -16,7 +17,7 @@ import ( // This call is separate from RunTests because some storage perform extremely // poorly under deadlocks, such as SQLite3, while others may be working towards // conformance. -func RunTransactionTests(t *testing.T, newStorage func() storage.Storage) { +func RunTransactionTests(t *testing.T, newStorage func(t *testing.T) storage.Storage) { runTests(t, newStorage, []subTest{ {"AuthRequestConcurrentUpdate", testAuthRequestConcurrentUpdate}, {"ClientConcurrentUpdate", testClientConcurrentUpdate}, @@ -26,6 +27,7 @@ func RunTransactionTests(t *testing.T, newStorage func() storage.Storage) { } func testClientConcurrentUpdate(t *testing.T, s storage.Storage) { + ctx := t.Context() c := storage.Client{ ID: storage.NewID(), Secret: "foobar", @@ -34,15 +36,15 @@ func testClientConcurrentUpdate(t *testing.T, s storage.Storage) { LogoURL: "https://goo.gl/JIyzIC", } - if err := s.CreateClient(c); err != nil { + if err := s.CreateClient(ctx, c); err != nil { t.Fatalf("create client: %v", err) } var err1, err2 error - err1 = s.UpdateClient(c.ID, func(old storage.Client) (storage.Client, error) { + err1 = s.UpdateClient(ctx, c.ID, func(old storage.Client) (storage.Client, error) { old.Secret = "new secret 1" - err2 = s.UpdateClient(c.ID, func(old storage.Client) (storage.Client, error) { + err2 = s.UpdateClient(ctx, c.ID, func(old storage.Client) (storage.Client, error) { old.Secret = "new secret 2" return old, nil }) @@ -55,6 +57,7 @@ func testClientConcurrentUpdate(t *testing.T, s storage.Storage) { } func testAuthRequestConcurrentUpdate(t *testing.T, s storage.Storage) { + ctx := t.Context() a := storage.AuthRequest{ ID: storage.NewID(), ClientID: "foobar", @@ -75,17 +78,18 @@ func testAuthRequestConcurrentUpdate(t *testing.T, s storage.Storage) { EmailVerified: true, Groups: []string{"a", "b"}, }, + HMACKey: []byte("hmac_key"), } - if err := s.CreateAuthRequest(a); err != nil { + if err := s.CreateAuthRequest(ctx, a); err != nil { t.Fatalf("failed creating auth request: %v", err) } var err1, err2 error - err1 = s.UpdateAuthRequest(a.ID, func(old storage.AuthRequest) (storage.AuthRequest, error) { + err1 = s.UpdateAuthRequest(ctx, a.ID, func(old storage.AuthRequest) (storage.AuthRequest, error) { old.State = "state 1" - err2 = s.UpdateAuthRequest(a.ID, func(old storage.AuthRequest) (storage.AuthRequest, error) { + err2 = s.UpdateAuthRequest(ctx, a.ID, func(old storage.AuthRequest) (storage.AuthRequest, error) { old.State = "state 2" return old, nil }) @@ -98,6 +102,7 @@ func testAuthRequestConcurrentUpdate(t *testing.T, s storage.Storage) { } func testPasswordConcurrentUpdate(t *testing.T, s storage.Storage) { + ctx := t.Context() // Use bcrypt.MinCost to keep the tests short. passwordHash, err := bcrypt.GenerateFromPassword([]byte("secret"), bcrypt.MinCost) if err != nil { @@ -110,15 +115,15 @@ func testPasswordConcurrentUpdate(t *testing.T, s storage.Storage) { Username: "jane", UserID: "foobar", } - if err := s.CreatePassword(password); err != nil { + if err := s.CreatePassword(ctx, password); err != nil { t.Fatalf("create password token: %v", err) } var err1, err2 error - err1 = s.UpdatePassword(password.Email, func(old storage.Password) (storage.Password, error) { + err1 = s.UpdatePassword(ctx, password.Email, func(old storage.Password) (storage.Password, error) { old.Username = "user 1" - err2 = s.UpdatePassword(password.Email, func(old storage.Password) (storage.Password, error) { + err2 = s.UpdatePassword(ctx, password.Email, func(old storage.Password) (storage.Password, error) { old.Username = "user 2" return old, nil }) @@ -158,8 +163,9 @@ func testKeysConcurrentUpdate(t *testing.T, s storage.Storage) { var err1, err2 error - err1 = s.UpdateKeys(func(old storage.Keys) (storage.Keys, error) { - err2 = s.UpdateKeys(func(old storage.Keys) (storage.Keys, error) { + ctx := context.TODO() + err1 = s.UpdateKeys(ctx, func(old storage.Keys) (storage.Keys, error) { + err2 = s.UpdateKeys(ctx, func(old storage.Keys) (storage.Keys, error) { return keys1, nil }) return keys2, nil diff --git a/storage/ent/client/authcode.go b/storage/ent/client/authcode.go index b6b263bff8..aa5bd184c3 100644 --- a/storage/ent/client/authcode.go +++ b/storage/ent/client/authcode.go @@ -7,7 +7,7 @@ import ( ) // CreateAuthCode saves provided auth code into the database. -func (d *Database) CreateAuthCode(code storage.AuthCode) error { +func (d *Database) CreateAuthCode(ctx context.Context, code storage.AuthCode) error { _, err := d.client.AuthCode.Create(). SetID(code.ID). SetClientID(code.ClientID). @@ -26,7 +26,7 @@ func (d *Database) CreateAuthCode(code storage.AuthCode) error { SetExpiry(code.Expiry.UTC()). SetConnectorID(code.ConnectorID). SetConnectorData(code.ConnectorData). - Save(context.TODO()) + Save(ctx) if err != nil { return convertDBError("create auth code: %w", err) } @@ -34,8 +34,8 @@ func (d *Database) CreateAuthCode(code storage.AuthCode) error { } // GetAuthCode extracts an auth code from the database by id. -func (d *Database) GetAuthCode(id string) (storage.AuthCode, error) { - authCode, err := d.client.AuthCode.Get(context.TODO(), id) +func (d *Database) GetAuthCode(ctx context.Context, id string) (storage.AuthCode, error) { + authCode, err := d.client.AuthCode.Get(ctx, id) if err != nil { return storage.AuthCode{}, convertDBError("get auth code: %w", err) } @@ -43,8 +43,8 @@ func (d *Database) GetAuthCode(id string) (storage.AuthCode, error) { } // DeleteAuthCode deletes an auth code from the database by id. -func (d *Database) DeleteAuthCode(id string) error { - err := d.client.AuthCode.DeleteOneID(id).Exec(context.TODO()) +func (d *Database) DeleteAuthCode(ctx context.Context, id string) error { + err := d.client.AuthCode.DeleteOneID(id).Exec(ctx) if err != nil { return convertDBError("delete auth code: %w", err) } diff --git a/storage/ent/client/authrequest.go b/storage/ent/client/authrequest.go index bde37adc27..25d3e41569 100644 --- a/storage/ent/client/authrequest.go +++ b/storage/ent/client/authrequest.go @@ -8,7 +8,7 @@ import ( ) // CreateAuthRequest saves provided auth request into the database. -func (d *Database) CreateAuthRequest(authRequest storage.AuthRequest) error { +func (d *Database) CreateAuthRequest(ctx context.Context, authRequest storage.AuthRequest) error { _, err := d.client.AuthRequest.Create(). SetID(authRequest.ID). SetClientID(authRequest.ClientID). @@ -31,7 +31,8 @@ func (d *Database) CreateAuthRequest(authRequest storage.AuthRequest) error { SetExpiry(authRequest.Expiry.UTC()). SetConnectorID(authRequest.ConnectorID). SetConnectorData(authRequest.ConnectorData). - Save(context.TODO()) + SetHmacKey(authRequest.HMACKey). + Save(ctx) if err != nil { return convertDBError("create auth request: %w", err) } @@ -39,8 +40,8 @@ func (d *Database) CreateAuthRequest(authRequest storage.AuthRequest) error { } // GetAuthRequest extracts an auth request from the database by id. -func (d *Database) GetAuthRequest(id string) (storage.AuthRequest, error) { - authRequest, err := d.client.AuthRequest.Get(context.TODO(), id) +func (d *Database) GetAuthRequest(ctx context.Context, id string) (storage.AuthRequest, error) { + authRequest, err := d.client.AuthRequest.Get(ctx, id) if err != nil { return storage.AuthRequest{}, convertDBError("get auth request: %w", err) } @@ -48,8 +49,8 @@ func (d *Database) GetAuthRequest(id string) (storage.AuthRequest, error) { } // DeleteAuthRequest deletes an auth request from the database by id. -func (d *Database) DeleteAuthRequest(id string) error { - err := d.client.AuthRequest.DeleteOneID(id).Exec(context.TODO()) +func (d *Database) DeleteAuthRequest(ctx context.Context, id string) error { + err := d.client.AuthRequest.DeleteOneID(id).Exec(ctx) if err != nil { return convertDBError("delete auth request: %w", err) } @@ -57,8 +58,8 @@ func (d *Database) DeleteAuthRequest(id string) error { } // UpdateAuthRequest changes an auth request by id using an updater function and saves it to the database. -func (d *Database) UpdateAuthRequest(id string, updater func(old storage.AuthRequest) (storage.AuthRequest, error)) error { - tx, err := d.BeginTx(context.TODO()) +func (d *Database) UpdateAuthRequest(ctx context.Context, id string, updater func(old storage.AuthRequest) (storage.AuthRequest, error)) error { + tx, err := d.BeginTx(ctx) if err != nil { return fmt.Errorf("update auth request tx: %w", err) } @@ -94,6 +95,7 @@ func (d *Database) UpdateAuthRequest(id string, updater func(old storage.AuthReq SetExpiry(newAuthRequest.Expiry.UTC()). SetConnectorID(newAuthRequest.ConnectorID). SetConnectorData(newAuthRequest.ConnectorData). + SetHmacKey(newAuthRequest.HMACKey). Save(context.TODO()) if err != nil { return rollback(tx, "update auth request uploading: %w", err) diff --git a/storage/ent/client/client.go b/storage/ent/client/client.go index 07434bd60b..1957a76a9b 100644 --- a/storage/ent/client/client.go +++ b/storage/ent/client/client.go @@ -7,7 +7,7 @@ import ( ) // CreateClient saves provided oauth2 client settings into the database. -func (d *Database) CreateClient(client storage.Client) error { +func (d *Database) CreateClient(ctx context.Context, client storage.Client) error { _, err := d.client.OAuth2Client.Create(). SetID(client.ID). SetName(client.Name). @@ -16,7 +16,7 @@ func (d *Database) CreateClient(client storage.Client) error { SetLogoURL(client.LogoURL). SetRedirectUris(client.RedirectURIs). SetTrustedPeers(client.TrustedPeers). - Save(context.TODO()) + Save(ctx) if err != nil { return convertDBError("create oauth2 client: %w", err) } @@ -24,8 +24,8 @@ func (d *Database) CreateClient(client storage.Client) error { } // ListClients extracts an array of oauth2 clients from the database. -func (d *Database) ListClients() ([]storage.Client, error) { - clients, err := d.client.OAuth2Client.Query().All(context.TODO()) +func (d *Database) ListClients(ctx context.Context) ([]storage.Client, error) { + clients, err := d.client.OAuth2Client.Query().All(ctx) if err != nil { return nil, convertDBError("list clients: %w", err) } @@ -38,8 +38,8 @@ func (d *Database) ListClients() ([]storage.Client, error) { } // GetClient extracts an oauth2 client from the database by id. -func (d *Database) GetClient(id string) (storage.Client, error) { - client, err := d.client.OAuth2Client.Get(context.TODO(), id) +func (d *Database) GetClient(ctx context.Context, id string) (storage.Client, error) { + client, err := d.client.OAuth2Client.Get(ctx, id) if err != nil { return storage.Client{}, convertDBError("get client: %w", err) } @@ -47,8 +47,8 @@ func (d *Database) GetClient(id string) (storage.Client, error) { } // DeleteClient deletes an oauth2 client from the database by id. -func (d *Database) DeleteClient(id string) error { - err := d.client.OAuth2Client.DeleteOneID(id).Exec(context.TODO()) +func (d *Database) DeleteClient(ctx context.Context, id string) error { + err := d.client.OAuth2Client.DeleteOneID(id).Exec(ctx) if err != nil { return convertDBError("delete client: %w", err) } @@ -56,13 +56,13 @@ func (d *Database) DeleteClient(id string) error { } // UpdateClient changes an oauth2 client by id using an updater function and saves it to the database. -func (d *Database) UpdateClient(id string, updater func(old storage.Client) (storage.Client, error)) error { - tx, err := d.BeginTx(context.TODO()) +func (d *Database) UpdateClient(ctx context.Context, id string, updater func(old storage.Client) (storage.Client, error)) error { + tx, err := d.BeginTx(ctx) if err != nil { return convertDBError("update client tx: %w", err) } - client, err := tx.OAuth2Client.Get(context.TODO(), id) + client, err := tx.OAuth2Client.Get(ctx, id) if err != nil { return rollback(tx, "update client database: %w", err) } @@ -79,7 +79,7 @@ func (d *Database) UpdateClient(id string, updater func(old storage.Client) (sto SetLogoURL(newClient.LogoURL). SetRedirectUris(newClient.RedirectURIs). SetTrustedPeers(newClient.TrustedPeers). - Save(context.TODO()) + Save(ctx) if err != nil { return rollback(tx, "update client uploading: %w", err) } diff --git a/storage/ent/client/connector.go b/storage/ent/client/connector.go index bfec4418dd..f0cff8ba6a 100644 --- a/storage/ent/client/connector.go +++ b/storage/ent/client/connector.go @@ -7,14 +7,14 @@ import ( ) // CreateConnector saves a connector into the database. -func (d *Database) CreateConnector(connector storage.Connector) error { +func (d *Database) CreateConnector(ctx context.Context, connector storage.Connector) error { _, err := d.client.Connector.Create(). SetID(connector.ID). SetName(connector.Name). SetType(connector.Type). SetResourceVersion(connector.ResourceVersion). SetConfig(connector.Config). - Save(context.TODO()) + Save(ctx) if err != nil { return convertDBError("create connector: %w", err) } @@ -22,8 +22,8 @@ func (d *Database) CreateConnector(connector storage.Connector) error { } // ListConnectors extracts an array of connectors from the database. -func (d *Database) ListConnectors() ([]storage.Connector, error) { - connectors, err := d.client.Connector.Query().All(context.TODO()) +func (d *Database) ListConnectors(ctx context.Context) ([]storage.Connector, error) { + connectors, err := d.client.Connector.Query().All(ctx) if err != nil { return nil, convertDBError("list connectors: %w", err) } @@ -36,8 +36,8 @@ func (d *Database) ListConnectors() ([]storage.Connector, error) { } // GetConnector extracts a connector from the database by id. -func (d *Database) GetConnector(id string) (storage.Connector, error) { - connector, err := d.client.Connector.Get(context.TODO(), id) +func (d *Database) GetConnector(ctx context.Context, id string) (storage.Connector, error) { + connector, err := d.client.Connector.Get(ctx, id) if err != nil { return storage.Connector{}, convertDBError("get connector: %w", err) } @@ -45,8 +45,8 @@ func (d *Database) GetConnector(id string) (storage.Connector, error) { } // DeleteConnector deletes a connector from the database by id. -func (d *Database) DeleteConnector(id string) error { - err := d.client.Connector.DeleteOneID(id).Exec(context.TODO()) +func (d *Database) DeleteConnector(ctx context.Context, id string) error { + err := d.client.Connector.DeleteOneID(id).Exec(ctx) if err != nil { return convertDBError("delete connector: %w", err) } @@ -54,13 +54,13 @@ func (d *Database) DeleteConnector(id string) error { } // UpdateConnector changes a connector by id using an updater function and saves it to the database. -func (d *Database) UpdateConnector(id string, updater func(old storage.Connector) (storage.Connector, error)) error { - tx, err := d.BeginTx(context.TODO()) +func (d *Database) UpdateConnector(ctx context.Context, id string, updater func(old storage.Connector) (storage.Connector, error)) error { + tx, err := d.BeginTx(ctx) if err != nil { return convertDBError("update connector tx: %w", err) } - connector, err := tx.Connector.Get(context.TODO(), id) + connector, err := tx.Connector.Get(ctx, id) if err != nil { return rollback(tx, "update connector database: %w", err) } @@ -75,7 +75,7 @@ func (d *Database) UpdateConnector(id string, updater func(old storage.Connector SetType(newConnector.Type). SetResourceVersion(newConnector.ResourceVersion). SetConfig(newConnector.Config). - Save(context.TODO()) + Save(ctx) if err != nil { return rollback(tx, "update connector uploading: %w", err) } diff --git a/storage/ent/client/devicerequest.go b/storage/ent/client/devicerequest.go index 6e9c25001d..5673395567 100644 --- a/storage/ent/client/devicerequest.go +++ b/storage/ent/client/devicerequest.go @@ -8,7 +8,7 @@ import ( ) // CreateDeviceRequest saves provided device request into the database. -func (d *Database) CreateDeviceRequest(request storage.DeviceRequest) error { +func (d *Database) CreateDeviceRequest(ctx context.Context, request storage.DeviceRequest) error { _, err := d.client.DeviceRequest.Create(). SetClientID(request.ClientID). SetClientSecret(request.ClientSecret). @@ -17,7 +17,7 @@ func (d *Database) CreateDeviceRequest(request storage.DeviceRequest) error { SetDeviceCode(request.DeviceCode). // Save utc time into database because ent doesn't support comparing dates with different timezones SetExpiry(request.Expiry.UTC()). - Save(context.TODO()) + Save(ctx) if err != nil { return convertDBError("create device request: %w", err) } @@ -25,10 +25,10 @@ func (d *Database) CreateDeviceRequest(request storage.DeviceRequest) error { } // GetDeviceRequest extracts a device request from the database by user code. -func (d *Database) GetDeviceRequest(userCode string) (storage.DeviceRequest, error) { +func (d *Database) GetDeviceRequest(ctx context.Context, userCode string) (storage.DeviceRequest, error) { deviceRequest, err := d.client.DeviceRequest.Query(). Where(devicerequest.UserCode(userCode)). - Only(context.TODO()) + Only(ctx) if err != nil { return storage.DeviceRequest{}, convertDBError("get device request: %w", err) } diff --git a/storage/ent/client/devicetoken.go b/storage/ent/client/devicetoken.go index 99cf077d02..759812b196 100644 --- a/storage/ent/client/devicetoken.go +++ b/storage/ent/client/devicetoken.go @@ -8,7 +8,7 @@ import ( ) // CreateDeviceToken saves provided token into the database. -func (d *Database) CreateDeviceToken(token storage.DeviceToken) error { +func (d *Database) CreateDeviceToken(ctx context.Context, token storage.DeviceToken) error { _, err := d.client.DeviceToken.Create(). SetDeviceCode(token.DeviceCode). SetToken([]byte(token.Token)). @@ -19,7 +19,7 @@ func (d *Database) CreateDeviceToken(token storage.DeviceToken) error { SetStatus(token.Status). SetCodeChallenge(token.PKCE.CodeChallenge). SetCodeChallengeMethod(token.PKCE.CodeChallengeMethod). - Save(context.TODO()) + Save(ctx) if err != nil { return convertDBError("create device token: %w", err) } @@ -27,10 +27,10 @@ func (d *Database) CreateDeviceToken(token storage.DeviceToken) error { } // GetDeviceToken extracts a token from the database by device code. -func (d *Database) GetDeviceToken(deviceCode string) (storage.DeviceToken, error) { +func (d *Database) GetDeviceToken(ctx context.Context, deviceCode string) (storage.DeviceToken, error) { deviceToken, err := d.client.DeviceToken.Query(). Where(devicetoken.DeviceCode(deviceCode)). - Only(context.TODO()) + Only(ctx) if err != nil { return storage.DeviceToken{}, convertDBError("get device token: %w", err) } @@ -38,15 +38,15 @@ func (d *Database) GetDeviceToken(deviceCode string) (storage.DeviceToken, error } // UpdateDeviceToken changes a token by device code using an updater function and saves it to the database. -func (d *Database) UpdateDeviceToken(deviceCode string, updater func(old storage.DeviceToken) (storage.DeviceToken, error)) error { - tx, err := d.BeginTx(context.TODO()) +func (d *Database) UpdateDeviceToken(ctx context.Context, deviceCode string, updater func(old storage.DeviceToken) (storage.DeviceToken, error)) error { + tx, err := d.BeginTx(ctx) if err != nil { return convertDBError("update device token tx: %w", err) } token, err := tx.DeviceToken.Query(). Where(devicetoken.DeviceCode(deviceCode)). - Only(context.TODO()) + Only(ctx) if err != nil { return rollback(tx, "update device token database: %w", err) } @@ -67,7 +67,7 @@ func (d *Database) UpdateDeviceToken(deviceCode string, updater func(old storage SetStatus(newToken.Status). SetCodeChallenge(newToken.PKCE.CodeChallenge). SetCodeChallengeMethod(newToken.PKCE.CodeChallengeMethod). - Save(context.TODO()) + Save(ctx) if err != nil { return rollback(tx, "update device token uploading: %w", err) } diff --git a/storage/ent/client/keys.go b/storage/ent/client/keys.go index f65d40fc21..c4e972026f 100644 --- a/storage/ent/client/keys.go +++ b/storage/ent/client/keys.go @@ -8,8 +8,8 @@ import ( "github.com/dexidp/dex/storage/ent/db" ) -func getKeys(client *db.KeysClient) (storage.Keys, error) { - rawKeys, err := client.Get(context.TODO(), keysRowID) +func getKeys(ctx context.Context, client *db.KeysClient) (storage.Keys, error) { + rawKeys, err := client.Get(ctx, keysRowID) if err != nil { return storage.Keys{}, convertDBError("get keys: %w", err) } @@ -18,20 +18,20 @@ func getKeys(client *db.KeysClient) (storage.Keys, error) { } // GetKeys returns signing keys, public keys and verification keys from the database. -func (d *Database) GetKeys() (storage.Keys, error) { - return getKeys(d.client.Keys) +func (d *Database) GetKeys(ctx context.Context) (storage.Keys, error) { + return getKeys(ctx, d.client.Keys) } // UpdateKeys rotates keys using updater function. -func (d *Database) UpdateKeys(updater func(old storage.Keys) (storage.Keys, error)) error { +func (d *Database) UpdateKeys(ctx context.Context, updater func(old storage.Keys) (storage.Keys, error)) error { firstUpdate := false - tx, err := d.BeginTx(context.TODO()) + tx, err := d.BeginTx(ctx) if err != nil { return convertDBError("update keys tx: %w", err) } - storageKeys, err := getKeys(tx.Keys) + storageKeys, err := getKeys(ctx, tx.Keys) if err != nil { if !errors.Is(err, storage.ErrNotFound) { return rollback(tx, "update keys get: %w", err) @@ -53,7 +53,7 @@ func (d *Database) UpdateKeys(updater func(old storage.Keys) (storage.Keys, erro SetSigningKey(*newKeys.SigningKey). SetSigningKeyPub(*newKeys.SigningKeyPub). SetVerificationKeys(newKeys.VerificationKeys). - Save(context.TODO()) + Save(ctx) if err != nil { return rollback(tx, "create keys: %w", err) } @@ -68,7 +68,7 @@ func (d *Database) UpdateKeys(updater func(old storage.Keys) (storage.Keys, erro SetSigningKey(*newKeys.SigningKey). SetSigningKeyPub(*newKeys.SigningKeyPub). SetVerificationKeys(newKeys.VerificationKeys). - Exec(context.TODO()) + Exec(ctx) if err != nil { return rollback(tx, "update keys uploading: %w", err) } diff --git a/storage/ent/client/main.go b/storage/ent/client/main.go index bc4c1600ac..a78830fc76 100644 --- a/storage/ent/client/main.go +++ b/storage/ent/client/main.go @@ -70,13 +70,13 @@ func (d *Database) BeginTx(ctx context.Context) (*db.Tx, error) { } // GarbageCollect removes expired entities from the database. -func (d *Database) GarbageCollect(now time.Time) (storage.GCResult, error) { +func (d *Database) GarbageCollect(ctx context.Context, now time.Time) (storage.GCResult, error) { result := storage.GCResult{} utcNow := now.UTC() q, err := d.client.AuthRequest.Delete(). Where(authrequest.ExpiryLT(utcNow)). - Exec(context.TODO()) + Exec(ctx) if err != nil { return result, convertDBError("gc auth request: %w", err) } @@ -84,7 +84,7 @@ func (d *Database) GarbageCollect(now time.Time) (storage.GCResult, error) { q, err = d.client.AuthCode.Delete(). Where(authcode.ExpiryLT(utcNow)). - Exec(context.TODO()) + Exec(ctx) if err != nil { return result, convertDBError("gc auth code: %w", err) } @@ -92,7 +92,7 @@ func (d *Database) GarbageCollect(now time.Time) (storage.GCResult, error) { q, err = d.client.DeviceRequest.Delete(). Where(devicerequest.ExpiryLT(utcNow)). - Exec(context.TODO()) + Exec(ctx) if err != nil { return result, convertDBError("gc device request: %w", err) } @@ -100,7 +100,7 @@ func (d *Database) GarbageCollect(now time.Time) (storage.GCResult, error) { q, err = d.client.DeviceToken.Delete(). Where(devicetoken.ExpiryLT(utcNow)). - Exec(context.TODO()) + Exec(ctx) if err != nil { return result, convertDBError("gc device token: %w", err) } diff --git a/storage/ent/client/offlinesession.go b/storage/ent/client/offlinesession.go index 9f54ea1d3c..9d608cb6f3 100644 --- a/storage/ent/client/offlinesession.go +++ b/storage/ent/client/offlinesession.go @@ -9,7 +9,7 @@ import ( ) // CreateOfflineSessions saves provided offline session into the database. -func (d *Database) CreateOfflineSessions(session storage.OfflineSessions) error { +func (d *Database) CreateOfflineSessions(ctx context.Context, session storage.OfflineSessions) error { encodedRefresh, err := json.Marshal(session.Refresh) if err != nil { return fmt.Errorf("encode refresh offline session: %w", err) @@ -22,7 +22,7 @@ func (d *Database) CreateOfflineSessions(session storage.OfflineSessions) error SetConnID(session.ConnID). SetConnectorData(session.ConnectorData). SetRefresh(encodedRefresh). - Save(context.TODO()) + Save(ctx) if err != nil { return convertDBError("create offline session: %w", err) } @@ -30,10 +30,10 @@ func (d *Database) CreateOfflineSessions(session storage.OfflineSessions) error } // GetOfflineSessions extracts an offline session from the database by user id and connector id. -func (d *Database) GetOfflineSessions(userID, connID string) (storage.OfflineSessions, error) { +func (d *Database) GetOfflineSessions(ctx context.Context, userID, connID string) (storage.OfflineSessions, error) { id := offlineSessionID(userID, connID, d.hasher) - offlineSession, err := d.client.OfflineSession.Get(context.TODO(), id) + offlineSession, err := d.client.OfflineSession.Get(ctx, id) if err != nil { return storage.OfflineSessions{}, convertDBError("get offline session: %w", err) } @@ -41,10 +41,10 @@ func (d *Database) GetOfflineSessions(userID, connID string) (storage.OfflineSes } // DeleteOfflineSessions deletes an offline session from the database by user id and connector id. -func (d *Database) DeleteOfflineSessions(userID, connID string) error { +func (d *Database) DeleteOfflineSessions(ctx context.Context, userID, connID string) error { id := offlineSessionID(userID, connID, d.hasher) - err := d.client.OfflineSession.DeleteOneID(id).Exec(context.TODO()) + err := d.client.OfflineSession.DeleteOneID(id).Exec(ctx) if err != nil { return convertDBError("delete offline session: %w", err) } @@ -52,15 +52,15 @@ func (d *Database) DeleteOfflineSessions(userID, connID string) error { } // UpdateOfflineSessions changes an offline session by user id and connector id using an updater function. -func (d *Database) UpdateOfflineSessions(userID string, connID string, updater func(s storage.OfflineSessions) (storage.OfflineSessions, error)) error { +func (d *Database) UpdateOfflineSessions(ctx context.Context, userID string, connID string, updater func(s storage.OfflineSessions) (storage.OfflineSessions, error)) error { id := offlineSessionID(userID, connID, d.hasher) - tx, err := d.BeginTx(context.TODO()) + tx, err := d.BeginTx(ctx) if err != nil { return convertDBError("update offline session tx: %w", err) } - offlineSession, err := tx.OfflineSession.Get(context.TODO(), id) + offlineSession, err := tx.OfflineSession.Get(ctx, id) if err != nil { return rollback(tx, "update offline session database: %w", err) } @@ -80,7 +80,7 @@ func (d *Database) UpdateOfflineSessions(userID string, connID string, updater f SetConnID(newOfflineSession.ConnID). SetConnectorData(newOfflineSession.ConnectorData). SetRefresh(encodedRefresh). - Save(context.TODO()) + Save(ctx) if err != nil { return rollback(tx, "update offline session uploading: %w", err) } diff --git a/storage/ent/client/password.go b/storage/ent/client/password.go index daaae30cea..2845fa8f76 100644 --- a/storage/ent/client/password.go +++ b/storage/ent/client/password.go @@ -9,13 +9,13 @@ import ( ) // CreatePassword saves provided password into the database. -func (d *Database) CreatePassword(password storage.Password) error { +func (d *Database) CreatePassword(ctx context.Context, password storage.Password) error { _, err := d.client.Password.Create(). SetEmail(password.Email). SetHash(password.Hash). SetUsername(password.Username). SetUserID(password.UserID). - Save(context.TODO()) + Save(ctx) if err != nil { return convertDBError("create password: %w", err) } @@ -23,8 +23,8 @@ func (d *Database) CreatePassword(password storage.Password) error { } // ListPasswords extracts an array of passwords from the database. -func (d *Database) ListPasswords() ([]storage.Password, error) { - passwords, err := d.client.Password.Query().All(context.TODO()) +func (d *Database) ListPasswords(ctx context.Context) ([]storage.Password, error) { + passwords, err := d.client.Password.Query().All(ctx) if err != nil { return nil, convertDBError("list passwords: %w", err) } @@ -37,11 +37,11 @@ func (d *Database) ListPasswords() ([]storage.Password, error) { } // GetPassword extracts a password from the database by email. -func (d *Database) GetPassword(email string) (storage.Password, error) { +func (d *Database) GetPassword(ctx context.Context, email string) (storage.Password, error) { email = strings.ToLower(email) passwordFromStorage, err := d.client.Password.Query(). Where(password.Email(email)). - Only(context.TODO()) + Only(ctx) if err != nil { return storage.Password{}, convertDBError("get password: %w", err) } @@ -49,11 +49,11 @@ func (d *Database) GetPassword(email string) (storage.Password, error) { } // DeletePassword deletes a password from the database by email. -func (d *Database) DeletePassword(email string) error { +func (d *Database) DeletePassword(ctx context.Context, email string) error { email = strings.ToLower(email) _, err := d.client.Password.Delete(). Where(password.Email(email)). - Exec(context.TODO()) + Exec(ctx) if err != nil { return convertDBError("delete password: %w", err) } @@ -61,17 +61,17 @@ func (d *Database) DeletePassword(email string) error { } // UpdatePassword changes a password by email using an updater function and saves it to the database. -func (d *Database) UpdatePassword(email string, updater func(old storage.Password) (storage.Password, error)) error { +func (d *Database) UpdatePassword(ctx context.Context, email string, updater func(old storage.Password) (storage.Password, error)) error { email = strings.ToLower(email) - tx, err := d.BeginTx(context.TODO()) + tx, err := d.BeginTx(ctx) if err != nil { return convertDBError("update connector tx: %w", err) } passwordToUpdate, err := tx.Password.Query(). Where(password.Email(email)). - Only(context.TODO()) + Only(ctx) if err != nil { return rollback(tx, "update password database: %w", err) } @@ -87,7 +87,7 @@ func (d *Database) UpdatePassword(email string, updater func(old storage.Passwor SetHash(newPassword.Hash). SetUsername(newPassword.Username). SetUserID(newPassword.UserID). - Save(context.TODO()) + Save(ctx) if err != nil { return rollback(tx, "update password uploading: %w", err) } diff --git a/storage/ent/client/refreshtoken.go b/storage/ent/client/refreshtoken.go index eca048f463..d423565439 100644 --- a/storage/ent/client/refreshtoken.go +++ b/storage/ent/client/refreshtoken.go @@ -7,7 +7,7 @@ import ( ) // CreateRefresh saves provided refresh token into the database. -func (d *Database) CreateRefresh(refresh storage.RefreshToken) error { +func (d *Database) CreateRefresh(ctx context.Context, refresh storage.RefreshToken) error { _, err := d.client.RefreshToken.Create(). SetID(refresh.ID). SetClientID(refresh.ClientID). @@ -26,7 +26,7 @@ func (d *Database) CreateRefresh(refresh storage.RefreshToken) error { // Save utc time into database because ent doesn't support comparing dates with different timezones SetLastUsed(refresh.LastUsed.UTC()). SetCreatedAt(refresh.CreatedAt.UTC()). - Save(context.TODO()) + Save(ctx) if err != nil { return convertDBError("create refresh token: %w", err) } @@ -34,8 +34,8 @@ func (d *Database) CreateRefresh(refresh storage.RefreshToken) error { } // ListRefreshTokens extracts an array of refresh tokens from the database. -func (d *Database) ListRefreshTokens() ([]storage.RefreshToken, error) { - refreshTokens, err := d.client.RefreshToken.Query().All(context.TODO()) +func (d *Database) ListRefreshTokens(ctx context.Context) ([]storage.RefreshToken, error) { + refreshTokens, err := d.client.RefreshToken.Query().All(ctx) if err != nil { return nil, convertDBError("list refresh tokens: %w", err) } @@ -48,8 +48,8 @@ func (d *Database) ListRefreshTokens() ([]storage.RefreshToken, error) { } // GetRefresh extracts a refresh token from the database by id. -func (d *Database) GetRefresh(id string) (storage.RefreshToken, error) { - refreshToken, err := d.client.RefreshToken.Get(context.TODO(), id) +func (d *Database) GetRefresh(ctx context.Context, id string) (storage.RefreshToken, error) { + refreshToken, err := d.client.RefreshToken.Get(ctx, id) if err != nil { return storage.RefreshToken{}, convertDBError("get refresh token: %w", err) } @@ -57,8 +57,8 @@ func (d *Database) GetRefresh(id string) (storage.RefreshToken, error) { } // DeleteRefresh deletes a refresh token from the database by id. -func (d *Database) DeleteRefresh(id string) error { - err := d.client.RefreshToken.DeleteOneID(id).Exec(context.TODO()) +func (d *Database) DeleteRefresh(ctx context.Context, id string) error { + err := d.client.RefreshToken.DeleteOneID(id).Exec(ctx) if err != nil { return convertDBError("delete refresh token: %w", err) } @@ -66,13 +66,13 @@ func (d *Database) DeleteRefresh(id string) error { } // UpdateRefreshToken changes a refresh token by id using an updater function and saves it to the database. -func (d *Database) UpdateRefreshToken(id string, updater func(old storage.RefreshToken) (storage.RefreshToken, error)) error { - tx, err := d.BeginTx(context.TODO()) +func (d *Database) UpdateRefreshToken(ctx context.Context, id string, updater func(old storage.RefreshToken) (storage.RefreshToken, error)) error { + tx, err := d.BeginTx(ctx) if err != nil { return convertDBError("update refresh token tx: %w", err) } - token, err := tx.RefreshToken.Get(context.TODO(), id) + token, err := tx.RefreshToken.Get(ctx, id) if err != nil { return rollback(tx, "update refresh token database: %w", err) } @@ -99,7 +99,7 @@ func (d *Database) UpdateRefreshToken(id string, updater func(old storage.Refres // Save utc time into database because ent doesn't support comparing dates with different timezones SetLastUsed(newtToken.LastUsed.UTC()). SetCreatedAt(newtToken.CreatedAt.UTC()). - Save(context.TODO()) + Save(ctx) if err != nil { return rollback(tx, "update refresh token uploading: %w", err) } diff --git a/storage/ent/client/types.go b/storage/ent/client/types.go index 256bb73dcb..397d4d30a2 100644 --- a/storage/ent/client/types.go +++ b/storage/ent/client/types.go @@ -45,6 +45,7 @@ func toStorageAuthRequest(a *db.AuthRequest) storage.AuthRequest { CodeChallenge: a.CodeChallenge, CodeChallengeMethod: a.CodeChallengeMethod, }, + HMACKey: a.HmacKey, } } diff --git a/storage/ent/db/authcode.go b/storage/ent/db/authcode.go index 6ddbeb57dc..06ad7c8cdf 100644 --- a/storage/ent/db/authcode.go +++ b/storage/ent/db/authcode.go @@ -8,6 +8,7 @@ import ( "strings" "time" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/dexidp/dex/storage/ent/db/authcode" ) @@ -47,11 +48,12 @@ type AuthCode struct { CodeChallenge string `json:"code_challenge,omitempty"` // CodeChallengeMethod holds the value of the "code_challenge_method" field. CodeChallengeMethod string `json:"code_challenge_method,omitempty"` + selectValues sql.SelectValues } // scanValues returns the types for scanning values from sql.Rows. -func (*AuthCode) scanValues(columns []string) ([]interface{}, error) { - values := make([]interface{}, len(columns)) +func (*AuthCode) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) for i := range columns { switch columns[i] { case authcode.FieldScopes, authcode.FieldClaimsGroups, authcode.FieldConnectorData: @@ -63,7 +65,7 @@ func (*AuthCode) scanValues(columns []string) ([]interface{}, error) { case authcode.FieldExpiry: values[i] = new(sql.NullTime) default: - return nil, fmt.Errorf("unexpected column %q for type AuthCode", columns[i]) + values[i] = new(sql.UnknownType) } } return values, nil @@ -71,7 +73,7 @@ func (*AuthCode) scanValues(columns []string) ([]interface{}, error) { // assignValues assigns the values that were returned from sql.Rows (after scanning) // to the AuthCode fields. -func (ac *AuthCode) assignValues(columns []string, values []interface{}) error { +func (_m *AuthCode) assignValues(columns []string, values []any) error { if m, n := len(values), len(columns); m < n { return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) } @@ -81,19 +83,19 @@ func (ac *AuthCode) assignValues(columns []string, values []interface{}) error { if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field id", values[i]) } else if value.Valid { - ac.ID = value.String + _m.ID = value.String } case authcode.FieldClientID: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field client_id", values[i]) } else if value.Valid { - ac.ClientID = value.String + _m.ClientID = value.String } case authcode.FieldScopes: if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field scopes", values[i]) } else if value != nil && len(*value) > 0 { - if err := json.Unmarshal(*value, &ac.Scopes); err != nil { + if err := json.Unmarshal(*value, &_m.Scopes); err != nil { return fmt.Errorf("unmarshal field scopes: %w", err) } } @@ -101,43 +103,43 @@ func (ac *AuthCode) assignValues(columns []string, values []interface{}) error { if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field nonce", values[i]) } else if value.Valid { - ac.Nonce = value.String + _m.Nonce = value.String } case authcode.FieldRedirectURI: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field redirect_uri", values[i]) } else if value.Valid { - ac.RedirectURI = value.String + _m.RedirectURI = value.String } case authcode.FieldClaimsUserID: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field claims_user_id", values[i]) } else if value.Valid { - ac.ClaimsUserID = value.String + _m.ClaimsUserID = value.String } case authcode.FieldClaimsUsername: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field claims_username", values[i]) } else if value.Valid { - ac.ClaimsUsername = value.String + _m.ClaimsUsername = value.String } case authcode.FieldClaimsEmail: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field claims_email", values[i]) } else if value.Valid { - ac.ClaimsEmail = value.String + _m.ClaimsEmail = value.String } case authcode.FieldClaimsEmailVerified: if value, ok := values[i].(*sql.NullBool); !ok { return fmt.Errorf("unexpected type %T for field claims_email_verified", values[i]) } else if value.Valid { - ac.ClaimsEmailVerified = value.Bool + _m.ClaimsEmailVerified = value.Bool } case authcode.FieldClaimsGroups: if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field claims_groups", values[i]) } else if value != nil && len(*value) > 0 { - if err := json.Unmarshal(*value, &ac.ClaimsGroups); err != nil { + if err := json.Unmarshal(*value, &_m.ClaimsGroups); err != nil { return fmt.Errorf("unmarshal field claims_groups: %w", err) } } @@ -145,121 +147,123 @@ func (ac *AuthCode) assignValues(columns []string, values []interface{}) error { if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field claims_preferred_username", values[i]) } else if value.Valid { - ac.ClaimsPreferredUsername = value.String + _m.ClaimsPreferredUsername = value.String } case authcode.FieldConnectorID: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field connector_id", values[i]) } else if value.Valid { - ac.ConnectorID = value.String + _m.ConnectorID = value.String } case authcode.FieldConnectorData: if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field connector_data", values[i]) } else if value != nil { - ac.ConnectorData = value + _m.ConnectorData = value } case authcode.FieldExpiry: if value, ok := values[i].(*sql.NullTime); !ok { return fmt.Errorf("unexpected type %T for field expiry", values[i]) } else if value.Valid { - ac.Expiry = value.Time + _m.Expiry = value.Time } case authcode.FieldCodeChallenge: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field code_challenge", values[i]) } else if value.Valid { - ac.CodeChallenge = value.String + _m.CodeChallenge = value.String } case authcode.FieldCodeChallengeMethod: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field code_challenge_method", values[i]) } else if value.Valid { - ac.CodeChallengeMethod = value.String + _m.CodeChallengeMethod = value.String } + default: + _m.selectValues.Set(columns[i], values[i]) } } return nil } +// Value returns the ent.Value that was dynamically selected and assigned to the AuthCode. +// This includes values selected through modifiers, order, etc. +func (_m *AuthCode) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + // Update returns a builder for updating this AuthCode. // Note that you need to call AuthCode.Unwrap() before calling this method if this AuthCode // was returned from a transaction, and the transaction was committed or rolled back. -func (ac *AuthCode) Update() *AuthCodeUpdateOne { - return (&AuthCodeClient{config: ac.config}).UpdateOne(ac) +func (_m *AuthCode) Update() *AuthCodeUpdateOne { + return NewAuthCodeClient(_m.config).UpdateOne(_m) } // Unwrap unwraps the AuthCode entity that was returned from a transaction after it was closed, // so that all future queries will be executed through the driver which created the transaction. -func (ac *AuthCode) Unwrap() *AuthCode { - _tx, ok := ac.config.driver.(*txDriver) +func (_m *AuthCode) Unwrap() *AuthCode { + _tx, ok := _m.config.driver.(*txDriver) if !ok { panic("db: AuthCode is not a transactional entity") } - ac.config.driver = _tx.drv - return ac + _m.config.driver = _tx.drv + return _m } // String implements the fmt.Stringer. -func (ac *AuthCode) String() string { +func (_m *AuthCode) String() string { var builder strings.Builder builder.WriteString("AuthCode(") - builder.WriteString(fmt.Sprintf("id=%v, ", ac.ID)) + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) builder.WriteString("client_id=") - builder.WriteString(ac.ClientID) + builder.WriteString(_m.ClientID) builder.WriteString(", ") builder.WriteString("scopes=") - builder.WriteString(fmt.Sprintf("%v", ac.Scopes)) + builder.WriteString(fmt.Sprintf("%v", _m.Scopes)) builder.WriteString(", ") builder.WriteString("nonce=") - builder.WriteString(ac.Nonce) + builder.WriteString(_m.Nonce) builder.WriteString(", ") builder.WriteString("redirect_uri=") - builder.WriteString(ac.RedirectURI) + builder.WriteString(_m.RedirectURI) builder.WriteString(", ") builder.WriteString("claims_user_id=") - builder.WriteString(ac.ClaimsUserID) + builder.WriteString(_m.ClaimsUserID) builder.WriteString(", ") builder.WriteString("claims_username=") - builder.WriteString(ac.ClaimsUsername) + builder.WriteString(_m.ClaimsUsername) builder.WriteString(", ") builder.WriteString("claims_email=") - builder.WriteString(ac.ClaimsEmail) + builder.WriteString(_m.ClaimsEmail) builder.WriteString(", ") builder.WriteString("claims_email_verified=") - builder.WriteString(fmt.Sprintf("%v", ac.ClaimsEmailVerified)) + builder.WriteString(fmt.Sprintf("%v", _m.ClaimsEmailVerified)) builder.WriteString(", ") builder.WriteString("claims_groups=") - builder.WriteString(fmt.Sprintf("%v", ac.ClaimsGroups)) + builder.WriteString(fmt.Sprintf("%v", _m.ClaimsGroups)) builder.WriteString(", ") builder.WriteString("claims_preferred_username=") - builder.WriteString(ac.ClaimsPreferredUsername) + builder.WriteString(_m.ClaimsPreferredUsername) builder.WriteString(", ") builder.WriteString("connector_id=") - builder.WriteString(ac.ConnectorID) + builder.WriteString(_m.ConnectorID) builder.WriteString(", ") - if v := ac.ConnectorData; v != nil { + if v := _m.ConnectorData; v != nil { builder.WriteString("connector_data=") builder.WriteString(fmt.Sprintf("%v", *v)) } builder.WriteString(", ") builder.WriteString("expiry=") - builder.WriteString(ac.Expiry.Format(time.ANSIC)) + builder.WriteString(_m.Expiry.Format(time.ANSIC)) builder.WriteString(", ") builder.WriteString("code_challenge=") - builder.WriteString(ac.CodeChallenge) + builder.WriteString(_m.CodeChallenge) builder.WriteString(", ") builder.WriteString("code_challenge_method=") - builder.WriteString(ac.CodeChallengeMethod) + builder.WriteString(_m.CodeChallengeMethod) builder.WriteByte(')') return builder.String() } // AuthCodes is a parsable slice of AuthCode. type AuthCodes []*AuthCode - -func (ac AuthCodes) config(cfg config) { - for _i := range ac { - ac[_i].config = cfg - } -} diff --git a/storage/ent/db/authcode/authcode.go b/storage/ent/db/authcode/authcode.go index b78eb97027..6e056f159c 100644 --- a/storage/ent/db/authcode/authcode.go +++ b/storage/ent/db/authcode/authcode.go @@ -2,6 +2,10 @@ package authcode +import ( + "entgo.io/ent/dialect/sql" +) + const ( // Label holds the string label denoting the authcode type in the database. Label = "auth_code" @@ -95,3 +99,71 @@ var ( // IDValidator is a validator for the "id" field. It is called by the builders before save. IDValidator func(string) error ) + +// OrderOption defines the ordering options for the AuthCode queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByClientID orders the results by the client_id field. +func ByClientID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClientID, opts...).ToFunc() +} + +// ByNonce orders the results by the nonce field. +func ByNonce(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldNonce, opts...).ToFunc() +} + +// ByRedirectURI orders the results by the redirect_uri field. +func ByRedirectURI(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldRedirectURI, opts...).ToFunc() +} + +// ByClaimsUserID orders the results by the claims_user_id field. +func ByClaimsUserID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClaimsUserID, opts...).ToFunc() +} + +// ByClaimsUsername orders the results by the claims_username field. +func ByClaimsUsername(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClaimsUsername, opts...).ToFunc() +} + +// ByClaimsEmail orders the results by the claims_email field. +func ByClaimsEmail(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClaimsEmail, opts...).ToFunc() +} + +// ByClaimsEmailVerified orders the results by the claims_email_verified field. +func ByClaimsEmailVerified(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClaimsEmailVerified, opts...).ToFunc() +} + +// ByClaimsPreferredUsername orders the results by the claims_preferred_username field. +func ByClaimsPreferredUsername(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClaimsPreferredUsername, opts...).ToFunc() +} + +// ByConnectorID orders the results by the connector_id field. +func ByConnectorID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldConnectorID, opts...).ToFunc() +} + +// ByExpiry orders the results by the expiry field. +func ByExpiry(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldExpiry, opts...).ToFunc() +} + +// ByCodeChallenge orders the results by the code_challenge field. +func ByCodeChallenge(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldCodeChallenge, opts...).ToFunc() +} + +// ByCodeChallengeMethod orders the results by the code_challenge_method field. +func ByCodeChallengeMethod(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldCodeChallengeMethod, opts...).ToFunc() +} diff --git a/storage/ent/db/authcode/where.go b/storage/ent/db/authcode/where.go index be1954d7bb..f8673fb039 100644 --- a/storage/ent/db/authcode/where.go +++ b/storage/ent/db/authcode/where.go @@ -11,1368 +11,905 @@ import ( // ID filters vertices based on their ID field. func ID(id string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldID, id)) } // IDEQ applies the EQ predicate on the ID field. func IDEQ(id string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldID, id)) } // IDNEQ applies the NEQ predicate on the ID field. func IDNEQ(id string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldID), id)) - }) + return predicate.AuthCode(sql.FieldNEQ(FieldID, id)) } // IDIn applies the In predicate on the ID field. func IDIn(ids ...string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.In(s.C(FieldID), v...)) - }) + return predicate.AuthCode(sql.FieldIn(FieldID, ids...)) } // IDNotIn applies the NotIn predicate on the ID field. func IDNotIn(ids ...string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.NotIn(s.C(FieldID), v...)) - }) + return predicate.AuthCode(sql.FieldNotIn(FieldID, ids...)) } // IDGT applies the GT predicate on the ID field. func IDGT(id string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldID), id)) - }) + return predicate.AuthCode(sql.FieldGT(FieldID, id)) } // IDGTE applies the GTE predicate on the ID field. func IDGTE(id string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldID), id)) - }) + return predicate.AuthCode(sql.FieldGTE(FieldID, id)) } // IDLT applies the LT predicate on the ID field. func IDLT(id string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldID), id)) - }) + return predicate.AuthCode(sql.FieldLT(FieldID, id)) } // IDLTE applies the LTE predicate on the ID field. func IDLTE(id string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldID), id)) - }) + return predicate.AuthCode(sql.FieldLTE(FieldID, id)) +} + +// IDEqualFold applies the EqualFold predicate on the ID field. +func IDEqualFold(id string) predicate.AuthCode { + return predicate.AuthCode(sql.FieldEqualFold(FieldID, id)) +} + +// IDContainsFold applies the ContainsFold predicate on the ID field. +func IDContainsFold(id string) predicate.AuthCode { + return predicate.AuthCode(sql.FieldContainsFold(FieldID, id)) } // ClientID applies equality check predicate on the "client_id" field. It's identical to ClientIDEQ. func ClientID(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClientID), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldClientID, v)) } // Nonce applies equality check predicate on the "nonce" field. It's identical to NonceEQ. func Nonce(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldNonce), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldNonce, v)) } // RedirectURI applies equality check predicate on the "redirect_uri" field. It's identical to RedirectURIEQ. func RedirectURI(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldRedirectURI, v)) } // ClaimsUserID applies equality check predicate on the "claims_user_id" field. It's identical to ClaimsUserIDEQ. func ClaimsUserID(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldClaimsUserID, v)) } // ClaimsUsername applies equality check predicate on the "claims_username" field. It's identical to ClaimsUsernameEQ. func ClaimsUsername(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldClaimsUsername, v)) } // ClaimsEmail applies equality check predicate on the "claims_email" field. It's identical to ClaimsEmailEQ. func ClaimsEmail(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldClaimsEmail, v)) } // ClaimsEmailVerified applies equality check predicate on the "claims_email_verified" field. It's identical to ClaimsEmailVerifiedEQ. func ClaimsEmailVerified(v bool) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsEmailVerified), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldClaimsEmailVerified, v)) } // ClaimsPreferredUsername applies equality check predicate on the "claims_preferred_username" field. It's identical to ClaimsPreferredUsernameEQ. func ClaimsPreferredUsername(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldClaimsPreferredUsername, v)) } // ConnectorID applies equality check predicate on the "connector_id" field. It's identical to ConnectorIDEQ. func ConnectorID(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldConnectorID), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldConnectorID, v)) } // ConnectorData applies equality check predicate on the "connector_data" field. It's identical to ConnectorDataEQ. func ConnectorData(v []byte) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldConnectorData), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldConnectorData, v)) } // Expiry applies equality check predicate on the "expiry" field. It's identical to ExpiryEQ. func Expiry(v time.Time) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldExpiry), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldExpiry, v)) } // CodeChallenge applies equality check predicate on the "code_challenge" field. It's identical to CodeChallengeEQ. func CodeChallenge(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldCodeChallenge, v)) } // CodeChallengeMethod applies equality check predicate on the "code_challenge_method" field. It's identical to CodeChallengeMethodEQ. func CodeChallengeMethod(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldCodeChallengeMethod, v)) } // ClientIDEQ applies the EQ predicate on the "client_id" field. func ClientIDEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClientID), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldClientID, v)) } // ClientIDNEQ applies the NEQ predicate on the "client_id" field. func ClientIDNEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClientID), v)) - }) + return predicate.AuthCode(sql.FieldNEQ(FieldClientID, v)) } // ClientIDIn applies the In predicate on the "client_id" field. func ClientIDIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldClientID), v...)) - }) + return predicate.AuthCode(sql.FieldIn(FieldClientID, vs...)) } // ClientIDNotIn applies the NotIn predicate on the "client_id" field. func ClientIDNotIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldClientID), v...)) - }) + return predicate.AuthCode(sql.FieldNotIn(FieldClientID, vs...)) } // ClientIDGT applies the GT predicate on the "client_id" field. func ClientIDGT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldClientID), v)) - }) + return predicate.AuthCode(sql.FieldGT(FieldClientID, v)) } // ClientIDGTE applies the GTE predicate on the "client_id" field. func ClientIDGTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldClientID), v)) - }) + return predicate.AuthCode(sql.FieldGTE(FieldClientID, v)) } // ClientIDLT applies the LT predicate on the "client_id" field. func ClientIDLT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldClientID), v)) - }) + return predicate.AuthCode(sql.FieldLT(FieldClientID, v)) } // ClientIDLTE applies the LTE predicate on the "client_id" field. func ClientIDLTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldClientID), v)) - }) + return predicate.AuthCode(sql.FieldLTE(FieldClientID, v)) } // ClientIDContains applies the Contains predicate on the "client_id" field. func ClientIDContains(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldClientID), v)) - }) + return predicate.AuthCode(sql.FieldContains(FieldClientID, v)) } // ClientIDHasPrefix applies the HasPrefix predicate on the "client_id" field. func ClientIDHasPrefix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldClientID), v)) - }) + return predicate.AuthCode(sql.FieldHasPrefix(FieldClientID, v)) } // ClientIDHasSuffix applies the HasSuffix predicate on the "client_id" field. func ClientIDHasSuffix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldClientID), v)) - }) + return predicate.AuthCode(sql.FieldHasSuffix(FieldClientID, v)) } // ClientIDEqualFold applies the EqualFold predicate on the "client_id" field. func ClientIDEqualFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldClientID), v)) - }) + return predicate.AuthCode(sql.FieldEqualFold(FieldClientID, v)) } // ClientIDContainsFold applies the ContainsFold predicate on the "client_id" field. func ClientIDContainsFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldClientID), v)) - }) + return predicate.AuthCode(sql.FieldContainsFold(FieldClientID, v)) } // ScopesIsNil applies the IsNil predicate on the "scopes" field. func ScopesIsNil() predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.IsNull(s.C(FieldScopes))) - }) + return predicate.AuthCode(sql.FieldIsNull(FieldScopes)) } // ScopesNotNil applies the NotNil predicate on the "scopes" field. func ScopesNotNil() predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NotNull(s.C(FieldScopes))) - }) + return predicate.AuthCode(sql.FieldNotNull(FieldScopes)) } // NonceEQ applies the EQ predicate on the "nonce" field. func NonceEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldNonce), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldNonce, v)) } // NonceNEQ applies the NEQ predicate on the "nonce" field. func NonceNEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldNonce), v)) - }) + return predicate.AuthCode(sql.FieldNEQ(FieldNonce, v)) } // NonceIn applies the In predicate on the "nonce" field. func NonceIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldNonce), v...)) - }) + return predicate.AuthCode(sql.FieldIn(FieldNonce, vs...)) } // NonceNotIn applies the NotIn predicate on the "nonce" field. func NonceNotIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldNonce), v...)) - }) + return predicate.AuthCode(sql.FieldNotIn(FieldNonce, vs...)) } // NonceGT applies the GT predicate on the "nonce" field. func NonceGT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldNonce), v)) - }) + return predicate.AuthCode(sql.FieldGT(FieldNonce, v)) } // NonceGTE applies the GTE predicate on the "nonce" field. func NonceGTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldNonce), v)) - }) + return predicate.AuthCode(sql.FieldGTE(FieldNonce, v)) } // NonceLT applies the LT predicate on the "nonce" field. func NonceLT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldNonce), v)) - }) + return predicate.AuthCode(sql.FieldLT(FieldNonce, v)) } // NonceLTE applies the LTE predicate on the "nonce" field. func NonceLTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldNonce), v)) - }) + return predicate.AuthCode(sql.FieldLTE(FieldNonce, v)) } // NonceContains applies the Contains predicate on the "nonce" field. func NonceContains(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldNonce), v)) - }) + return predicate.AuthCode(sql.FieldContains(FieldNonce, v)) } // NonceHasPrefix applies the HasPrefix predicate on the "nonce" field. func NonceHasPrefix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldNonce), v)) - }) + return predicate.AuthCode(sql.FieldHasPrefix(FieldNonce, v)) } // NonceHasSuffix applies the HasSuffix predicate on the "nonce" field. func NonceHasSuffix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldNonce), v)) - }) + return predicate.AuthCode(sql.FieldHasSuffix(FieldNonce, v)) } // NonceEqualFold applies the EqualFold predicate on the "nonce" field. func NonceEqualFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldNonce), v)) - }) + return predicate.AuthCode(sql.FieldEqualFold(FieldNonce, v)) } // NonceContainsFold applies the ContainsFold predicate on the "nonce" field. func NonceContainsFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldNonce), v)) - }) + return predicate.AuthCode(sql.FieldContainsFold(FieldNonce, v)) } // RedirectURIEQ applies the EQ predicate on the "redirect_uri" field. func RedirectURIEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldRedirectURI, v)) } // RedirectURINEQ applies the NEQ predicate on the "redirect_uri" field. func RedirectURINEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthCode(sql.FieldNEQ(FieldRedirectURI, v)) } // RedirectURIIn applies the In predicate on the "redirect_uri" field. func RedirectURIIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldRedirectURI), v...)) - }) + return predicate.AuthCode(sql.FieldIn(FieldRedirectURI, vs...)) } // RedirectURINotIn applies the NotIn predicate on the "redirect_uri" field. func RedirectURINotIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldRedirectURI), v...)) - }) + return predicate.AuthCode(sql.FieldNotIn(FieldRedirectURI, vs...)) } // RedirectURIGT applies the GT predicate on the "redirect_uri" field. func RedirectURIGT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthCode(sql.FieldGT(FieldRedirectURI, v)) } // RedirectURIGTE applies the GTE predicate on the "redirect_uri" field. func RedirectURIGTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthCode(sql.FieldGTE(FieldRedirectURI, v)) } // RedirectURILT applies the LT predicate on the "redirect_uri" field. func RedirectURILT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthCode(sql.FieldLT(FieldRedirectURI, v)) } // RedirectURILTE applies the LTE predicate on the "redirect_uri" field. func RedirectURILTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthCode(sql.FieldLTE(FieldRedirectURI, v)) } // RedirectURIContains applies the Contains predicate on the "redirect_uri" field. func RedirectURIContains(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthCode(sql.FieldContains(FieldRedirectURI, v)) } // RedirectURIHasPrefix applies the HasPrefix predicate on the "redirect_uri" field. func RedirectURIHasPrefix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthCode(sql.FieldHasPrefix(FieldRedirectURI, v)) } // RedirectURIHasSuffix applies the HasSuffix predicate on the "redirect_uri" field. func RedirectURIHasSuffix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthCode(sql.FieldHasSuffix(FieldRedirectURI, v)) } // RedirectURIEqualFold applies the EqualFold predicate on the "redirect_uri" field. func RedirectURIEqualFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthCode(sql.FieldEqualFold(FieldRedirectURI, v)) } // RedirectURIContainsFold applies the ContainsFold predicate on the "redirect_uri" field. func RedirectURIContainsFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthCode(sql.FieldContainsFold(FieldRedirectURI, v)) } // ClaimsUserIDEQ applies the EQ predicate on the "claims_user_id" field. func ClaimsUserIDEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldClaimsUserID, v)) } // ClaimsUserIDNEQ applies the NEQ predicate on the "claims_user_id" field. func ClaimsUserIDNEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthCode(sql.FieldNEQ(FieldClaimsUserID, v)) } // ClaimsUserIDIn applies the In predicate on the "claims_user_id" field. func ClaimsUserIDIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldClaimsUserID), v...)) - }) + return predicate.AuthCode(sql.FieldIn(FieldClaimsUserID, vs...)) } // ClaimsUserIDNotIn applies the NotIn predicate on the "claims_user_id" field. func ClaimsUserIDNotIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldClaimsUserID), v...)) - }) + return predicate.AuthCode(sql.FieldNotIn(FieldClaimsUserID, vs...)) } // ClaimsUserIDGT applies the GT predicate on the "claims_user_id" field. func ClaimsUserIDGT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthCode(sql.FieldGT(FieldClaimsUserID, v)) } // ClaimsUserIDGTE applies the GTE predicate on the "claims_user_id" field. func ClaimsUserIDGTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthCode(sql.FieldGTE(FieldClaimsUserID, v)) } // ClaimsUserIDLT applies the LT predicate on the "claims_user_id" field. func ClaimsUserIDLT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthCode(sql.FieldLT(FieldClaimsUserID, v)) } // ClaimsUserIDLTE applies the LTE predicate on the "claims_user_id" field. func ClaimsUserIDLTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthCode(sql.FieldLTE(FieldClaimsUserID, v)) } // ClaimsUserIDContains applies the Contains predicate on the "claims_user_id" field. func ClaimsUserIDContains(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthCode(sql.FieldContains(FieldClaimsUserID, v)) } // ClaimsUserIDHasPrefix applies the HasPrefix predicate on the "claims_user_id" field. func ClaimsUserIDHasPrefix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthCode(sql.FieldHasPrefix(FieldClaimsUserID, v)) } // ClaimsUserIDHasSuffix applies the HasSuffix predicate on the "claims_user_id" field. func ClaimsUserIDHasSuffix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthCode(sql.FieldHasSuffix(FieldClaimsUserID, v)) } // ClaimsUserIDEqualFold applies the EqualFold predicate on the "claims_user_id" field. func ClaimsUserIDEqualFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthCode(sql.FieldEqualFold(FieldClaimsUserID, v)) } // ClaimsUserIDContainsFold applies the ContainsFold predicate on the "claims_user_id" field. func ClaimsUserIDContainsFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthCode(sql.FieldContainsFold(FieldClaimsUserID, v)) } // ClaimsUsernameEQ applies the EQ predicate on the "claims_username" field. func ClaimsUsernameEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldClaimsUsername, v)) } // ClaimsUsernameNEQ applies the NEQ predicate on the "claims_username" field. func ClaimsUsernameNEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthCode(sql.FieldNEQ(FieldClaimsUsername, v)) } // ClaimsUsernameIn applies the In predicate on the "claims_username" field. func ClaimsUsernameIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldClaimsUsername), v...)) - }) + return predicate.AuthCode(sql.FieldIn(FieldClaimsUsername, vs...)) } // ClaimsUsernameNotIn applies the NotIn predicate on the "claims_username" field. func ClaimsUsernameNotIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldClaimsUsername), v...)) - }) + return predicate.AuthCode(sql.FieldNotIn(FieldClaimsUsername, vs...)) } // ClaimsUsernameGT applies the GT predicate on the "claims_username" field. func ClaimsUsernameGT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthCode(sql.FieldGT(FieldClaimsUsername, v)) } // ClaimsUsernameGTE applies the GTE predicate on the "claims_username" field. func ClaimsUsernameGTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthCode(sql.FieldGTE(FieldClaimsUsername, v)) } // ClaimsUsernameLT applies the LT predicate on the "claims_username" field. func ClaimsUsernameLT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthCode(sql.FieldLT(FieldClaimsUsername, v)) } // ClaimsUsernameLTE applies the LTE predicate on the "claims_username" field. func ClaimsUsernameLTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthCode(sql.FieldLTE(FieldClaimsUsername, v)) } // ClaimsUsernameContains applies the Contains predicate on the "claims_username" field. func ClaimsUsernameContains(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthCode(sql.FieldContains(FieldClaimsUsername, v)) } // ClaimsUsernameHasPrefix applies the HasPrefix predicate on the "claims_username" field. func ClaimsUsernameHasPrefix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthCode(sql.FieldHasPrefix(FieldClaimsUsername, v)) } // ClaimsUsernameHasSuffix applies the HasSuffix predicate on the "claims_username" field. func ClaimsUsernameHasSuffix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthCode(sql.FieldHasSuffix(FieldClaimsUsername, v)) } // ClaimsUsernameEqualFold applies the EqualFold predicate on the "claims_username" field. func ClaimsUsernameEqualFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthCode(sql.FieldEqualFold(FieldClaimsUsername, v)) } // ClaimsUsernameContainsFold applies the ContainsFold predicate on the "claims_username" field. func ClaimsUsernameContainsFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthCode(sql.FieldContainsFold(FieldClaimsUsername, v)) } // ClaimsEmailEQ applies the EQ predicate on the "claims_email" field. func ClaimsEmailEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldClaimsEmail, v)) } // ClaimsEmailNEQ applies the NEQ predicate on the "claims_email" field. func ClaimsEmailNEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthCode(sql.FieldNEQ(FieldClaimsEmail, v)) } // ClaimsEmailIn applies the In predicate on the "claims_email" field. func ClaimsEmailIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldClaimsEmail), v...)) - }) + return predicate.AuthCode(sql.FieldIn(FieldClaimsEmail, vs...)) } // ClaimsEmailNotIn applies the NotIn predicate on the "claims_email" field. func ClaimsEmailNotIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldClaimsEmail), v...)) - }) + return predicate.AuthCode(sql.FieldNotIn(FieldClaimsEmail, vs...)) } // ClaimsEmailGT applies the GT predicate on the "claims_email" field. func ClaimsEmailGT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthCode(sql.FieldGT(FieldClaimsEmail, v)) } // ClaimsEmailGTE applies the GTE predicate on the "claims_email" field. func ClaimsEmailGTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthCode(sql.FieldGTE(FieldClaimsEmail, v)) } // ClaimsEmailLT applies the LT predicate on the "claims_email" field. func ClaimsEmailLT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthCode(sql.FieldLT(FieldClaimsEmail, v)) } // ClaimsEmailLTE applies the LTE predicate on the "claims_email" field. func ClaimsEmailLTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthCode(sql.FieldLTE(FieldClaimsEmail, v)) } // ClaimsEmailContains applies the Contains predicate on the "claims_email" field. func ClaimsEmailContains(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthCode(sql.FieldContains(FieldClaimsEmail, v)) } // ClaimsEmailHasPrefix applies the HasPrefix predicate on the "claims_email" field. func ClaimsEmailHasPrefix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthCode(sql.FieldHasPrefix(FieldClaimsEmail, v)) } // ClaimsEmailHasSuffix applies the HasSuffix predicate on the "claims_email" field. func ClaimsEmailHasSuffix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthCode(sql.FieldHasSuffix(FieldClaimsEmail, v)) } // ClaimsEmailEqualFold applies the EqualFold predicate on the "claims_email" field. func ClaimsEmailEqualFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthCode(sql.FieldEqualFold(FieldClaimsEmail, v)) } // ClaimsEmailContainsFold applies the ContainsFold predicate on the "claims_email" field. func ClaimsEmailContainsFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthCode(sql.FieldContainsFold(FieldClaimsEmail, v)) } // ClaimsEmailVerifiedEQ applies the EQ predicate on the "claims_email_verified" field. func ClaimsEmailVerifiedEQ(v bool) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsEmailVerified), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldClaimsEmailVerified, v)) } // ClaimsEmailVerifiedNEQ applies the NEQ predicate on the "claims_email_verified" field. func ClaimsEmailVerifiedNEQ(v bool) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClaimsEmailVerified), v)) - }) + return predicate.AuthCode(sql.FieldNEQ(FieldClaimsEmailVerified, v)) } // ClaimsGroupsIsNil applies the IsNil predicate on the "claims_groups" field. func ClaimsGroupsIsNil() predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.IsNull(s.C(FieldClaimsGroups))) - }) + return predicate.AuthCode(sql.FieldIsNull(FieldClaimsGroups)) } // ClaimsGroupsNotNil applies the NotNil predicate on the "claims_groups" field. func ClaimsGroupsNotNil() predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NotNull(s.C(FieldClaimsGroups))) - }) + return predicate.AuthCode(sql.FieldNotNull(FieldClaimsGroups)) } // ClaimsPreferredUsernameEQ applies the EQ predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameNEQ applies the NEQ predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameNEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthCode(sql.FieldNEQ(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameIn applies the In predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldClaimsPreferredUsername), v...)) - }) + return predicate.AuthCode(sql.FieldIn(FieldClaimsPreferredUsername, vs...)) } // ClaimsPreferredUsernameNotIn applies the NotIn predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameNotIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldClaimsPreferredUsername), v...)) - }) + return predicate.AuthCode(sql.FieldNotIn(FieldClaimsPreferredUsername, vs...)) } // ClaimsPreferredUsernameGT applies the GT predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameGT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthCode(sql.FieldGT(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameGTE applies the GTE predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameGTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthCode(sql.FieldGTE(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameLT applies the LT predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameLT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthCode(sql.FieldLT(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameLTE applies the LTE predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameLTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthCode(sql.FieldLTE(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameContains applies the Contains predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameContains(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthCode(sql.FieldContains(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameHasPrefix applies the HasPrefix predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameHasPrefix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthCode(sql.FieldHasPrefix(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameHasSuffix applies the HasSuffix predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameHasSuffix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthCode(sql.FieldHasSuffix(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameEqualFold applies the EqualFold predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameEqualFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthCode(sql.FieldEqualFold(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameContainsFold applies the ContainsFold predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameContainsFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthCode(sql.FieldContainsFold(FieldClaimsPreferredUsername, v)) } // ConnectorIDEQ applies the EQ predicate on the "connector_id" field. func ConnectorIDEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldConnectorID), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldConnectorID, v)) } // ConnectorIDNEQ applies the NEQ predicate on the "connector_id" field. func ConnectorIDNEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldConnectorID), v)) - }) + return predicate.AuthCode(sql.FieldNEQ(FieldConnectorID, v)) } // ConnectorIDIn applies the In predicate on the "connector_id" field. func ConnectorIDIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldConnectorID), v...)) - }) + return predicate.AuthCode(sql.FieldIn(FieldConnectorID, vs...)) } // ConnectorIDNotIn applies the NotIn predicate on the "connector_id" field. func ConnectorIDNotIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldConnectorID), v...)) - }) + return predicate.AuthCode(sql.FieldNotIn(FieldConnectorID, vs...)) } // ConnectorIDGT applies the GT predicate on the "connector_id" field. func ConnectorIDGT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldConnectorID), v)) - }) + return predicate.AuthCode(sql.FieldGT(FieldConnectorID, v)) } // ConnectorIDGTE applies the GTE predicate on the "connector_id" field. func ConnectorIDGTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldConnectorID), v)) - }) + return predicate.AuthCode(sql.FieldGTE(FieldConnectorID, v)) } // ConnectorIDLT applies the LT predicate on the "connector_id" field. func ConnectorIDLT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldConnectorID), v)) - }) + return predicate.AuthCode(sql.FieldLT(FieldConnectorID, v)) } // ConnectorIDLTE applies the LTE predicate on the "connector_id" field. func ConnectorIDLTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldConnectorID), v)) - }) + return predicate.AuthCode(sql.FieldLTE(FieldConnectorID, v)) } // ConnectorIDContains applies the Contains predicate on the "connector_id" field. func ConnectorIDContains(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldConnectorID), v)) - }) + return predicate.AuthCode(sql.FieldContains(FieldConnectorID, v)) } // ConnectorIDHasPrefix applies the HasPrefix predicate on the "connector_id" field. func ConnectorIDHasPrefix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldConnectorID), v)) - }) + return predicate.AuthCode(sql.FieldHasPrefix(FieldConnectorID, v)) } // ConnectorIDHasSuffix applies the HasSuffix predicate on the "connector_id" field. func ConnectorIDHasSuffix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldConnectorID), v)) - }) + return predicate.AuthCode(sql.FieldHasSuffix(FieldConnectorID, v)) } // ConnectorIDEqualFold applies the EqualFold predicate on the "connector_id" field. func ConnectorIDEqualFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldConnectorID), v)) - }) + return predicate.AuthCode(sql.FieldEqualFold(FieldConnectorID, v)) } // ConnectorIDContainsFold applies the ContainsFold predicate on the "connector_id" field. func ConnectorIDContainsFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldConnectorID), v)) - }) + return predicate.AuthCode(sql.FieldContainsFold(FieldConnectorID, v)) } // ConnectorDataEQ applies the EQ predicate on the "connector_data" field. func ConnectorDataEQ(v []byte) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldConnectorData), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldConnectorData, v)) } // ConnectorDataNEQ applies the NEQ predicate on the "connector_data" field. func ConnectorDataNEQ(v []byte) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldConnectorData), v)) - }) + return predicate.AuthCode(sql.FieldNEQ(FieldConnectorData, v)) } // ConnectorDataIn applies the In predicate on the "connector_data" field. func ConnectorDataIn(vs ...[]byte) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldConnectorData), v...)) - }) + return predicate.AuthCode(sql.FieldIn(FieldConnectorData, vs...)) } // ConnectorDataNotIn applies the NotIn predicate on the "connector_data" field. func ConnectorDataNotIn(vs ...[]byte) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldConnectorData), v...)) - }) + return predicate.AuthCode(sql.FieldNotIn(FieldConnectorData, vs...)) } // ConnectorDataGT applies the GT predicate on the "connector_data" field. func ConnectorDataGT(v []byte) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldConnectorData), v)) - }) + return predicate.AuthCode(sql.FieldGT(FieldConnectorData, v)) } // ConnectorDataGTE applies the GTE predicate on the "connector_data" field. func ConnectorDataGTE(v []byte) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldConnectorData), v)) - }) + return predicate.AuthCode(sql.FieldGTE(FieldConnectorData, v)) } // ConnectorDataLT applies the LT predicate on the "connector_data" field. func ConnectorDataLT(v []byte) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldConnectorData), v)) - }) + return predicate.AuthCode(sql.FieldLT(FieldConnectorData, v)) } // ConnectorDataLTE applies the LTE predicate on the "connector_data" field. func ConnectorDataLTE(v []byte) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldConnectorData), v)) - }) + return predicate.AuthCode(sql.FieldLTE(FieldConnectorData, v)) } // ConnectorDataIsNil applies the IsNil predicate on the "connector_data" field. func ConnectorDataIsNil() predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.IsNull(s.C(FieldConnectorData))) - }) + return predicate.AuthCode(sql.FieldIsNull(FieldConnectorData)) } // ConnectorDataNotNil applies the NotNil predicate on the "connector_data" field. func ConnectorDataNotNil() predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NotNull(s.C(FieldConnectorData))) - }) + return predicate.AuthCode(sql.FieldNotNull(FieldConnectorData)) } // ExpiryEQ applies the EQ predicate on the "expiry" field. func ExpiryEQ(v time.Time) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldExpiry), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldExpiry, v)) } // ExpiryNEQ applies the NEQ predicate on the "expiry" field. func ExpiryNEQ(v time.Time) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldExpiry), v)) - }) + return predicate.AuthCode(sql.FieldNEQ(FieldExpiry, v)) } // ExpiryIn applies the In predicate on the "expiry" field. func ExpiryIn(vs ...time.Time) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldExpiry), v...)) - }) + return predicate.AuthCode(sql.FieldIn(FieldExpiry, vs...)) } // ExpiryNotIn applies the NotIn predicate on the "expiry" field. func ExpiryNotIn(vs ...time.Time) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldExpiry), v...)) - }) + return predicate.AuthCode(sql.FieldNotIn(FieldExpiry, vs...)) } // ExpiryGT applies the GT predicate on the "expiry" field. func ExpiryGT(v time.Time) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldExpiry), v)) - }) + return predicate.AuthCode(sql.FieldGT(FieldExpiry, v)) } // ExpiryGTE applies the GTE predicate on the "expiry" field. func ExpiryGTE(v time.Time) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldExpiry), v)) - }) + return predicate.AuthCode(sql.FieldGTE(FieldExpiry, v)) } // ExpiryLT applies the LT predicate on the "expiry" field. func ExpiryLT(v time.Time) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldExpiry), v)) - }) + return predicate.AuthCode(sql.FieldLT(FieldExpiry, v)) } // ExpiryLTE applies the LTE predicate on the "expiry" field. func ExpiryLTE(v time.Time) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldExpiry), v)) - }) + return predicate.AuthCode(sql.FieldLTE(FieldExpiry, v)) } // CodeChallengeEQ applies the EQ predicate on the "code_challenge" field. func CodeChallengeEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldCodeChallenge, v)) } // CodeChallengeNEQ applies the NEQ predicate on the "code_challenge" field. func CodeChallengeNEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthCode(sql.FieldNEQ(FieldCodeChallenge, v)) } // CodeChallengeIn applies the In predicate on the "code_challenge" field. func CodeChallengeIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldCodeChallenge), v...)) - }) + return predicate.AuthCode(sql.FieldIn(FieldCodeChallenge, vs...)) } // CodeChallengeNotIn applies the NotIn predicate on the "code_challenge" field. func CodeChallengeNotIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldCodeChallenge), v...)) - }) + return predicate.AuthCode(sql.FieldNotIn(FieldCodeChallenge, vs...)) } // CodeChallengeGT applies the GT predicate on the "code_challenge" field. func CodeChallengeGT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthCode(sql.FieldGT(FieldCodeChallenge, v)) } // CodeChallengeGTE applies the GTE predicate on the "code_challenge" field. func CodeChallengeGTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthCode(sql.FieldGTE(FieldCodeChallenge, v)) } // CodeChallengeLT applies the LT predicate on the "code_challenge" field. func CodeChallengeLT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthCode(sql.FieldLT(FieldCodeChallenge, v)) } // CodeChallengeLTE applies the LTE predicate on the "code_challenge" field. func CodeChallengeLTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthCode(sql.FieldLTE(FieldCodeChallenge, v)) } // CodeChallengeContains applies the Contains predicate on the "code_challenge" field. func CodeChallengeContains(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthCode(sql.FieldContains(FieldCodeChallenge, v)) } // CodeChallengeHasPrefix applies the HasPrefix predicate on the "code_challenge" field. func CodeChallengeHasPrefix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthCode(sql.FieldHasPrefix(FieldCodeChallenge, v)) } // CodeChallengeHasSuffix applies the HasSuffix predicate on the "code_challenge" field. func CodeChallengeHasSuffix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthCode(sql.FieldHasSuffix(FieldCodeChallenge, v)) } // CodeChallengeEqualFold applies the EqualFold predicate on the "code_challenge" field. func CodeChallengeEqualFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthCode(sql.FieldEqualFold(FieldCodeChallenge, v)) } // CodeChallengeContainsFold applies the ContainsFold predicate on the "code_challenge" field. func CodeChallengeContainsFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthCode(sql.FieldContainsFold(FieldCodeChallenge, v)) } // CodeChallengeMethodEQ applies the EQ predicate on the "code_challenge_method" field. func CodeChallengeMethodEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthCode(sql.FieldEQ(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodNEQ applies the NEQ predicate on the "code_challenge_method" field. func CodeChallengeMethodNEQ(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthCode(sql.FieldNEQ(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodIn applies the In predicate on the "code_challenge_method" field. func CodeChallengeMethodIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldCodeChallengeMethod), v...)) - }) + return predicate.AuthCode(sql.FieldIn(FieldCodeChallengeMethod, vs...)) } // CodeChallengeMethodNotIn applies the NotIn predicate on the "code_challenge_method" field. func CodeChallengeMethodNotIn(vs ...string) predicate.AuthCode { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldCodeChallengeMethod), v...)) - }) + return predicate.AuthCode(sql.FieldNotIn(FieldCodeChallengeMethod, vs...)) } // CodeChallengeMethodGT applies the GT predicate on the "code_challenge_method" field. func CodeChallengeMethodGT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthCode(sql.FieldGT(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodGTE applies the GTE predicate on the "code_challenge_method" field. func CodeChallengeMethodGTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthCode(sql.FieldGTE(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodLT applies the LT predicate on the "code_challenge_method" field. func CodeChallengeMethodLT(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthCode(sql.FieldLT(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodLTE applies the LTE predicate on the "code_challenge_method" field. func CodeChallengeMethodLTE(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthCode(sql.FieldLTE(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodContains applies the Contains predicate on the "code_challenge_method" field. func CodeChallengeMethodContains(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthCode(sql.FieldContains(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodHasPrefix applies the HasPrefix predicate on the "code_challenge_method" field. func CodeChallengeMethodHasPrefix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthCode(sql.FieldHasPrefix(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodHasSuffix applies the HasSuffix predicate on the "code_challenge_method" field. func CodeChallengeMethodHasSuffix(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthCode(sql.FieldHasSuffix(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodEqualFold applies the EqualFold predicate on the "code_challenge_method" field. func CodeChallengeMethodEqualFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthCode(sql.FieldEqualFold(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodContainsFold applies the ContainsFold predicate on the "code_challenge_method" field. func CodeChallengeMethodContainsFold(v string) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthCode(sql.FieldContainsFold(FieldCodeChallengeMethod, v)) } // And groups predicates with the AND operator between them. func And(predicates ...predicate.AuthCode) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for _, p := range predicates { - p(s1) - } - s.Where(s1.P()) - }) + return predicate.AuthCode(sql.AndPredicates(predicates...)) } // Or groups predicates with the OR operator between them. func Or(predicates ...predicate.AuthCode) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for i, p := range predicates { - if i > 0 { - s1.Or() - } - p(s1) - } - s.Where(s1.P()) - }) + return predicate.AuthCode(sql.OrPredicates(predicates...)) } // Not applies the not operator on the given predicate. func Not(p predicate.AuthCode) predicate.AuthCode { - return predicate.AuthCode(func(s *sql.Selector) { - p(s.Not()) - }) + return predicate.AuthCode(sql.NotPredicates(p)) } diff --git a/storage/ent/db/authcode_create.go b/storage/ent/db/authcode_create.go index c075c3d3fc..ab4b9e4e14 100644 --- a/storage/ent/db/authcode_create.go +++ b/storage/ent/db/authcode_create.go @@ -21,181 +21,139 @@ type AuthCodeCreate struct { } // SetClientID sets the "client_id" field. -func (acc *AuthCodeCreate) SetClientID(s string) *AuthCodeCreate { - acc.mutation.SetClientID(s) - return acc +func (_c *AuthCodeCreate) SetClientID(v string) *AuthCodeCreate { + _c.mutation.SetClientID(v) + return _c } // SetScopes sets the "scopes" field. -func (acc *AuthCodeCreate) SetScopes(s []string) *AuthCodeCreate { - acc.mutation.SetScopes(s) - return acc +func (_c *AuthCodeCreate) SetScopes(v []string) *AuthCodeCreate { + _c.mutation.SetScopes(v) + return _c } // SetNonce sets the "nonce" field. -func (acc *AuthCodeCreate) SetNonce(s string) *AuthCodeCreate { - acc.mutation.SetNonce(s) - return acc +func (_c *AuthCodeCreate) SetNonce(v string) *AuthCodeCreate { + _c.mutation.SetNonce(v) + return _c } // SetRedirectURI sets the "redirect_uri" field. -func (acc *AuthCodeCreate) SetRedirectURI(s string) *AuthCodeCreate { - acc.mutation.SetRedirectURI(s) - return acc +func (_c *AuthCodeCreate) SetRedirectURI(v string) *AuthCodeCreate { + _c.mutation.SetRedirectURI(v) + return _c } // SetClaimsUserID sets the "claims_user_id" field. -func (acc *AuthCodeCreate) SetClaimsUserID(s string) *AuthCodeCreate { - acc.mutation.SetClaimsUserID(s) - return acc +func (_c *AuthCodeCreate) SetClaimsUserID(v string) *AuthCodeCreate { + _c.mutation.SetClaimsUserID(v) + return _c } // SetClaimsUsername sets the "claims_username" field. -func (acc *AuthCodeCreate) SetClaimsUsername(s string) *AuthCodeCreate { - acc.mutation.SetClaimsUsername(s) - return acc +func (_c *AuthCodeCreate) SetClaimsUsername(v string) *AuthCodeCreate { + _c.mutation.SetClaimsUsername(v) + return _c } // SetClaimsEmail sets the "claims_email" field. -func (acc *AuthCodeCreate) SetClaimsEmail(s string) *AuthCodeCreate { - acc.mutation.SetClaimsEmail(s) - return acc +func (_c *AuthCodeCreate) SetClaimsEmail(v string) *AuthCodeCreate { + _c.mutation.SetClaimsEmail(v) + return _c } // SetClaimsEmailVerified sets the "claims_email_verified" field. -func (acc *AuthCodeCreate) SetClaimsEmailVerified(b bool) *AuthCodeCreate { - acc.mutation.SetClaimsEmailVerified(b) - return acc +func (_c *AuthCodeCreate) SetClaimsEmailVerified(v bool) *AuthCodeCreate { + _c.mutation.SetClaimsEmailVerified(v) + return _c } // SetClaimsGroups sets the "claims_groups" field. -func (acc *AuthCodeCreate) SetClaimsGroups(s []string) *AuthCodeCreate { - acc.mutation.SetClaimsGroups(s) - return acc +func (_c *AuthCodeCreate) SetClaimsGroups(v []string) *AuthCodeCreate { + _c.mutation.SetClaimsGroups(v) + return _c } // SetClaimsPreferredUsername sets the "claims_preferred_username" field. -func (acc *AuthCodeCreate) SetClaimsPreferredUsername(s string) *AuthCodeCreate { - acc.mutation.SetClaimsPreferredUsername(s) - return acc +func (_c *AuthCodeCreate) SetClaimsPreferredUsername(v string) *AuthCodeCreate { + _c.mutation.SetClaimsPreferredUsername(v) + return _c } // SetNillableClaimsPreferredUsername sets the "claims_preferred_username" field if the given value is not nil. -func (acc *AuthCodeCreate) SetNillableClaimsPreferredUsername(s *string) *AuthCodeCreate { - if s != nil { - acc.SetClaimsPreferredUsername(*s) +func (_c *AuthCodeCreate) SetNillableClaimsPreferredUsername(v *string) *AuthCodeCreate { + if v != nil { + _c.SetClaimsPreferredUsername(*v) } - return acc + return _c } // SetConnectorID sets the "connector_id" field. -func (acc *AuthCodeCreate) SetConnectorID(s string) *AuthCodeCreate { - acc.mutation.SetConnectorID(s) - return acc +func (_c *AuthCodeCreate) SetConnectorID(v string) *AuthCodeCreate { + _c.mutation.SetConnectorID(v) + return _c } // SetConnectorData sets the "connector_data" field. -func (acc *AuthCodeCreate) SetConnectorData(b []byte) *AuthCodeCreate { - acc.mutation.SetConnectorData(b) - return acc +func (_c *AuthCodeCreate) SetConnectorData(v []byte) *AuthCodeCreate { + _c.mutation.SetConnectorData(v) + return _c } // SetExpiry sets the "expiry" field. -func (acc *AuthCodeCreate) SetExpiry(t time.Time) *AuthCodeCreate { - acc.mutation.SetExpiry(t) - return acc +func (_c *AuthCodeCreate) SetExpiry(v time.Time) *AuthCodeCreate { + _c.mutation.SetExpiry(v) + return _c } // SetCodeChallenge sets the "code_challenge" field. -func (acc *AuthCodeCreate) SetCodeChallenge(s string) *AuthCodeCreate { - acc.mutation.SetCodeChallenge(s) - return acc +func (_c *AuthCodeCreate) SetCodeChallenge(v string) *AuthCodeCreate { + _c.mutation.SetCodeChallenge(v) + return _c } // SetNillableCodeChallenge sets the "code_challenge" field if the given value is not nil. -func (acc *AuthCodeCreate) SetNillableCodeChallenge(s *string) *AuthCodeCreate { - if s != nil { - acc.SetCodeChallenge(*s) +func (_c *AuthCodeCreate) SetNillableCodeChallenge(v *string) *AuthCodeCreate { + if v != nil { + _c.SetCodeChallenge(*v) } - return acc + return _c } // SetCodeChallengeMethod sets the "code_challenge_method" field. -func (acc *AuthCodeCreate) SetCodeChallengeMethod(s string) *AuthCodeCreate { - acc.mutation.SetCodeChallengeMethod(s) - return acc +func (_c *AuthCodeCreate) SetCodeChallengeMethod(v string) *AuthCodeCreate { + _c.mutation.SetCodeChallengeMethod(v) + return _c } // SetNillableCodeChallengeMethod sets the "code_challenge_method" field if the given value is not nil. -func (acc *AuthCodeCreate) SetNillableCodeChallengeMethod(s *string) *AuthCodeCreate { - if s != nil { - acc.SetCodeChallengeMethod(*s) +func (_c *AuthCodeCreate) SetNillableCodeChallengeMethod(v *string) *AuthCodeCreate { + if v != nil { + _c.SetCodeChallengeMethod(*v) } - return acc + return _c } // SetID sets the "id" field. -func (acc *AuthCodeCreate) SetID(s string) *AuthCodeCreate { - acc.mutation.SetID(s) - return acc +func (_c *AuthCodeCreate) SetID(v string) *AuthCodeCreate { + _c.mutation.SetID(v) + return _c } // Mutation returns the AuthCodeMutation object of the builder. -func (acc *AuthCodeCreate) Mutation() *AuthCodeMutation { - return acc.mutation +func (_c *AuthCodeCreate) Mutation() *AuthCodeMutation { + return _c.mutation } // Save creates the AuthCode in the database. -func (acc *AuthCodeCreate) Save(ctx context.Context) (*AuthCode, error) { - var ( - err error - node *AuthCode - ) - acc.defaults() - if len(acc.hooks) == 0 { - if err = acc.check(); err != nil { - return nil, err - } - node, err = acc.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*AuthCodeMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = acc.check(); err != nil { - return nil, err - } - acc.mutation = mutation - if node, err = acc.sqlSave(ctx); err != nil { - return nil, err - } - mutation.id = &node.ID - mutation.done = true - return node, err - }) - for i := len(acc.hooks) - 1; i >= 0; i-- { - if acc.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = acc.hooks[i](mut) - } - v, err := mut.Mutate(ctx, acc.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*AuthCode) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from AuthCodeMutation", v) - } - node = nv - } - return node, err +func (_c *AuthCodeCreate) Save(ctx context.Context) (*AuthCode, error) { + _c.defaults() + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) } // SaveX calls Save and panics if Save returns an error. -func (acc *AuthCodeCreate) SaveX(ctx context.Context) *AuthCode { - v, err := acc.Save(ctx) +func (_c *AuthCodeCreate) SaveX(ctx context.Context) *AuthCode { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -203,108 +161,108 @@ func (acc *AuthCodeCreate) SaveX(ctx context.Context) *AuthCode { } // Exec executes the query. -func (acc *AuthCodeCreate) Exec(ctx context.Context) error { - _, err := acc.Save(ctx) +func (_c *AuthCodeCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (acc *AuthCodeCreate) ExecX(ctx context.Context) { - if err := acc.Exec(ctx); err != nil { +func (_c *AuthCodeCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } // defaults sets the default values of the builder before save. -func (acc *AuthCodeCreate) defaults() { - if _, ok := acc.mutation.ClaimsPreferredUsername(); !ok { +func (_c *AuthCodeCreate) defaults() { + if _, ok := _c.mutation.ClaimsPreferredUsername(); !ok { v := authcode.DefaultClaimsPreferredUsername - acc.mutation.SetClaimsPreferredUsername(v) + _c.mutation.SetClaimsPreferredUsername(v) } - if _, ok := acc.mutation.CodeChallenge(); !ok { + if _, ok := _c.mutation.CodeChallenge(); !ok { v := authcode.DefaultCodeChallenge - acc.mutation.SetCodeChallenge(v) + _c.mutation.SetCodeChallenge(v) } - if _, ok := acc.mutation.CodeChallengeMethod(); !ok { + if _, ok := _c.mutation.CodeChallengeMethod(); !ok { v := authcode.DefaultCodeChallengeMethod - acc.mutation.SetCodeChallengeMethod(v) + _c.mutation.SetCodeChallengeMethod(v) } } // check runs all checks and user-defined validators on the builder. -func (acc *AuthCodeCreate) check() error { - if _, ok := acc.mutation.ClientID(); !ok { +func (_c *AuthCodeCreate) check() error { + if _, ok := _c.mutation.ClientID(); !ok { return &ValidationError{Name: "client_id", err: errors.New(`db: missing required field "AuthCode.client_id"`)} } - if v, ok := acc.mutation.ClientID(); ok { + if v, ok := _c.mutation.ClientID(); ok { if err := authcode.ClientIDValidator(v); err != nil { return &ValidationError{Name: "client_id", err: fmt.Errorf(`db: validator failed for field "AuthCode.client_id": %w`, err)} } } - if _, ok := acc.mutation.Nonce(); !ok { + if _, ok := _c.mutation.Nonce(); !ok { return &ValidationError{Name: "nonce", err: errors.New(`db: missing required field "AuthCode.nonce"`)} } - if v, ok := acc.mutation.Nonce(); ok { + if v, ok := _c.mutation.Nonce(); ok { if err := authcode.NonceValidator(v); err != nil { return &ValidationError{Name: "nonce", err: fmt.Errorf(`db: validator failed for field "AuthCode.nonce": %w`, err)} } } - if _, ok := acc.mutation.RedirectURI(); !ok { + if _, ok := _c.mutation.RedirectURI(); !ok { return &ValidationError{Name: "redirect_uri", err: errors.New(`db: missing required field "AuthCode.redirect_uri"`)} } - if v, ok := acc.mutation.RedirectURI(); ok { + if v, ok := _c.mutation.RedirectURI(); ok { if err := authcode.RedirectURIValidator(v); err != nil { return &ValidationError{Name: "redirect_uri", err: fmt.Errorf(`db: validator failed for field "AuthCode.redirect_uri": %w`, err)} } } - if _, ok := acc.mutation.ClaimsUserID(); !ok { + if _, ok := _c.mutation.ClaimsUserID(); !ok { return &ValidationError{Name: "claims_user_id", err: errors.New(`db: missing required field "AuthCode.claims_user_id"`)} } - if v, ok := acc.mutation.ClaimsUserID(); ok { + if v, ok := _c.mutation.ClaimsUserID(); ok { if err := authcode.ClaimsUserIDValidator(v); err != nil { return &ValidationError{Name: "claims_user_id", err: fmt.Errorf(`db: validator failed for field "AuthCode.claims_user_id": %w`, err)} } } - if _, ok := acc.mutation.ClaimsUsername(); !ok { + if _, ok := _c.mutation.ClaimsUsername(); !ok { return &ValidationError{Name: "claims_username", err: errors.New(`db: missing required field "AuthCode.claims_username"`)} } - if v, ok := acc.mutation.ClaimsUsername(); ok { + if v, ok := _c.mutation.ClaimsUsername(); ok { if err := authcode.ClaimsUsernameValidator(v); err != nil { return &ValidationError{Name: "claims_username", err: fmt.Errorf(`db: validator failed for field "AuthCode.claims_username": %w`, err)} } } - if _, ok := acc.mutation.ClaimsEmail(); !ok { + if _, ok := _c.mutation.ClaimsEmail(); !ok { return &ValidationError{Name: "claims_email", err: errors.New(`db: missing required field "AuthCode.claims_email"`)} } - if v, ok := acc.mutation.ClaimsEmail(); ok { + if v, ok := _c.mutation.ClaimsEmail(); ok { if err := authcode.ClaimsEmailValidator(v); err != nil { return &ValidationError{Name: "claims_email", err: fmt.Errorf(`db: validator failed for field "AuthCode.claims_email": %w`, err)} } } - if _, ok := acc.mutation.ClaimsEmailVerified(); !ok { + if _, ok := _c.mutation.ClaimsEmailVerified(); !ok { return &ValidationError{Name: "claims_email_verified", err: errors.New(`db: missing required field "AuthCode.claims_email_verified"`)} } - if _, ok := acc.mutation.ClaimsPreferredUsername(); !ok { + if _, ok := _c.mutation.ClaimsPreferredUsername(); !ok { return &ValidationError{Name: "claims_preferred_username", err: errors.New(`db: missing required field "AuthCode.claims_preferred_username"`)} } - if _, ok := acc.mutation.ConnectorID(); !ok { + if _, ok := _c.mutation.ConnectorID(); !ok { return &ValidationError{Name: "connector_id", err: errors.New(`db: missing required field "AuthCode.connector_id"`)} } - if v, ok := acc.mutation.ConnectorID(); ok { + if v, ok := _c.mutation.ConnectorID(); ok { if err := authcode.ConnectorIDValidator(v); err != nil { return &ValidationError{Name: "connector_id", err: fmt.Errorf(`db: validator failed for field "AuthCode.connector_id": %w`, err)} } } - if _, ok := acc.mutation.Expiry(); !ok { + if _, ok := _c.mutation.Expiry(); !ok { return &ValidationError{Name: "expiry", err: errors.New(`db: missing required field "AuthCode.expiry"`)} } - if _, ok := acc.mutation.CodeChallenge(); !ok { + if _, ok := _c.mutation.CodeChallenge(); !ok { return &ValidationError{Name: "code_challenge", err: errors.New(`db: missing required field "AuthCode.code_challenge"`)} } - if _, ok := acc.mutation.CodeChallengeMethod(); !ok { + if _, ok := _c.mutation.CodeChallengeMethod(); !ok { return &ValidationError{Name: "code_challenge_method", err: errors.New(`db: missing required field "AuthCode.code_challenge_method"`)} } - if v, ok := acc.mutation.ID(); ok { + if v, ok := _c.mutation.ID(); ok { if err := authcode.IDValidator(v); err != nil { return &ValidationError{Name: "id", err: fmt.Errorf(`db: validator failed for field "AuthCode.id": %w`, err)} } @@ -312,9 +270,12 @@ func (acc *AuthCodeCreate) check() error { return nil } -func (acc *AuthCodeCreate) sqlSave(ctx context.Context) (*AuthCode, error) { - _node, _spec := acc.createSpec() - if err := sqlgraph.CreateNode(ctx, acc.driver, _spec); err != nil { +func (_c *AuthCodeCreate) sqlSave(ctx context.Context) (*AuthCode, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -327,142 +288,78 @@ func (acc *AuthCodeCreate) sqlSave(ctx context.Context) (*AuthCode, error) { return nil, fmt.Errorf("unexpected AuthCode.ID type: %T", _spec.ID.Value) } } + _c.mutation.id = &_node.ID + _c.mutation.done = true return _node, nil } -func (acc *AuthCodeCreate) createSpec() (*AuthCode, *sqlgraph.CreateSpec) { +func (_c *AuthCodeCreate) createSpec() (*AuthCode, *sqlgraph.CreateSpec) { var ( - _node = &AuthCode{config: acc.config} - _spec = &sqlgraph.CreateSpec{ - Table: authcode.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: authcode.FieldID, - }, - } + _node = &AuthCode{config: _c.config} + _spec = sqlgraph.NewCreateSpec(authcode.Table, sqlgraph.NewFieldSpec(authcode.FieldID, field.TypeString)) ) - if id, ok := acc.mutation.ID(); ok { + if id, ok := _c.mutation.ID(); ok { _node.ID = id _spec.ID.Value = id } - if value, ok := acc.mutation.ClientID(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldClientID, - }) + if value, ok := _c.mutation.ClientID(); ok { + _spec.SetField(authcode.FieldClientID, field.TypeString, value) _node.ClientID = value } - if value, ok := acc.mutation.Scopes(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: authcode.FieldScopes, - }) + if value, ok := _c.mutation.Scopes(); ok { + _spec.SetField(authcode.FieldScopes, field.TypeJSON, value) _node.Scopes = value } - if value, ok := acc.mutation.Nonce(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldNonce, - }) + if value, ok := _c.mutation.Nonce(); ok { + _spec.SetField(authcode.FieldNonce, field.TypeString, value) _node.Nonce = value } - if value, ok := acc.mutation.RedirectURI(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldRedirectURI, - }) + if value, ok := _c.mutation.RedirectURI(); ok { + _spec.SetField(authcode.FieldRedirectURI, field.TypeString, value) _node.RedirectURI = value } - if value, ok := acc.mutation.ClaimsUserID(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldClaimsUserID, - }) + if value, ok := _c.mutation.ClaimsUserID(); ok { + _spec.SetField(authcode.FieldClaimsUserID, field.TypeString, value) _node.ClaimsUserID = value } - if value, ok := acc.mutation.ClaimsUsername(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldClaimsUsername, - }) + if value, ok := _c.mutation.ClaimsUsername(); ok { + _spec.SetField(authcode.FieldClaimsUsername, field.TypeString, value) _node.ClaimsUsername = value } - if value, ok := acc.mutation.ClaimsEmail(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldClaimsEmail, - }) + if value, ok := _c.mutation.ClaimsEmail(); ok { + _spec.SetField(authcode.FieldClaimsEmail, field.TypeString, value) _node.ClaimsEmail = value } - if value, ok := acc.mutation.ClaimsEmailVerified(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeBool, - Value: value, - Column: authcode.FieldClaimsEmailVerified, - }) + if value, ok := _c.mutation.ClaimsEmailVerified(); ok { + _spec.SetField(authcode.FieldClaimsEmailVerified, field.TypeBool, value) _node.ClaimsEmailVerified = value } - if value, ok := acc.mutation.ClaimsGroups(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: authcode.FieldClaimsGroups, - }) + if value, ok := _c.mutation.ClaimsGroups(); ok { + _spec.SetField(authcode.FieldClaimsGroups, field.TypeJSON, value) _node.ClaimsGroups = value } - if value, ok := acc.mutation.ClaimsPreferredUsername(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldClaimsPreferredUsername, - }) + if value, ok := _c.mutation.ClaimsPreferredUsername(); ok { + _spec.SetField(authcode.FieldClaimsPreferredUsername, field.TypeString, value) _node.ClaimsPreferredUsername = value } - if value, ok := acc.mutation.ConnectorID(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldConnectorID, - }) + if value, ok := _c.mutation.ConnectorID(); ok { + _spec.SetField(authcode.FieldConnectorID, field.TypeString, value) _node.ConnectorID = value } - if value, ok := acc.mutation.ConnectorData(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: authcode.FieldConnectorData, - }) + if value, ok := _c.mutation.ConnectorData(); ok { + _spec.SetField(authcode.FieldConnectorData, field.TypeBytes, value) _node.ConnectorData = &value } - if value, ok := acc.mutation.Expiry(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: authcode.FieldExpiry, - }) + if value, ok := _c.mutation.Expiry(); ok { + _spec.SetField(authcode.FieldExpiry, field.TypeTime, value) _node.Expiry = value } - if value, ok := acc.mutation.CodeChallenge(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldCodeChallenge, - }) + if value, ok := _c.mutation.CodeChallenge(); ok { + _spec.SetField(authcode.FieldCodeChallenge, field.TypeString, value) _node.CodeChallenge = value } - if value, ok := acc.mutation.CodeChallengeMethod(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldCodeChallengeMethod, - }) + if value, ok := _c.mutation.CodeChallengeMethod(); ok { + _spec.SetField(authcode.FieldCodeChallengeMethod, field.TypeString, value) _node.CodeChallengeMethod = value } return _node, _spec @@ -471,17 +368,21 @@ func (acc *AuthCodeCreate) createSpec() (*AuthCode, *sqlgraph.CreateSpec) { // AuthCodeCreateBulk is the builder for creating many AuthCode entities in bulk. type AuthCodeCreateBulk struct { config + err error builders []*AuthCodeCreate } // Save creates the AuthCode entities in the database. -func (accb *AuthCodeCreateBulk) Save(ctx context.Context) ([]*AuthCode, error) { - specs := make([]*sqlgraph.CreateSpec, len(accb.builders)) - nodes := make([]*AuthCode, len(accb.builders)) - mutators := make([]Mutator, len(accb.builders)) - for i := range accb.builders { +func (_c *AuthCodeCreateBulk) Save(ctx context.Context) ([]*AuthCode, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*AuthCode, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { func(i int, root context.Context) { - builder := accb.builders[i] + builder := _c.builders[i] builder.defaults() var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { mutation, ok := m.(*AuthCodeMutation) @@ -492,14 +393,14 @@ func (accb *AuthCodeCreateBulk) Save(ctx context.Context) ([]*AuthCode, error) { return nil, err } builder.mutation = mutation - nodes[i], specs[i] = builder.createSpec() var err error + nodes[i], specs[i] = builder.createSpec() if i < len(mutators)-1 { - _, err = mutators[i+1].Mutate(root, accb.builders[i+1].mutation) + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} // Invoke the actual operation on the latest mutation in the chain. - if err = sqlgraph.BatchCreate(ctx, accb.driver, spec); err != nil { + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -519,7 +420,7 @@ func (accb *AuthCodeCreateBulk) Save(ctx context.Context) ([]*AuthCode, error) { }(i, ctx) } if len(mutators) > 0 { - if _, err := mutators[0].Mutate(ctx, accb.builders[0].mutation); err != nil { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { return nil, err } } @@ -527,8 +428,8 @@ func (accb *AuthCodeCreateBulk) Save(ctx context.Context) ([]*AuthCode, error) { } // SaveX is like Save, but panics if an error occurs. -func (accb *AuthCodeCreateBulk) SaveX(ctx context.Context) []*AuthCode { - v, err := accb.Save(ctx) +func (_c *AuthCodeCreateBulk) SaveX(ctx context.Context) []*AuthCode { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -536,14 +437,14 @@ func (accb *AuthCodeCreateBulk) SaveX(ctx context.Context) []*AuthCode { } // Exec executes the query. -func (accb *AuthCodeCreateBulk) Exec(ctx context.Context) error { - _, err := accb.Save(ctx) +func (_c *AuthCodeCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (accb *AuthCodeCreateBulk) ExecX(ctx context.Context) { - if err := accb.Exec(ctx); err != nil { +func (_c *AuthCodeCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } diff --git a/storage/ent/db/authcode_delete.go b/storage/ent/db/authcode_delete.go index 3471394ad2..8ef0a122fb 100644 --- a/storage/ent/db/authcode_delete.go +++ b/storage/ent/db/authcode_delete.go @@ -4,7 +4,6 @@ package db import ( "context" - "fmt" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" @@ -21,84 +20,56 @@ type AuthCodeDelete struct { } // Where appends a list predicates to the AuthCodeDelete builder. -func (acd *AuthCodeDelete) Where(ps ...predicate.AuthCode) *AuthCodeDelete { - acd.mutation.Where(ps...) - return acd +func (_d *AuthCodeDelete) Where(ps ...predicate.AuthCode) *AuthCodeDelete { + _d.mutation.Where(ps...) + return _d } // Exec executes the deletion query and returns how many vertices were deleted. -func (acd *AuthCodeDelete) Exec(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(acd.hooks) == 0 { - affected, err = acd.sqlExec(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*AuthCodeMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - acd.mutation = mutation - affected, err = acd.sqlExec(ctx) - mutation.done = true - return affected, err - }) - for i := len(acd.hooks) - 1; i >= 0; i-- { - if acd.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = acd.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, acd.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_d *AuthCodeDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) } // ExecX is like Exec, but panics if an error occurs. -func (acd *AuthCodeDelete) ExecX(ctx context.Context) int { - n, err := acd.Exec(ctx) +func (_d *AuthCodeDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) if err != nil { panic(err) } return n } -func (acd *AuthCodeDelete) sqlExec(ctx context.Context) (int, error) { - _spec := &sqlgraph.DeleteSpec{ - Node: &sqlgraph.NodeSpec{ - Table: authcode.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: authcode.FieldID, - }, - }, - } - if ps := acd.mutation.predicates; len(ps) > 0 { +func (_d *AuthCodeDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(authcode.Table, sqlgraph.NewFieldSpec(authcode.FieldID, field.TypeString)) + if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - affected, err := sqlgraph.DeleteNodes(ctx, acd.driver, _spec) + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) if err != nil && sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } + _d.mutation.done = true return affected, err } // AuthCodeDeleteOne is the builder for deleting a single AuthCode entity. type AuthCodeDeleteOne struct { - acd *AuthCodeDelete + _d *AuthCodeDelete +} + +// Where appends a list predicates to the AuthCodeDelete builder. +func (_d *AuthCodeDeleteOne) Where(ps ...predicate.AuthCode) *AuthCodeDeleteOne { + _d._d.mutation.Where(ps...) + return _d } // Exec executes the deletion query. -func (acdo *AuthCodeDeleteOne) Exec(ctx context.Context) error { - n, err := acdo.acd.Exec(ctx) +func (_d *AuthCodeDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) switch { case err != nil: return err @@ -110,6 +81,8 @@ func (acdo *AuthCodeDeleteOne) Exec(ctx context.Context) error { } // ExecX is like Exec, but panics if an error occurs. -func (acdo *AuthCodeDeleteOne) ExecX(ctx context.Context) { - acdo.acd.ExecX(ctx) +func (_d *AuthCodeDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } } diff --git a/storage/ent/db/authcode_query.go b/storage/ent/db/authcode_query.go index a82a450686..b7c3ae251c 100644 --- a/storage/ent/db/authcode_query.go +++ b/storage/ent/db/authcode_query.go @@ -7,6 +7,7 @@ import ( "fmt" "math" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" @@ -17,11 +18,9 @@ import ( // AuthCodeQuery is the builder for querying AuthCode entities. type AuthCodeQuery struct { config - limit *int - offset *int - unique *bool - order []OrderFunc - fields []string + ctx *QueryContext + order []authcode.OrderOption + inters []Interceptor predicates []predicate.AuthCode // intermediate query (i.e. traversal path). sql *sql.Selector @@ -29,40 +28,40 @@ type AuthCodeQuery struct { } // Where adds a new predicate for the AuthCodeQuery builder. -func (acq *AuthCodeQuery) Where(ps ...predicate.AuthCode) *AuthCodeQuery { - acq.predicates = append(acq.predicates, ps...) - return acq +func (_q *AuthCodeQuery) Where(ps ...predicate.AuthCode) *AuthCodeQuery { + _q.predicates = append(_q.predicates, ps...) + return _q } -// Limit adds a limit step to the query. -func (acq *AuthCodeQuery) Limit(limit int) *AuthCodeQuery { - acq.limit = &limit - return acq +// Limit the number of records to be returned by this query. +func (_q *AuthCodeQuery) Limit(limit int) *AuthCodeQuery { + _q.ctx.Limit = &limit + return _q } -// Offset adds an offset step to the query. -func (acq *AuthCodeQuery) Offset(offset int) *AuthCodeQuery { - acq.offset = &offset - return acq +// Offset to start from. +func (_q *AuthCodeQuery) Offset(offset int) *AuthCodeQuery { + _q.ctx.Offset = &offset + return _q } // Unique configures the query builder to filter duplicate records on query. // By default, unique is set to true, and can be disabled using this method. -func (acq *AuthCodeQuery) Unique(unique bool) *AuthCodeQuery { - acq.unique = &unique - return acq +func (_q *AuthCodeQuery) Unique(unique bool) *AuthCodeQuery { + _q.ctx.Unique = &unique + return _q } -// Order adds an order step to the query. -func (acq *AuthCodeQuery) Order(o ...OrderFunc) *AuthCodeQuery { - acq.order = append(acq.order, o...) - return acq +// Order specifies how the records should be ordered. +func (_q *AuthCodeQuery) Order(o ...authcode.OrderOption) *AuthCodeQuery { + _q.order = append(_q.order, o...) + return _q } // First returns the first AuthCode entity from the query. // Returns a *NotFoundError when no AuthCode was found. -func (acq *AuthCodeQuery) First(ctx context.Context) (*AuthCode, error) { - nodes, err := acq.Limit(1).All(ctx) +func (_q *AuthCodeQuery) First(ctx context.Context) (*AuthCode, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) if err != nil { return nil, err } @@ -73,8 +72,8 @@ func (acq *AuthCodeQuery) First(ctx context.Context) (*AuthCode, error) { } // FirstX is like First, but panics if an error occurs. -func (acq *AuthCodeQuery) FirstX(ctx context.Context) *AuthCode { - node, err := acq.First(ctx) +func (_q *AuthCodeQuery) FirstX(ctx context.Context) *AuthCode { + node, err := _q.First(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -83,9 +82,9 @@ func (acq *AuthCodeQuery) FirstX(ctx context.Context) *AuthCode { // FirstID returns the first AuthCode ID from the query. // Returns a *NotFoundError when no AuthCode ID was found. -func (acq *AuthCodeQuery) FirstID(ctx context.Context) (id string, err error) { +func (_q *AuthCodeQuery) FirstID(ctx context.Context) (id string, err error) { var ids []string - if ids, err = acq.Limit(1).IDs(ctx); err != nil { + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { return } if len(ids) == 0 { @@ -96,8 +95,8 @@ func (acq *AuthCodeQuery) FirstID(ctx context.Context) (id string, err error) { } // FirstIDX is like FirstID, but panics if an error occurs. -func (acq *AuthCodeQuery) FirstIDX(ctx context.Context) string { - id, err := acq.FirstID(ctx) +func (_q *AuthCodeQuery) FirstIDX(ctx context.Context) string { + id, err := _q.FirstID(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -107,8 +106,8 @@ func (acq *AuthCodeQuery) FirstIDX(ctx context.Context) string { // Only returns a single AuthCode entity found by the query, ensuring it only returns one. // Returns a *NotSingularError when more than one AuthCode entity is found. // Returns a *NotFoundError when no AuthCode entities are found. -func (acq *AuthCodeQuery) Only(ctx context.Context) (*AuthCode, error) { - nodes, err := acq.Limit(2).All(ctx) +func (_q *AuthCodeQuery) Only(ctx context.Context) (*AuthCode, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) if err != nil { return nil, err } @@ -123,8 +122,8 @@ func (acq *AuthCodeQuery) Only(ctx context.Context) (*AuthCode, error) { } // OnlyX is like Only, but panics if an error occurs. -func (acq *AuthCodeQuery) OnlyX(ctx context.Context) *AuthCode { - node, err := acq.Only(ctx) +func (_q *AuthCodeQuery) OnlyX(ctx context.Context) *AuthCode { + node, err := _q.Only(ctx) if err != nil { panic(err) } @@ -134,9 +133,9 @@ func (acq *AuthCodeQuery) OnlyX(ctx context.Context) *AuthCode { // OnlyID is like Only, but returns the only AuthCode ID in the query. // Returns a *NotSingularError when more than one AuthCode ID is found. // Returns a *NotFoundError when no entities are found. -func (acq *AuthCodeQuery) OnlyID(ctx context.Context) (id string, err error) { +func (_q *AuthCodeQuery) OnlyID(ctx context.Context) (id string, err error) { var ids []string - if ids, err = acq.Limit(2).IDs(ctx); err != nil { + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { return } switch len(ids) { @@ -151,8 +150,8 @@ func (acq *AuthCodeQuery) OnlyID(ctx context.Context) (id string, err error) { } // OnlyIDX is like OnlyID, but panics if an error occurs. -func (acq *AuthCodeQuery) OnlyIDX(ctx context.Context) string { - id, err := acq.OnlyID(ctx) +func (_q *AuthCodeQuery) OnlyIDX(ctx context.Context) string { + id, err := _q.OnlyID(ctx) if err != nil { panic(err) } @@ -160,16 +159,18 @@ func (acq *AuthCodeQuery) OnlyIDX(ctx context.Context) string { } // All executes the query and returns a list of AuthCodes. -func (acq *AuthCodeQuery) All(ctx context.Context) ([]*AuthCode, error) { - if err := acq.prepareQuery(ctx); err != nil { +func (_q *AuthCodeQuery) All(ctx context.Context) ([]*AuthCode, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { return nil, err } - return acq.sqlAll(ctx) + qr := querierAll[[]*AuthCode, *AuthCodeQuery]() + return withInterceptors[[]*AuthCode](ctx, _q, qr, _q.inters) } // AllX is like All, but panics if an error occurs. -func (acq *AuthCodeQuery) AllX(ctx context.Context) []*AuthCode { - nodes, err := acq.All(ctx) +func (_q *AuthCodeQuery) AllX(ctx context.Context) []*AuthCode { + nodes, err := _q.All(ctx) if err != nil { panic(err) } @@ -177,17 +178,20 @@ func (acq *AuthCodeQuery) AllX(ctx context.Context) []*AuthCode { } // IDs executes the query and returns a list of AuthCode IDs. -func (acq *AuthCodeQuery) IDs(ctx context.Context) ([]string, error) { - var ids []string - if err := acq.Select(authcode.FieldID).Scan(ctx, &ids); err != nil { +func (_q *AuthCodeQuery) IDs(ctx context.Context) (ids []string, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(authcode.FieldID).Scan(ctx, &ids); err != nil { return nil, err } return ids, nil } // IDsX is like IDs, but panics if an error occurs. -func (acq *AuthCodeQuery) IDsX(ctx context.Context) []string { - ids, err := acq.IDs(ctx) +func (_q *AuthCodeQuery) IDsX(ctx context.Context) []string { + ids, err := _q.IDs(ctx) if err != nil { panic(err) } @@ -195,16 +199,17 @@ func (acq *AuthCodeQuery) IDsX(ctx context.Context) []string { } // Count returns the count of the given query. -func (acq *AuthCodeQuery) Count(ctx context.Context) (int, error) { - if err := acq.prepareQuery(ctx); err != nil { +func (_q *AuthCodeQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { return 0, err } - return acq.sqlCount(ctx) + return withInterceptors[int](ctx, _q, querierCount[*AuthCodeQuery](), _q.inters) } // CountX is like Count, but panics if an error occurs. -func (acq *AuthCodeQuery) CountX(ctx context.Context) int { - count, err := acq.Count(ctx) +func (_q *AuthCodeQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) if err != nil { panic(err) } @@ -212,16 +217,21 @@ func (acq *AuthCodeQuery) CountX(ctx context.Context) int { } // Exist returns true if the query has elements in the graph. -func (acq *AuthCodeQuery) Exist(ctx context.Context) (bool, error) { - if err := acq.prepareQuery(ctx); err != nil { - return false, err +func (_q *AuthCodeQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("db: check existence: %w", err) + default: + return true, nil } - return acq.sqlExist(ctx) } // ExistX is like Exist, but panics if an error occurs. -func (acq *AuthCodeQuery) ExistX(ctx context.Context) bool { - exist, err := acq.Exist(ctx) +func (_q *AuthCodeQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) if err != nil { panic(err) } @@ -230,20 +240,19 @@ func (acq *AuthCodeQuery) ExistX(ctx context.Context) bool { // Clone returns a duplicate of the AuthCodeQuery builder, including all associated steps. It can be // used to prepare common query builders and use them differently after the clone is made. -func (acq *AuthCodeQuery) Clone() *AuthCodeQuery { - if acq == nil { +func (_q *AuthCodeQuery) Clone() *AuthCodeQuery { + if _q == nil { return nil } return &AuthCodeQuery{ - config: acq.config, - limit: acq.limit, - offset: acq.offset, - order: append([]OrderFunc{}, acq.order...), - predicates: append([]predicate.AuthCode{}, acq.predicates...), + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]authcode.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.AuthCode{}, _q.predicates...), // clone intermediate query. - sql: acq.sql.Clone(), - path: acq.path, - unique: acq.unique, + sql: _q.sql.Clone(), + path: _q.path, } } @@ -261,18 +270,12 @@ func (acq *AuthCodeQuery) Clone() *AuthCodeQuery { // GroupBy(authcode.FieldClientID). // Aggregate(db.Count()). // Scan(ctx, &v) -// -func (acq *AuthCodeQuery) GroupBy(field string, fields ...string) *AuthCodeGroupBy { - grbuild := &AuthCodeGroupBy{config: acq.config} - grbuild.fields = append([]string{field}, fields...) - grbuild.path = func(ctx context.Context) (prev *sql.Selector, err error) { - if err := acq.prepareQuery(ctx); err != nil { - return nil, err - } - return acq.sqlQuery(ctx), nil - } +func (_q *AuthCodeQuery) GroupBy(field string, fields ...string) *AuthCodeGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &AuthCodeGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields grbuild.label = authcode.Label - grbuild.flds, grbuild.scan = &grbuild.fields, grbuild.Scan + grbuild.scan = grbuild.Scan return grbuild } @@ -288,48 +291,62 @@ func (acq *AuthCodeQuery) GroupBy(field string, fields ...string) *AuthCodeGroup // client.AuthCode.Query(). // Select(authcode.FieldClientID). // Scan(ctx, &v) -// -func (acq *AuthCodeQuery) Select(fields ...string) *AuthCodeSelect { - acq.fields = append(acq.fields, fields...) - selbuild := &AuthCodeSelect{AuthCodeQuery: acq} - selbuild.label = authcode.Label - selbuild.flds, selbuild.scan = &acq.fields, selbuild.Scan - return selbuild +func (_q *AuthCodeQuery) Select(fields ...string) *AuthCodeSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &AuthCodeSelect{AuthCodeQuery: _q} + sbuild.label = authcode.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a AuthCodeSelect configured with the given aggregations. +func (_q *AuthCodeQuery) Aggregate(fns ...AggregateFunc) *AuthCodeSelect { + return _q.Select().Aggregate(fns...) } -func (acq *AuthCodeQuery) prepareQuery(ctx context.Context) error { - for _, f := range acq.fields { +func (_q *AuthCodeQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("db: uninitialized interceptor (forgotten import db/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { if !authcode.ValidColumn(f) { return &ValidationError{Name: f, err: fmt.Errorf("db: invalid field %q for query", f)} } } - if acq.path != nil { - prev, err := acq.path(ctx) + if _q.path != nil { + prev, err := _q.path(ctx) if err != nil { return err } - acq.sql = prev + _q.sql = prev } return nil } -func (acq *AuthCodeQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*AuthCode, error) { +func (_q *AuthCodeQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*AuthCode, error) { var ( nodes = []*AuthCode{} - _spec = acq.querySpec() + _spec = _q.querySpec() ) - _spec.ScanValues = func(columns []string) ([]interface{}, error) { + _spec.ScanValues = func(columns []string) ([]any, error) { return (*AuthCode).scanValues(nil, columns) } - _spec.Assign = func(columns []string, values []interface{}) error { - node := &AuthCode{config: acq.config} + _spec.Assign = func(columns []string, values []any) error { + node := &AuthCode{config: _q.config} nodes = append(nodes, node) return node.assignValues(columns, values) } for i := range hooks { hooks[i](ctx, _spec) } - if err := sqlgraph.QueryNodes(ctx, acq.driver, _spec); err != nil { + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { return nil, err } if len(nodes) == 0 { @@ -338,40 +355,24 @@ func (acq *AuthCodeQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Au return nodes, nil } -func (acq *AuthCodeQuery) sqlCount(ctx context.Context) (int, error) { - _spec := acq.querySpec() - _spec.Node.Columns = acq.fields - if len(acq.fields) > 0 { - _spec.Unique = acq.unique != nil && *acq.unique - } - return sqlgraph.CountNodes(ctx, acq.driver, _spec) -} - -func (acq *AuthCodeQuery) sqlExist(ctx context.Context) (bool, error) { - n, err := acq.sqlCount(ctx) - if err != nil { - return false, fmt.Errorf("db: check existence: %w", err) +func (_q *AuthCodeQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique } - return n > 0, nil + return sqlgraph.CountNodes(ctx, _q.driver, _spec) } -func (acq *AuthCodeQuery) querySpec() *sqlgraph.QuerySpec { - _spec := &sqlgraph.QuerySpec{ - Node: &sqlgraph.NodeSpec{ - Table: authcode.Table, - Columns: authcode.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: authcode.FieldID, - }, - }, - From: acq.sql, - Unique: true, - } - if unique := acq.unique; unique != nil { +func (_q *AuthCodeQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(authcode.Table, authcode.Columns, sqlgraph.NewFieldSpec(authcode.FieldID, field.TypeString)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true } - if fields := acq.fields; len(fields) > 0 { + if fields := _q.ctx.Fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, authcode.FieldID) for i := range fields { @@ -380,20 +381,20 @@ func (acq *AuthCodeQuery) querySpec() *sqlgraph.QuerySpec { } } } - if ps := acq.predicates; len(ps) > 0 { + if ps := _q.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if limit := acq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { _spec.Limit = *limit } - if offset := acq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { _spec.Offset = *offset } - if ps := acq.order; len(ps) > 0 { + if ps := _q.order; len(ps) > 0 { _spec.Order = func(selector *sql.Selector) { for i := range ps { ps[i](selector) @@ -403,33 +404,33 @@ func (acq *AuthCodeQuery) querySpec() *sqlgraph.QuerySpec { return _spec } -func (acq *AuthCodeQuery) sqlQuery(ctx context.Context) *sql.Selector { - builder := sql.Dialect(acq.driver.Dialect()) +func (_q *AuthCodeQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) t1 := builder.Table(authcode.Table) - columns := acq.fields + columns := _q.ctx.Fields if len(columns) == 0 { columns = authcode.Columns } selector := builder.Select(t1.Columns(columns...)...).From(t1) - if acq.sql != nil { - selector = acq.sql + if _q.sql != nil { + selector = _q.sql selector.Select(selector.Columns(columns...)...) } - if acq.unique != nil && *acq.unique { + if _q.ctx.Unique != nil && *_q.ctx.Unique { selector.Distinct() } - for _, p := range acq.predicates { + for _, p := range _q.predicates { p(selector) } - for _, p := range acq.order { + for _, p := range _q.order { p(selector) } - if offset := acq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { // limit is mandatory for offset clause. We start // with default value, and override it below if needed. selector.Offset(*offset).Limit(math.MaxInt32) } - if limit := acq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { selector.Limit(*limit) } return selector @@ -437,90 +438,88 @@ func (acq *AuthCodeQuery) sqlQuery(ctx context.Context) *sql.Selector { // AuthCodeGroupBy is the group-by builder for AuthCode entities. type AuthCodeGroupBy struct { - config selector - fields []string - fns []AggregateFunc - // intermediate query (i.e. traversal path). - sql *sql.Selector - path func(context.Context) (*sql.Selector, error) + build *AuthCodeQuery } // Aggregate adds the given aggregation functions to the group-by query. -func (acgb *AuthCodeGroupBy) Aggregate(fns ...AggregateFunc) *AuthCodeGroupBy { - acgb.fns = append(acgb.fns, fns...) - return acgb +func (_g *AuthCodeGroupBy) Aggregate(fns ...AggregateFunc) *AuthCodeGroupBy { + _g.fns = append(_g.fns, fns...) + return _g } -// Scan applies the group-by query and scans the result into the given value. -func (acgb *AuthCodeGroupBy) Scan(ctx context.Context, v interface{}) error { - query, err := acgb.path(ctx) - if err != nil { +// Scan applies the selector query and scans the result into the given value. +func (_g *AuthCodeGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { return err } - acgb.sql = query - return acgb.sqlScan(ctx, v) + return scanWithInterceptors[*AuthCodeQuery, *AuthCodeGroupBy](ctx, _g.build, _g, _g.build.inters, v) } -func (acgb *AuthCodeGroupBy) sqlScan(ctx context.Context, v interface{}) error { - for _, f := range acgb.fields { - if !authcode.ValidColumn(f) { - return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)} +func (_g *AuthCodeGroupBy) sqlScan(ctx context.Context, root *AuthCodeQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) } + columns = append(columns, aggregation...) + selector.Select(columns...) } - selector := acgb.sqlQuery() + selector.GroupBy(selector.Columns(*_g.flds...)...) if err := selector.Err(); err != nil { return err } rows := &sql.Rows{} query, args := selector.Query() - if err := acgb.driver.Query(ctx, query, args, rows); err != nil { + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() return sql.ScanSlice(rows, v) } -func (acgb *AuthCodeGroupBy) sqlQuery() *sql.Selector { - selector := acgb.sql.Select() - aggregation := make([]string, 0, len(acgb.fns)) - for _, fn := range acgb.fns { - aggregation = append(aggregation, fn(selector)) - } - // If no columns were selected in a custom aggregation function, the default - // selection is the fields used for "group-by", and the aggregation functions. - if len(selector.SelectedColumns()) == 0 { - columns := make([]string, 0, len(acgb.fields)+len(acgb.fns)) - for _, f := range acgb.fields { - columns = append(columns, selector.C(f)) - } - columns = append(columns, aggregation...) - selector.Select(columns...) - } - return selector.GroupBy(selector.Columns(acgb.fields...)...) -} - // AuthCodeSelect is the builder for selecting fields of AuthCode entities. type AuthCodeSelect struct { *AuthCodeQuery selector - // intermediate query (i.e. traversal path). - sql *sql.Selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *AuthCodeSelect) Aggregate(fns ...AggregateFunc) *AuthCodeSelect { + _s.fns = append(_s.fns, fns...) + return _s } // Scan applies the selector query and scans the result into the given value. -func (acs *AuthCodeSelect) Scan(ctx context.Context, v interface{}) error { - if err := acs.prepareQuery(ctx); err != nil { +func (_s *AuthCodeSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { return err } - acs.sql = acs.AuthCodeQuery.sqlQuery(ctx) - return acs.sqlScan(ctx, v) + return scanWithInterceptors[*AuthCodeQuery, *AuthCodeSelect](ctx, _s.AuthCodeQuery, _s, _s.inters, v) } -func (acs *AuthCodeSelect) sqlScan(ctx context.Context, v interface{}) error { +func (_s *AuthCodeSelect) sqlScan(ctx context.Context, root *AuthCodeQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } rows := &sql.Rows{} - query, args := acs.sql.Query() - if err := acs.driver.Query(ctx, query, args, rows); err != nil { + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() diff --git a/storage/ent/db/authcode_update.go b/storage/ent/db/authcode_update.go index 5d9764bcf4..7b7e186e87 100644 --- a/storage/ent/db/authcode_update.go +++ b/storage/ent/db/authcode_update.go @@ -10,6 +10,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/dialect/sql/sqljson" "entgo.io/ent/schema/field" "github.com/dexidp/dex/storage/ent/db/authcode" "github.com/dexidp/dex/storage/ent/db/predicate" @@ -23,189 +24,240 @@ type AuthCodeUpdate struct { } // Where appends a list predicates to the AuthCodeUpdate builder. -func (acu *AuthCodeUpdate) Where(ps ...predicate.AuthCode) *AuthCodeUpdate { - acu.mutation.Where(ps...) - return acu +func (_u *AuthCodeUpdate) Where(ps ...predicate.AuthCode) *AuthCodeUpdate { + _u.mutation.Where(ps...) + return _u } // SetClientID sets the "client_id" field. -func (acu *AuthCodeUpdate) SetClientID(s string) *AuthCodeUpdate { - acu.mutation.SetClientID(s) - return acu +func (_u *AuthCodeUpdate) SetClientID(v string) *AuthCodeUpdate { + _u.mutation.SetClientID(v) + return _u +} + +// SetNillableClientID sets the "client_id" field if the given value is not nil. +func (_u *AuthCodeUpdate) SetNillableClientID(v *string) *AuthCodeUpdate { + if v != nil { + _u.SetClientID(*v) + } + return _u } // SetScopes sets the "scopes" field. -func (acu *AuthCodeUpdate) SetScopes(s []string) *AuthCodeUpdate { - acu.mutation.SetScopes(s) - return acu +func (_u *AuthCodeUpdate) SetScopes(v []string) *AuthCodeUpdate { + _u.mutation.SetScopes(v) + return _u +} + +// AppendScopes appends value to the "scopes" field. +func (_u *AuthCodeUpdate) AppendScopes(v []string) *AuthCodeUpdate { + _u.mutation.AppendScopes(v) + return _u } // ClearScopes clears the value of the "scopes" field. -func (acu *AuthCodeUpdate) ClearScopes() *AuthCodeUpdate { - acu.mutation.ClearScopes() - return acu +func (_u *AuthCodeUpdate) ClearScopes() *AuthCodeUpdate { + _u.mutation.ClearScopes() + return _u } // SetNonce sets the "nonce" field. -func (acu *AuthCodeUpdate) SetNonce(s string) *AuthCodeUpdate { - acu.mutation.SetNonce(s) - return acu +func (_u *AuthCodeUpdate) SetNonce(v string) *AuthCodeUpdate { + _u.mutation.SetNonce(v) + return _u +} + +// SetNillableNonce sets the "nonce" field if the given value is not nil. +func (_u *AuthCodeUpdate) SetNillableNonce(v *string) *AuthCodeUpdate { + if v != nil { + _u.SetNonce(*v) + } + return _u } // SetRedirectURI sets the "redirect_uri" field. -func (acu *AuthCodeUpdate) SetRedirectURI(s string) *AuthCodeUpdate { - acu.mutation.SetRedirectURI(s) - return acu +func (_u *AuthCodeUpdate) SetRedirectURI(v string) *AuthCodeUpdate { + _u.mutation.SetRedirectURI(v) + return _u +} + +// SetNillableRedirectURI sets the "redirect_uri" field if the given value is not nil. +func (_u *AuthCodeUpdate) SetNillableRedirectURI(v *string) *AuthCodeUpdate { + if v != nil { + _u.SetRedirectURI(*v) + } + return _u } // SetClaimsUserID sets the "claims_user_id" field. -func (acu *AuthCodeUpdate) SetClaimsUserID(s string) *AuthCodeUpdate { - acu.mutation.SetClaimsUserID(s) - return acu +func (_u *AuthCodeUpdate) SetClaimsUserID(v string) *AuthCodeUpdate { + _u.mutation.SetClaimsUserID(v) + return _u +} + +// SetNillableClaimsUserID sets the "claims_user_id" field if the given value is not nil. +func (_u *AuthCodeUpdate) SetNillableClaimsUserID(v *string) *AuthCodeUpdate { + if v != nil { + _u.SetClaimsUserID(*v) + } + return _u } // SetClaimsUsername sets the "claims_username" field. -func (acu *AuthCodeUpdate) SetClaimsUsername(s string) *AuthCodeUpdate { - acu.mutation.SetClaimsUsername(s) - return acu +func (_u *AuthCodeUpdate) SetClaimsUsername(v string) *AuthCodeUpdate { + _u.mutation.SetClaimsUsername(v) + return _u +} + +// SetNillableClaimsUsername sets the "claims_username" field if the given value is not nil. +func (_u *AuthCodeUpdate) SetNillableClaimsUsername(v *string) *AuthCodeUpdate { + if v != nil { + _u.SetClaimsUsername(*v) + } + return _u } // SetClaimsEmail sets the "claims_email" field. -func (acu *AuthCodeUpdate) SetClaimsEmail(s string) *AuthCodeUpdate { - acu.mutation.SetClaimsEmail(s) - return acu +func (_u *AuthCodeUpdate) SetClaimsEmail(v string) *AuthCodeUpdate { + _u.mutation.SetClaimsEmail(v) + return _u +} + +// SetNillableClaimsEmail sets the "claims_email" field if the given value is not nil. +func (_u *AuthCodeUpdate) SetNillableClaimsEmail(v *string) *AuthCodeUpdate { + if v != nil { + _u.SetClaimsEmail(*v) + } + return _u } // SetClaimsEmailVerified sets the "claims_email_verified" field. -func (acu *AuthCodeUpdate) SetClaimsEmailVerified(b bool) *AuthCodeUpdate { - acu.mutation.SetClaimsEmailVerified(b) - return acu +func (_u *AuthCodeUpdate) SetClaimsEmailVerified(v bool) *AuthCodeUpdate { + _u.mutation.SetClaimsEmailVerified(v) + return _u +} + +// SetNillableClaimsEmailVerified sets the "claims_email_verified" field if the given value is not nil. +func (_u *AuthCodeUpdate) SetNillableClaimsEmailVerified(v *bool) *AuthCodeUpdate { + if v != nil { + _u.SetClaimsEmailVerified(*v) + } + return _u } // SetClaimsGroups sets the "claims_groups" field. -func (acu *AuthCodeUpdate) SetClaimsGroups(s []string) *AuthCodeUpdate { - acu.mutation.SetClaimsGroups(s) - return acu +func (_u *AuthCodeUpdate) SetClaimsGroups(v []string) *AuthCodeUpdate { + _u.mutation.SetClaimsGroups(v) + return _u +} + +// AppendClaimsGroups appends value to the "claims_groups" field. +func (_u *AuthCodeUpdate) AppendClaimsGroups(v []string) *AuthCodeUpdate { + _u.mutation.AppendClaimsGroups(v) + return _u } // ClearClaimsGroups clears the value of the "claims_groups" field. -func (acu *AuthCodeUpdate) ClearClaimsGroups() *AuthCodeUpdate { - acu.mutation.ClearClaimsGroups() - return acu +func (_u *AuthCodeUpdate) ClearClaimsGroups() *AuthCodeUpdate { + _u.mutation.ClearClaimsGroups() + return _u } // SetClaimsPreferredUsername sets the "claims_preferred_username" field. -func (acu *AuthCodeUpdate) SetClaimsPreferredUsername(s string) *AuthCodeUpdate { - acu.mutation.SetClaimsPreferredUsername(s) - return acu +func (_u *AuthCodeUpdate) SetClaimsPreferredUsername(v string) *AuthCodeUpdate { + _u.mutation.SetClaimsPreferredUsername(v) + return _u } // SetNillableClaimsPreferredUsername sets the "claims_preferred_username" field if the given value is not nil. -func (acu *AuthCodeUpdate) SetNillableClaimsPreferredUsername(s *string) *AuthCodeUpdate { - if s != nil { - acu.SetClaimsPreferredUsername(*s) +func (_u *AuthCodeUpdate) SetNillableClaimsPreferredUsername(v *string) *AuthCodeUpdate { + if v != nil { + _u.SetClaimsPreferredUsername(*v) } - return acu + return _u } // SetConnectorID sets the "connector_id" field. -func (acu *AuthCodeUpdate) SetConnectorID(s string) *AuthCodeUpdate { - acu.mutation.SetConnectorID(s) - return acu +func (_u *AuthCodeUpdate) SetConnectorID(v string) *AuthCodeUpdate { + _u.mutation.SetConnectorID(v) + return _u +} + +// SetNillableConnectorID sets the "connector_id" field if the given value is not nil. +func (_u *AuthCodeUpdate) SetNillableConnectorID(v *string) *AuthCodeUpdate { + if v != nil { + _u.SetConnectorID(*v) + } + return _u } // SetConnectorData sets the "connector_data" field. -func (acu *AuthCodeUpdate) SetConnectorData(b []byte) *AuthCodeUpdate { - acu.mutation.SetConnectorData(b) - return acu +func (_u *AuthCodeUpdate) SetConnectorData(v []byte) *AuthCodeUpdate { + _u.mutation.SetConnectorData(v) + return _u } // ClearConnectorData clears the value of the "connector_data" field. -func (acu *AuthCodeUpdate) ClearConnectorData() *AuthCodeUpdate { - acu.mutation.ClearConnectorData() - return acu +func (_u *AuthCodeUpdate) ClearConnectorData() *AuthCodeUpdate { + _u.mutation.ClearConnectorData() + return _u } // SetExpiry sets the "expiry" field. -func (acu *AuthCodeUpdate) SetExpiry(t time.Time) *AuthCodeUpdate { - acu.mutation.SetExpiry(t) - return acu +func (_u *AuthCodeUpdate) SetExpiry(v time.Time) *AuthCodeUpdate { + _u.mutation.SetExpiry(v) + return _u +} + +// SetNillableExpiry sets the "expiry" field if the given value is not nil. +func (_u *AuthCodeUpdate) SetNillableExpiry(v *time.Time) *AuthCodeUpdate { + if v != nil { + _u.SetExpiry(*v) + } + return _u } // SetCodeChallenge sets the "code_challenge" field. -func (acu *AuthCodeUpdate) SetCodeChallenge(s string) *AuthCodeUpdate { - acu.mutation.SetCodeChallenge(s) - return acu +func (_u *AuthCodeUpdate) SetCodeChallenge(v string) *AuthCodeUpdate { + _u.mutation.SetCodeChallenge(v) + return _u } // SetNillableCodeChallenge sets the "code_challenge" field if the given value is not nil. -func (acu *AuthCodeUpdate) SetNillableCodeChallenge(s *string) *AuthCodeUpdate { - if s != nil { - acu.SetCodeChallenge(*s) +func (_u *AuthCodeUpdate) SetNillableCodeChallenge(v *string) *AuthCodeUpdate { + if v != nil { + _u.SetCodeChallenge(*v) } - return acu + return _u } // SetCodeChallengeMethod sets the "code_challenge_method" field. -func (acu *AuthCodeUpdate) SetCodeChallengeMethod(s string) *AuthCodeUpdate { - acu.mutation.SetCodeChallengeMethod(s) - return acu +func (_u *AuthCodeUpdate) SetCodeChallengeMethod(v string) *AuthCodeUpdate { + _u.mutation.SetCodeChallengeMethod(v) + return _u } // SetNillableCodeChallengeMethod sets the "code_challenge_method" field if the given value is not nil. -func (acu *AuthCodeUpdate) SetNillableCodeChallengeMethod(s *string) *AuthCodeUpdate { - if s != nil { - acu.SetCodeChallengeMethod(*s) +func (_u *AuthCodeUpdate) SetNillableCodeChallengeMethod(v *string) *AuthCodeUpdate { + if v != nil { + _u.SetCodeChallengeMethod(*v) } - return acu + return _u } // Mutation returns the AuthCodeMutation object of the builder. -func (acu *AuthCodeUpdate) Mutation() *AuthCodeMutation { - return acu.mutation +func (_u *AuthCodeUpdate) Mutation() *AuthCodeMutation { + return _u.mutation } // Save executes the query and returns the number of nodes affected by the update operation. -func (acu *AuthCodeUpdate) Save(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(acu.hooks) == 0 { - if err = acu.check(); err != nil { - return 0, err - } - affected, err = acu.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*AuthCodeMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = acu.check(); err != nil { - return 0, err - } - acu.mutation = mutation - affected, err = acu.sqlSave(ctx) - mutation.done = true - return affected, err - }) - for i := len(acu.hooks) - 1; i >= 0; i-- { - if acu.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = acu.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, acu.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_u *AuthCodeUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (acu *AuthCodeUpdate) SaveX(ctx context.Context) int { - affected, err := acu.Save(ctx) +func (_u *AuthCodeUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) if err != nil { panic(err) } @@ -213,51 +265,51 @@ func (acu *AuthCodeUpdate) SaveX(ctx context.Context) int { } // Exec executes the query. -func (acu *AuthCodeUpdate) Exec(ctx context.Context) error { - _, err := acu.Save(ctx) +func (_u *AuthCodeUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (acu *AuthCodeUpdate) ExecX(ctx context.Context) { - if err := acu.Exec(ctx); err != nil { +func (_u *AuthCodeUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (acu *AuthCodeUpdate) check() error { - if v, ok := acu.mutation.ClientID(); ok { +func (_u *AuthCodeUpdate) check() error { + if v, ok := _u.mutation.ClientID(); ok { if err := authcode.ClientIDValidator(v); err != nil { return &ValidationError{Name: "client_id", err: fmt.Errorf(`db: validator failed for field "AuthCode.client_id": %w`, err)} } } - if v, ok := acu.mutation.Nonce(); ok { + if v, ok := _u.mutation.Nonce(); ok { if err := authcode.NonceValidator(v); err != nil { return &ValidationError{Name: "nonce", err: fmt.Errorf(`db: validator failed for field "AuthCode.nonce": %w`, err)} } } - if v, ok := acu.mutation.RedirectURI(); ok { + if v, ok := _u.mutation.RedirectURI(); ok { if err := authcode.RedirectURIValidator(v); err != nil { return &ValidationError{Name: "redirect_uri", err: fmt.Errorf(`db: validator failed for field "AuthCode.redirect_uri": %w`, err)} } } - if v, ok := acu.mutation.ClaimsUserID(); ok { + if v, ok := _u.mutation.ClaimsUserID(); ok { if err := authcode.ClaimsUserIDValidator(v); err != nil { return &ValidationError{Name: "claims_user_id", err: fmt.Errorf(`db: validator failed for field "AuthCode.claims_user_id": %w`, err)} } } - if v, ok := acu.mutation.ClaimsUsername(); ok { + if v, ok := _u.mutation.ClaimsUsername(); ok { if err := authcode.ClaimsUsernameValidator(v); err != nil { return &ValidationError{Name: "claims_username", err: fmt.Errorf(`db: validator failed for field "AuthCode.claims_username": %w`, err)} } } - if v, ok := acu.mutation.ClaimsEmail(); ok { + if v, ok := _u.mutation.ClaimsEmail(); ok { if err := authcode.ClaimsEmailValidator(v); err != nil { return &ValidationError{Name: "claims_email", err: fmt.Errorf(`db: validator failed for field "AuthCode.claims_email": %w`, err)} } } - if v, ok := acu.mutation.ConnectorID(); ok { + if v, ok := _u.mutation.ConnectorID(); ok { if err := authcode.ConnectorIDValidator(v); err != nil { return &ValidationError{Name: "connector_id", err: fmt.Errorf(`db: validator failed for field "AuthCode.connector_id": %w`, err)} } @@ -265,148 +317,83 @@ func (acu *AuthCodeUpdate) check() error { return nil } -func (acu *AuthCodeUpdate) sqlSave(ctx context.Context) (n int, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: authcode.Table, - Columns: authcode.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: authcode.FieldID, - }, - }, +func (_u *AuthCodeUpdate) sqlSave(ctx context.Context) (_node int, err error) { + if err := _u.check(); err != nil { + return _node, err } - if ps := acu.mutation.predicates; len(ps) > 0 { + _spec := sqlgraph.NewUpdateSpec(authcode.Table, authcode.Columns, sqlgraph.NewFieldSpec(authcode.FieldID, field.TypeString)) + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := acu.mutation.ClientID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldClientID, - }) + if value, ok := _u.mutation.ClientID(); ok { + _spec.SetField(authcode.FieldClientID, field.TypeString, value) } - if value, ok := acu.mutation.Scopes(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: authcode.FieldScopes, - }) + if value, ok := _u.mutation.Scopes(); ok { + _spec.SetField(authcode.FieldScopes, field.TypeJSON, value) } - if acu.mutation.ScopesCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: authcode.FieldScopes, + if value, ok := _u.mutation.AppendedScopes(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, authcode.FieldScopes, value) }) } - if value, ok := acu.mutation.Nonce(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldNonce, - }) + if _u.mutation.ScopesCleared() { + _spec.ClearField(authcode.FieldScopes, field.TypeJSON) } - if value, ok := acu.mutation.RedirectURI(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldRedirectURI, - }) + if value, ok := _u.mutation.Nonce(); ok { + _spec.SetField(authcode.FieldNonce, field.TypeString, value) } - if value, ok := acu.mutation.ClaimsUserID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldClaimsUserID, - }) + if value, ok := _u.mutation.RedirectURI(); ok { + _spec.SetField(authcode.FieldRedirectURI, field.TypeString, value) } - if value, ok := acu.mutation.ClaimsUsername(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldClaimsUsername, - }) + if value, ok := _u.mutation.ClaimsUserID(); ok { + _spec.SetField(authcode.FieldClaimsUserID, field.TypeString, value) } - if value, ok := acu.mutation.ClaimsEmail(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldClaimsEmail, - }) + if value, ok := _u.mutation.ClaimsUsername(); ok { + _spec.SetField(authcode.FieldClaimsUsername, field.TypeString, value) } - if value, ok := acu.mutation.ClaimsEmailVerified(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBool, - Value: value, - Column: authcode.FieldClaimsEmailVerified, - }) + if value, ok := _u.mutation.ClaimsEmail(); ok { + _spec.SetField(authcode.FieldClaimsEmail, field.TypeString, value) } - if value, ok := acu.mutation.ClaimsGroups(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: authcode.FieldClaimsGroups, - }) + if value, ok := _u.mutation.ClaimsEmailVerified(); ok { + _spec.SetField(authcode.FieldClaimsEmailVerified, field.TypeBool, value) } - if acu.mutation.ClaimsGroupsCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: authcode.FieldClaimsGroups, - }) + if value, ok := _u.mutation.ClaimsGroups(); ok { + _spec.SetField(authcode.FieldClaimsGroups, field.TypeJSON, value) } - if value, ok := acu.mutation.ClaimsPreferredUsername(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldClaimsPreferredUsername, + if value, ok := _u.mutation.AppendedClaimsGroups(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, authcode.FieldClaimsGroups, value) }) } - if value, ok := acu.mutation.ConnectorID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldConnectorID, - }) + if _u.mutation.ClaimsGroupsCleared() { + _spec.ClearField(authcode.FieldClaimsGroups, field.TypeJSON) } - if value, ok := acu.mutation.ConnectorData(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: authcode.FieldConnectorData, - }) + if value, ok := _u.mutation.ClaimsPreferredUsername(); ok { + _spec.SetField(authcode.FieldClaimsPreferredUsername, field.TypeString, value) } - if acu.mutation.ConnectorDataCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Column: authcode.FieldConnectorData, - }) + if value, ok := _u.mutation.ConnectorID(); ok { + _spec.SetField(authcode.FieldConnectorID, field.TypeString, value) } - if value, ok := acu.mutation.Expiry(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: authcode.FieldExpiry, - }) + if value, ok := _u.mutation.ConnectorData(); ok { + _spec.SetField(authcode.FieldConnectorData, field.TypeBytes, value) } - if value, ok := acu.mutation.CodeChallenge(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldCodeChallenge, - }) + if _u.mutation.ConnectorDataCleared() { + _spec.ClearField(authcode.FieldConnectorData, field.TypeBytes) } - if value, ok := acu.mutation.CodeChallengeMethod(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldCodeChallengeMethod, - }) + if value, ok := _u.mutation.Expiry(); ok { + _spec.SetField(authcode.FieldExpiry, field.TypeTime, value) + } + if value, ok := _u.mutation.CodeChallenge(); ok { + _spec.SetField(authcode.FieldCodeChallenge, field.TypeString, value) + } + if value, ok := _u.mutation.CodeChallengeMethod(); ok { + _spec.SetField(authcode.FieldCodeChallengeMethod, field.TypeString, value) } - if n, err = sqlgraph.UpdateNodes(ctx, acu.driver, _spec); err != nil { + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{authcode.Label} } else if sqlgraph.IsConstraintError(err) { @@ -414,7 +401,8 @@ func (acu *AuthCodeUpdate) sqlSave(ctx context.Context) (n int, err error) { } return 0, err } - return n, nil + _u.mutation.done = true + return _node, nil } // AuthCodeUpdateOne is the builder for updating a single AuthCode entity. @@ -426,196 +414,247 @@ type AuthCodeUpdateOne struct { } // SetClientID sets the "client_id" field. -func (acuo *AuthCodeUpdateOne) SetClientID(s string) *AuthCodeUpdateOne { - acuo.mutation.SetClientID(s) - return acuo +func (_u *AuthCodeUpdateOne) SetClientID(v string) *AuthCodeUpdateOne { + _u.mutation.SetClientID(v) + return _u +} + +// SetNillableClientID sets the "client_id" field if the given value is not nil. +func (_u *AuthCodeUpdateOne) SetNillableClientID(v *string) *AuthCodeUpdateOne { + if v != nil { + _u.SetClientID(*v) + } + return _u } // SetScopes sets the "scopes" field. -func (acuo *AuthCodeUpdateOne) SetScopes(s []string) *AuthCodeUpdateOne { - acuo.mutation.SetScopes(s) - return acuo +func (_u *AuthCodeUpdateOne) SetScopes(v []string) *AuthCodeUpdateOne { + _u.mutation.SetScopes(v) + return _u +} + +// AppendScopes appends value to the "scopes" field. +func (_u *AuthCodeUpdateOne) AppendScopes(v []string) *AuthCodeUpdateOne { + _u.mutation.AppendScopes(v) + return _u } // ClearScopes clears the value of the "scopes" field. -func (acuo *AuthCodeUpdateOne) ClearScopes() *AuthCodeUpdateOne { - acuo.mutation.ClearScopes() - return acuo +func (_u *AuthCodeUpdateOne) ClearScopes() *AuthCodeUpdateOne { + _u.mutation.ClearScopes() + return _u } // SetNonce sets the "nonce" field. -func (acuo *AuthCodeUpdateOne) SetNonce(s string) *AuthCodeUpdateOne { - acuo.mutation.SetNonce(s) - return acuo +func (_u *AuthCodeUpdateOne) SetNonce(v string) *AuthCodeUpdateOne { + _u.mutation.SetNonce(v) + return _u +} + +// SetNillableNonce sets the "nonce" field if the given value is not nil. +func (_u *AuthCodeUpdateOne) SetNillableNonce(v *string) *AuthCodeUpdateOne { + if v != nil { + _u.SetNonce(*v) + } + return _u } // SetRedirectURI sets the "redirect_uri" field. -func (acuo *AuthCodeUpdateOne) SetRedirectURI(s string) *AuthCodeUpdateOne { - acuo.mutation.SetRedirectURI(s) - return acuo +func (_u *AuthCodeUpdateOne) SetRedirectURI(v string) *AuthCodeUpdateOne { + _u.mutation.SetRedirectURI(v) + return _u +} + +// SetNillableRedirectURI sets the "redirect_uri" field if the given value is not nil. +func (_u *AuthCodeUpdateOne) SetNillableRedirectURI(v *string) *AuthCodeUpdateOne { + if v != nil { + _u.SetRedirectURI(*v) + } + return _u } // SetClaimsUserID sets the "claims_user_id" field. -func (acuo *AuthCodeUpdateOne) SetClaimsUserID(s string) *AuthCodeUpdateOne { - acuo.mutation.SetClaimsUserID(s) - return acuo +func (_u *AuthCodeUpdateOne) SetClaimsUserID(v string) *AuthCodeUpdateOne { + _u.mutation.SetClaimsUserID(v) + return _u +} + +// SetNillableClaimsUserID sets the "claims_user_id" field if the given value is not nil. +func (_u *AuthCodeUpdateOne) SetNillableClaimsUserID(v *string) *AuthCodeUpdateOne { + if v != nil { + _u.SetClaimsUserID(*v) + } + return _u } // SetClaimsUsername sets the "claims_username" field. -func (acuo *AuthCodeUpdateOne) SetClaimsUsername(s string) *AuthCodeUpdateOne { - acuo.mutation.SetClaimsUsername(s) - return acuo +func (_u *AuthCodeUpdateOne) SetClaimsUsername(v string) *AuthCodeUpdateOne { + _u.mutation.SetClaimsUsername(v) + return _u +} + +// SetNillableClaimsUsername sets the "claims_username" field if the given value is not nil. +func (_u *AuthCodeUpdateOne) SetNillableClaimsUsername(v *string) *AuthCodeUpdateOne { + if v != nil { + _u.SetClaimsUsername(*v) + } + return _u } // SetClaimsEmail sets the "claims_email" field. -func (acuo *AuthCodeUpdateOne) SetClaimsEmail(s string) *AuthCodeUpdateOne { - acuo.mutation.SetClaimsEmail(s) - return acuo +func (_u *AuthCodeUpdateOne) SetClaimsEmail(v string) *AuthCodeUpdateOne { + _u.mutation.SetClaimsEmail(v) + return _u +} + +// SetNillableClaimsEmail sets the "claims_email" field if the given value is not nil. +func (_u *AuthCodeUpdateOne) SetNillableClaimsEmail(v *string) *AuthCodeUpdateOne { + if v != nil { + _u.SetClaimsEmail(*v) + } + return _u } // SetClaimsEmailVerified sets the "claims_email_verified" field. -func (acuo *AuthCodeUpdateOne) SetClaimsEmailVerified(b bool) *AuthCodeUpdateOne { - acuo.mutation.SetClaimsEmailVerified(b) - return acuo +func (_u *AuthCodeUpdateOne) SetClaimsEmailVerified(v bool) *AuthCodeUpdateOne { + _u.mutation.SetClaimsEmailVerified(v) + return _u +} + +// SetNillableClaimsEmailVerified sets the "claims_email_verified" field if the given value is not nil. +func (_u *AuthCodeUpdateOne) SetNillableClaimsEmailVerified(v *bool) *AuthCodeUpdateOne { + if v != nil { + _u.SetClaimsEmailVerified(*v) + } + return _u } // SetClaimsGroups sets the "claims_groups" field. -func (acuo *AuthCodeUpdateOne) SetClaimsGroups(s []string) *AuthCodeUpdateOne { - acuo.mutation.SetClaimsGroups(s) - return acuo +func (_u *AuthCodeUpdateOne) SetClaimsGroups(v []string) *AuthCodeUpdateOne { + _u.mutation.SetClaimsGroups(v) + return _u +} + +// AppendClaimsGroups appends value to the "claims_groups" field. +func (_u *AuthCodeUpdateOne) AppendClaimsGroups(v []string) *AuthCodeUpdateOne { + _u.mutation.AppendClaimsGroups(v) + return _u } // ClearClaimsGroups clears the value of the "claims_groups" field. -func (acuo *AuthCodeUpdateOne) ClearClaimsGroups() *AuthCodeUpdateOne { - acuo.mutation.ClearClaimsGroups() - return acuo +func (_u *AuthCodeUpdateOne) ClearClaimsGroups() *AuthCodeUpdateOne { + _u.mutation.ClearClaimsGroups() + return _u } // SetClaimsPreferredUsername sets the "claims_preferred_username" field. -func (acuo *AuthCodeUpdateOne) SetClaimsPreferredUsername(s string) *AuthCodeUpdateOne { - acuo.mutation.SetClaimsPreferredUsername(s) - return acuo +func (_u *AuthCodeUpdateOne) SetClaimsPreferredUsername(v string) *AuthCodeUpdateOne { + _u.mutation.SetClaimsPreferredUsername(v) + return _u } // SetNillableClaimsPreferredUsername sets the "claims_preferred_username" field if the given value is not nil. -func (acuo *AuthCodeUpdateOne) SetNillableClaimsPreferredUsername(s *string) *AuthCodeUpdateOne { - if s != nil { - acuo.SetClaimsPreferredUsername(*s) +func (_u *AuthCodeUpdateOne) SetNillableClaimsPreferredUsername(v *string) *AuthCodeUpdateOne { + if v != nil { + _u.SetClaimsPreferredUsername(*v) } - return acuo + return _u } // SetConnectorID sets the "connector_id" field. -func (acuo *AuthCodeUpdateOne) SetConnectorID(s string) *AuthCodeUpdateOne { - acuo.mutation.SetConnectorID(s) - return acuo +func (_u *AuthCodeUpdateOne) SetConnectorID(v string) *AuthCodeUpdateOne { + _u.mutation.SetConnectorID(v) + return _u +} + +// SetNillableConnectorID sets the "connector_id" field if the given value is not nil. +func (_u *AuthCodeUpdateOne) SetNillableConnectorID(v *string) *AuthCodeUpdateOne { + if v != nil { + _u.SetConnectorID(*v) + } + return _u } // SetConnectorData sets the "connector_data" field. -func (acuo *AuthCodeUpdateOne) SetConnectorData(b []byte) *AuthCodeUpdateOne { - acuo.mutation.SetConnectorData(b) - return acuo +func (_u *AuthCodeUpdateOne) SetConnectorData(v []byte) *AuthCodeUpdateOne { + _u.mutation.SetConnectorData(v) + return _u } // ClearConnectorData clears the value of the "connector_data" field. -func (acuo *AuthCodeUpdateOne) ClearConnectorData() *AuthCodeUpdateOne { - acuo.mutation.ClearConnectorData() - return acuo +func (_u *AuthCodeUpdateOne) ClearConnectorData() *AuthCodeUpdateOne { + _u.mutation.ClearConnectorData() + return _u } // SetExpiry sets the "expiry" field. -func (acuo *AuthCodeUpdateOne) SetExpiry(t time.Time) *AuthCodeUpdateOne { - acuo.mutation.SetExpiry(t) - return acuo +func (_u *AuthCodeUpdateOne) SetExpiry(v time.Time) *AuthCodeUpdateOne { + _u.mutation.SetExpiry(v) + return _u +} + +// SetNillableExpiry sets the "expiry" field if the given value is not nil. +func (_u *AuthCodeUpdateOne) SetNillableExpiry(v *time.Time) *AuthCodeUpdateOne { + if v != nil { + _u.SetExpiry(*v) + } + return _u } // SetCodeChallenge sets the "code_challenge" field. -func (acuo *AuthCodeUpdateOne) SetCodeChallenge(s string) *AuthCodeUpdateOne { - acuo.mutation.SetCodeChallenge(s) - return acuo +func (_u *AuthCodeUpdateOne) SetCodeChallenge(v string) *AuthCodeUpdateOne { + _u.mutation.SetCodeChallenge(v) + return _u } // SetNillableCodeChallenge sets the "code_challenge" field if the given value is not nil. -func (acuo *AuthCodeUpdateOne) SetNillableCodeChallenge(s *string) *AuthCodeUpdateOne { - if s != nil { - acuo.SetCodeChallenge(*s) +func (_u *AuthCodeUpdateOne) SetNillableCodeChallenge(v *string) *AuthCodeUpdateOne { + if v != nil { + _u.SetCodeChallenge(*v) } - return acuo + return _u } // SetCodeChallengeMethod sets the "code_challenge_method" field. -func (acuo *AuthCodeUpdateOne) SetCodeChallengeMethod(s string) *AuthCodeUpdateOne { - acuo.mutation.SetCodeChallengeMethod(s) - return acuo +func (_u *AuthCodeUpdateOne) SetCodeChallengeMethod(v string) *AuthCodeUpdateOne { + _u.mutation.SetCodeChallengeMethod(v) + return _u } // SetNillableCodeChallengeMethod sets the "code_challenge_method" field if the given value is not nil. -func (acuo *AuthCodeUpdateOne) SetNillableCodeChallengeMethod(s *string) *AuthCodeUpdateOne { - if s != nil { - acuo.SetCodeChallengeMethod(*s) +func (_u *AuthCodeUpdateOne) SetNillableCodeChallengeMethod(v *string) *AuthCodeUpdateOne { + if v != nil { + _u.SetCodeChallengeMethod(*v) } - return acuo + return _u } // Mutation returns the AuthCodeMutation object of the builder. -func (acuo *AuthCodeUpdateOne) Mutation() *AuthCodeMutation { - return acuo.mutation +func (_u *AuthCodeUpdateOne) Mutation() *AuthCodeMutation { + return _u.mutation +} + +// Where appends a list predicates to the AuthCodeUpdate builder. +func (_u *AuthCodeUpdateOne) Where(ps ...predicate.AuthCode) *AuthCodeUpdateOne { + _u.mutation.Where(ps...) + return _u } // Select allows selecting one or more fields (columns) of the returned entity. // The default is selecting all fields defined in the entity schema. -func (acuo *AuthCodeUpdateOne) Select(field string, fields ...string) *AuthCodeUpdateOne { - acuo.fields = append([]string{field}, fields...) - return acuo +func (_u *AuthCodeUpdateOne) Select(field string, fields ...string) *AuthCodeUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u } // Save executes the query and returns the updated AuthCode entity. -func (acuo *AuthCodeUpdateOne) Save(ctx context.Context) (*AuthCode, error) { - var ( - err error - node *AuthCode - ) - if len(acuo.hooks) == 0 { - if err = acuo.check(); err != nil { - return nil, err - } - node, err = acuo.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*AuthCodeMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = acuo.check(); err != nil { - return nil, err - } - acuo.mutation = mutation - node, err = acuo.sqlSave(ctx) - mutation.done = true - return node, err - }) - for i := len(acuo.hooks) - 1; i >= 0; i-- { - if acuo.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = acuo.hooks[i](mut) - } - v, err := mut.Mutate(ctx, acuo.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*AuthCode) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from AuthCodeMutation", v) - } - node = nv - } - return node, err +func (_u *AuthCodeUpdateOne) Save(ctx context.Context) (*AuthCode, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (acuo *AuthCodeUpdateOne) SaveX(ctx context.Context) *AuthCode { - node, err := acuo.Save(ctx) +func (_u *AuthCodeUpdateOne) SaveX(ctx context.Context) *AuthCode { + node, err := _u.Save(ctx) if err != nil { panic(err) } @@ -623,51 +662,51 @@ func (acuo *AuthCodeUpdateOne) SaveX(ctx context.Context) *AuthCode { } // Exec executes the query on the entity. -func (acuo *AuthCodeUpdateOne) Exec(ctx context.Context) error { - _, err := acuo.Save(ctx) +func (_u *AuthCodeUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (acuo *AuthCodeUpdateOne) ExecX(ctx context.Context) { - if err := acuo.Exec(ctx); err != nil { +func (_u *AuthCodeUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (acuo *AuthCodeUpdateOne) check() error { - if v, ok := acuo.mutation.ClientID(); ok { +func (_u *AuthCodeUpdateOne) check() error { + if v, ok := _u.mutation.ClientID(); ok { if err := authcode.ClientIDValidator(v); err != nil { return &ValidationError{Name: "client_id", err: fmt.Errorf(`db: validator failed for field "AuthCode.client_id": %w`, err)} } } - if v, ok := acuo.mutation.Nonce(); ok { + if v, ok := _u.mutation.Nonce(); ok { if err := authcode.NonceValidator(v); err != nil { return &ValidationError{Name: "nonce", err: fmt.Errorf(`db: validator failed for field "AuthCode.nonce": %w`, err)} } } - if v, ok := acuo.mutation.RedirectURI(); ok { + if v, ok := _u.mutation.RedirectURI(); ok { if err := authcode.RedirectURIValidator(v); err != nil { return &ValidationError{Name: "redirect_uri", err: fmt.Errorf(`db: validator failed for field "AuthCode.redirect_uri": %w`, err)} } } - if v, ok := acuo.mutation.ClaimsUserID(); ok { + if v, ok := _u.mutation.ClaimsUserID(); ok { if err := authcode.ClaimsUserIDValidator(v); err != nil { return &ValidationError{Name: "claims_user_id", err: fmt.Errorf(`db: validator failed for field "AuthCode.claims_user_id": %w`, err)} } } - if v, ok := acuo.mutation.ClaimsUsername(); ok { + if v, ok := _u.mutation.ClaimsUsername(); ok { if err := authcode.ClaimsUsernameValidator(v); err != nil { return &ValidationError{Name: "claims_username", err: fmt.Errorf(`db: validator failed for field "AuthCode.claims_username": %w`, err)} } } - if v, ok := acuo.mutation.ClaimsEmail(); ok { + if v, ok := _u.mutation.ClaimsEmail(); ok { if err := authcode.ClaimsEmailValidator(v); err != nil { return &ValidationError{Name: "claims_email", err: fmt.Errorf(`db: validator failed for field "AuthCode.claims_email": %w`, err)} } } - if v, ok := acuo.mutation.ConnectorID(); ok { + if v, ok := _u.mutation.ConnectorID(); ok { if err := authcode.ConnectorIDValidator(v); err != nil { return &ValidationError{Name: "connector_id", err: fmt.Errorf(`db: validator failed for field "AuthCode.connector_id": %w`, err)} } @@ -675,23 +714,17 @@ func (acuo *AuthCodeUpdateOne) check() error { return nil } -func (acuo *AuthCodeUpdateOne) sqlSave(ctx context.Context) (_node *AuthCode, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: authcode.Table, - Columns: authcode.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: authcode.FieldID, - }, - }, +func (_u *AuthCodeUpdateOne) sqlSave(ctx context.Context) (_node *AuthCode, err error) { + if err := _u.check(); err != nil { + return _node, err } - id, ok := acuo.mutation.ID() + _spec := sqlgraph.NewUpdateSpec(authcode.Table, authcode.Columns, sqlgraph.NewFieldSpec(authcode.FieldID, field.TypeString)) + id, ok := _u.mutation.ID() if !ok { return nil, &ValidationError{Name: "id", err: errors.New(`db: missing "AuthCode.id" for update`)} } _spec.Node.ID.Value = id - if fields := acuo.fields; len(fields) > 0 { + if fields := _u.fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, authcode.FieldID) for _, f := range fields { @@ -703,140 +736,81 @@ func (acuo *AuthCodeUpdateOne) sqlSave(ctx context.Context) (_node *AuthCode, er } } } - if ps := acuo.mutation.predicates; len(ps) > 0 { + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := acuo.mutation.ClientID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldClientID, - }) + if value, ok := _u.mutation.ClientID(); ok { + _spec.SetField(authcode.FieldClientID, field.TypeString, value) } - if value, ok := acuo.mutation.Scopes(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: authcode.FieldScopes, - }) + if value, ok := _u.mutation.Scopes(); ok { + _spec.SetField(authcode.FieldScopes, field.TypeJSON, value) } - if acuo.mutation.ScopesCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: authcode.FieldScopes, + if value, ok := _u.mutation.AppendedScopes(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, authcode.FieldScopes, value) }) } - if value, ok := acuo.mutation.Nonce(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldNonce, - }) + if _u.mutation.ScopesCleared() { + _spec.ClearField(authcode.FieldScopes, field.TypeJSON) } - if value, ok := acuo.mutation.RedirectURI(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldRedirectURI, - }) + if value, ok := _u.mutation.Nonce(); ok { + _spec.SetField(authcode.FieldNonce, field.TypeString, value) } - if value, ok := acuo.mutation.ClaimsUserID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldClaimsUserID, - }) + if value, ok := _u.mutation.RedirectURI(); ok { + _spec.SetField(authcode.FieldRedirectURI, field.TypeString, value) } - if value, ok := acuo.mutation.ClaimsUsername(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldClaimsUsername, - }) + if value, ok := _u.mutation.ClaimsUserID(); ok { + _spec.SetField(authcode.FieldClaimsUserID, field.TypeString, value) } - if value, ok := acuo.mutation.ClaimsEmail(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldClaimsEmail, - }) + if value, ok := _u.mutation.ClaimsUsername(); ok { + _spec.SetField(authcode.FieldClaimsUsername, field.TypeString, value) } - if value, ok := acuo.mutation.ClaimsEmailVerified(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBool, - Value: value, - Column: authcode.FieldClaimsEmailVerified, - }) + if value, ok := _u.mutation.ClaimsEmail(); ok { + _spec.SetField(authcode.FieldClaimsEmail, field.TypeString, value) } - if value, ok := acuo.mutation.ClaimsGroups(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: authcode.FieldClaimsGroups, - }) + if value, ok := _u.mutation.ClaimsEmailVerified(); ok { + _spec.SetField(authcode.FieldClaimsEmailVerified, field.TypeBool, value) } - if acuo.mutation.ClaimsGroupsCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: authcode.FieldClaimsGroups, - }) + if value, ok := _u.mutation.ClaimsGroups(); ok { + _spec.SetField(authcode.FieldClaimsGroups, field.TypeJSON, value) } - if value, ok := acuo.mutation.ClaimsPreferredUsername(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldClaimsPreferredUsername, + if value, ok := _u.mutation.AppendedClaimsGroups(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, authcode.FieldClaimsGroups, value) }) } - if value, ok := acuo.mutation.ConnectorID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldConnectorID, - }) + if _u.mutation.ClaimsGroupsCleared() { + _spec.ClearField(authcode.FieldClaimsGroups, field.TypeJSON) } - if value, ok := acuo.mutation.ConnectorData(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: authcode.FieldConnectorData, - }) + if value, ok := _u.mutation.ClaimsPreferredUsername(); ok { + _spec.SetField(authcode.FieldClaimsPreferredUsername, field.TypeString, value) } - if acuo.mutation.ConnectorDataCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Column: authcode.FieldConnectorData, - }) + if value, ok := _u.mutation.ConnectorID(); ok { + _spec.SetField(authcode.FieldConnectorID, field.TypeString, value) } - if value, ok := acuo.mutation.Expiry(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: authcode.FieldExpiry, - }) + if value, ok := _u.mutation.ConnectorData(); ok { + _spec.SetField(authcode.FieldConnectorData, field.TypeBytes, value) } - if value, ok := acuo.mutation.CodeChallenge(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldCodeChallenge, - }) + if _u.mutation.ConnectorDataCleared() { + _spec.ClearField(authcode.FieldConnectorData, field.TypeBytes) } - if value, ok := acuo.mutation.CodeChallengeMethod(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authcode.FieldCodeChallengeMethod, - }) + if value, ok := _u.mutation.Expiry(); ok { + _spec.SetField(authcode.FieldExpiry, field.TypeTime, value) + } + if value, ok := _u.mutation.CodeChallenge(); ok { + _spec.SetField(authcode.FieldCodeChallenge, field.TypeString, value) + } + if value, ok := _u.mutation.CodeChallengeMethod(); ok { + _spec.SetField(authcode.FieldCodeChallengeMethod, field.TypeString, value) } - _node = &AuthCode{config: acuo.config} + _node = &AuthCode{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues - if err = sqlgraph.UpdateNode(ctx, acuo.driver, _spec); err != nil { + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{authcode.Label} } else if sqlgraph.IsConstraintError(err) { @@ -844,5 +818,6 @@ func (acuo *AuthCodeUpdateOne) sqlSave(ctx context.Context) (_node *AuthCode, er } return nil, err } + _u.mutation.done = true return _node, nil } diff --git a/storage/ent/db/authrequest.go b/storage/ent/db/authrequest.go index ecef32d789..ac5b550ad9 100644 --- a/storage/ent/db/authrequest.go +++ b/storage/ent/db/authrequest.go @@ -8,6 +8,7 @@ import ( "strings" "time" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/dexidp/dex/storage/ent/db/authrequest" ) @@ -55,14 +56,17 @@ type AuthRequest struct { CodeChallenge string `json:"code_challenge,omitempty"` // CodeChallengeMethod holds the value of the "code_challenge_method" field. CodeChallengeMethod string `json:"code_challenge_method,omitempty"` + // HmacKey holds the value of the "hmac_key" field. + HmacKey []byte `json:"hmac_key,omitempty"` + selectValues sql.SelectValues } // scanValues returns the types for scanning values from sql.Rows. -func (*AuthRequest) scanValues(columns []string) ([]interface{}, error) { - values := make([]interface{}, len(columns)) +func (*AuthRequest) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) for i := range columns { switch columns[i] { - case authrequest.FieldScopes, authrequest.FieldResponseTypes, authrequest.FieldClaimsGroups, authrequest.FieldConnectorData: + case authrequest.FieldScopes, authrequest.FieldResponseTypes, authrequest.FieldClaimsGroups, authrequest.FieldConnectorData, authrequest.FieldHmacKey: values[i] = new([]byte) case authrequest.FieldForceApprovalPrompt, authrequest.FieldLoggedIn, authrequest.FieldClaimsEmailVerified: values[i] = new(sql.NullBool) @@ -71,7 +75,7 @@ func (*AuthRequest) scanValues(columns []string) ([]interface{}, error) { case authrequest.FieldExpiry: values[i] = new(sql.NullTime) default: - return nil, fmt.Errorf("unexpected column %q for type AuthRequest", columns[i]) + values[i] = new(sql.UnknownType) } } return values, nil @@ -79,7 +83,7 @@ func (*AuthRequest) scanValues(columns []string) ([]interface{}, error) { // assignValues assigns the values that were returned from sql.Rows (after scanning) // to the AuthRequest fields. -func (ar *AuthRequest) assignValues(columns []string, values []interface{}) error { +func (_m *AuthRequest) assignValues(columns []string, values []any) error { if m, n := len(values), len(columns); m < n { return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) } @@ -89,19 +93,19 @@ func (ar *AuthRequest) assignValues(columns []string, values []interface{}) erro if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field id", values[i]) } else if value.Valid { - ar.ID = value.String + _m.ID = value.String } case authrequest.FieldClientID: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field client_id", values[i]) } else if value.Valid { - ar.ClientID = value.String + _m.ClientID = value.String } case authrequest.FieldScopes: if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field scopes", values[i]) } else if value != nil && len(*value) > 0 { - if err := json.Unmarshal(*value, &ar.Scopes); err != nil { + if err := json.Unmarshal(*value, &_m.Scopes); err != nil { return fmt.Errorf("unmarshal field scopes: %w", err) } } @@ -109,7 +113,7 @@ func (ar *AuthRequest) assignValues(columns []string, values []interface{}) erro if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field response_types", values[i]) } else if value != nil && len(*value) > 0 { - if err := json.Unmarshal(*value, &ar.ResponseTypes); err != nil { + if err := json.Unmarshal(*value, &_m.ResponseTypes); err != nil { return fmt.Errorf("unmarshal field response_types: %w", err) } } @@ -117,61 +121,61 @@ func (ar *AuthRequest) assignValues(columns []string, values []interface{}) erro if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field redirect_uri", values[i]) } else if value.Valid { - ar.RedirectURI = value.String + _m.RedirectURI = value.String } case authrequest.FieldNonce: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field nonce", values[i]) } else if value.Valid { - ar.Nonce = value.String + _m.Nonce = value.String } case authrequest.FieldState: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field state", values[i]) } else if value.Valid { - ar.State = value.String + _m.State = value.String } case authrequest.FieldForceApprovalPrompt: if value, ok := values[i].(*sql.NullBool); !ok { return fmt.Errorf("unexpected type %T for field force_approval_prompt", values[i]) } else if value.Valid { - ar.ForceApprovalPrompt = value.Bool + _m.ForceApprovalPrompt = value.Bool } case authrequest.FieldLoggedIn: if value, ok := values[i].(*sql.NullBool); !ok { return fmt.Errorf("unexpected type %T for field logged_in", values[i]) } else if value.Valid { - ar.LoggedIn = value.Bool + _m.LoggedIn = value.Bool } case authrequest.FieldClaimsUserID: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field claims_user_id", values[i]) } else if value.Valid { - ar.ClaimsUserID = value.String + _m.ClaimsUserID = value.String } case authrequest.FieldClaimsUsername: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field claims_username", values[i]) } else if value.Valid { - ar.ClaimsUsername = value.String + _m.ClaimsUsername = value.String } case authrequest.FieldClaimsEmail: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field claims_email", values[i]) } else if value.Valid { - ar.ClaimsEmail = value.String + _m.ClaimsEmail = value.String } case authrequest.FieldClaimsEmailVerified: if value, ok := values[i].(*sql.NullBool); !ok { return fmt.Errorf("unexpected type %T for field claims_email_verified", values[i]) } else if value.Valid { - ar.ClaimsEmailVerified = value.Bool + _m.ClaimsEmailVerified = value.Bool } case authrequest.FieldClaimsGroups: if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field claims_groups", values[i]) } else if value != nil && len(*value) > 0 { - if err := json.Unmarshal(*value, &ar.ClaimsGroups); err != nil { + if err := json.Unmarshal(*value, &_m.ClaimsGroups); err != nil { return fmt.Errorf("unmarshal field claims_groups: %w", err) } } @@ -179,133 +183,144 @@ func (ar *AuthRequest) assignValues(columns []string, values []interface{}) erro if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field claims_preferred_username", values[i]) } else if value.Valid { - ar.ClaimsPreferredUsername = value.String + _m.ClaimsPreferredUsername = value.String } case authrequest.FieldConnectorID: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field connector_id", values[i]) } else if value.Valid { - ar.ConnectorID = value.String + _m.ConnectorID = value.String } case authrequest.FieldConnectorData: if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field connector_data", values[i]) } else if value != nil { - ar.ConnectorData = value + _m.ConnectorData = value } case authrequest.FieldExpiry: if value, ok := values[i].(*sql.NullTime); !ok { return fmt.Errorf("unexpected type %T for field expiry", values[i]) } else if value.Valid { - ar.Expiry = value.Time + _m.Expiry = value.Time } case authrequest.FieldCodeChallenge: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field code_challenge", values[i]) } else if value.Valid { - ar.CodeChallenge = value.String + _m.CodeChallenge = value.String } case authrequest.FieldCodeChallengeMethod: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field code_challenge_method", values[i]) } else if value.Valid { - ar.CodeChallengeMethod = value.String + _m.CodeChallengeMethod = value.String } + case authrequest.FieldHmacKey: + if value, ok := values[i].(*[]byte); !ok { + return fmt.Errorf("unexpected type %T for field hmac_key", values[i]) + } else if value != nil { + _m.HmacKey = *value + } + default: + _m.selectValues.Set(columns[i], values[i]) } } return nil } +// Value returns the ent.Value that was dynamically selected and assigned to the AuthRequest. +// This includes values selected through modifiers, order, etc. +func (_m *AuthRequest) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + // Update returns a builder for updating this AuthRequest. // Note that you need to call AuthRequest.Unwrap() before calling this method if this AuthRequest // was returned from a transaction, and the transaction was committed or rolled back. -func (ar *AuthRequest) Update() *AuthRequestUpdateOne { - return (&AuthRequestClient{config: ar.config}).UpdateOne(ar) +func (_m *AuthRequest) Update() *AuthRequestUpdateOne { + return NewAuthRequestClient(_m.config).UpdateOne(_m) } // Unwrap unwraps the AuthRequest entity that was returned from a transaction after it was closed, // so that all future queries will be executed through the driver which created the transaction. -func (ar *AuthRequest) Unwrap() *AuthRequest { - _tx, ok := ar.config.driver.(*txDriver) +func (_m *AuthRequest) Unwrap() *AuthRequest { + _tx, ok := _m.config.driver.(*txDriver) if !ok { panic("db: AuthRequest is not a transactional entity") } - ar.config.driver = _tx.drv - return ar + _m.config.driver = _tx.drv + return _m } // String implements the fmt.Stringer. -func (ar *AuthRequest) String() string { +func (_m *AuthRequest) String() string { var builder strings.Builder builder.WriteString("AuthRequest(") - builder.WriteString(fmt.Sprintf("id=%v, ", ar.ID)) + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) builder.WriteString("client_id=") - builder.WriteString(ar.ClientID) + builder.WriteString(_m.ClientID) builder.WriteString(", ") builder.WriteString("scopes=") - builder.WriteString(fmt.Sprintf("%v", ar.Scopes)) + builder.WriteString(fmt.Sprintf("%v", _m.Scopes)) builder.WriteString(", ") builder.WriteString("response_types=") - builder.WriteString(fmt.Sprintf("%v", ar.ResponseTypes)) + builder.WriteString(fmt.Sprintf("%v", _m.ResponseTypes)) builder.WriteString(", ") builder.WriteString("redirect_uri=") - builder.WriteString(ar.RedirectURI) + builder.WriteString(_m.RedirectURI) builder.WriteString(", ") builder.WriteString("nonce=") - builder.WriteString(ar.Nonce) + builder.WriteString(_m.Nonce) builder.WriteString(", ") builder.WriteString("state=") - builder.WriteString(ar.State) + builder.WriteString(_m.State) builder.WriteString(", ") builder.WriteString("force_approval_prompt=") - builder.WriteString(fmt.Sprintf("%v", ar.ForceApprovalPrompt)) + builder.WriteString(fmt.Sprintf("%v", _m.ForceApprovalPrompt)) builder.WriteString(", ") builder.WriteString("logged_in=") - builder.WriteString(fmt.Sprintf("%v", ar.LoggedIn)) + builder.WriteString(fmt.Sprintf("%v", _m.LoggedIn)) builder.WriteString(", ") builder.WriteString("claims_user_id=") - builder.WriteString(ar.ClaimsUserID) + builder.WriteString(_m.ClaimsUserID) builder.WriteString(", ") builder.WriteString("claims_username=") - builder.WriteString(ar.ClaimsUsername) + builder.WriteString(_m.ClaimsUsername) builder.WriteString(", ") builder.WriteString("claims_email=") - builder.WriteString(ar.ClaimsEmail) + builder.WriteString(_m.ClaimsEmail) builder.WriteString(", ") builder.WriteString("claims_email_verified=") - builder.WriteString(fmt.Sprintf("%v", ar.ClaimsEmailVerified)) + builder.WriteString(fmt.Sprintf("%v", _m.ClaimsEmailVerified)) builder.WriteString(", ") builder.WriteString("claims_groups=") - builder.WriteString(fmt.Sprintf("%v", ar.ClaimsGroups)) + builder.WriteString(fmt.Sprintf("%v", _m.ClaimsGroups)) builder.WriteString(", ") builder.WriteString("claims_preferred_username=") - builder.WriteString(ar.ClaimsPreferredUsername) + builder.WriteString(_m.ClaimsPreferredUsername) builder.WriteString(", ") builder.WriteString("connector_id=") - builder.WriteString(ar.ConnectorID) + builder.WriteString(_m.ConnectorID) builder.WriteString(", ") - if v := ar.ConnectorData; v != nil { + if v := _m.ConnectorData; v != nil { builder.WriteString("connector_data=") builder.WriteString(fmt.Sprintf("%v", *v)) } builder.WriteString(", ") builder.WriteString("expiry=") - builder.WriteString(ar.Expiry.Format(time.ANSIC)) + builder.WriteString(_m.Expiry.Format(time.ANSIC)) builder.WriteString(", ") builder.WriteString("code_challenge=") - builder.WriteString(ar.CodeChallenge) + builder.WriteString(_m.CodeChallenge) builder.WriteString(", ") builder.WriteString("code_challenge_method=") - builder.WriteString(ar.CodeChallengeMethod) + builder.WriteString(_m.CodeChallengeMethod) + builder.WriteString(", ") + builder.WriteString("hmac_key=") + builder.WriteString(fmt.Sprintf("%v", _m.HmacKey)) builder.WriteByte(')') return builder.String() } // AuthRequests is a parsable slice of AuthRequest. type AuthRequests []*AuthRequest - -func (ar AuthRequests) config(cfg config) { - for _i := range ar { - ar[_i].config = cfg - } -} diff --git a/storage/ent/db/authrequest/authrequest.go b/storage/ent/db/authrequest/authrequest.go index 528d26b626..0998c79932 100644 --- a/storage/ent/db/authrequest/authrequest.go +++ b/storage/ent/db/authrequest/authrequest.go @@ -2,6 +2,10 @@ package authrequest +import ( + "entgo.io/ent/dialect/sql" +) + const ( // Label holds the string label denoting the authrequest type in the database. Label = "auth_request" @@ -45,6 +49,8 @@ const ( FieldCodeChallenge = "code_challenge" // FieldCodeChallengeMethod holds the string denoting the code_challenge_method field in the database. FieldCodeChallengeMethod = "code_challenge_method" + // FieldHmacKey holds the string denoting the hmac_key field in the database. + FieldHmacKey = "hmac_key" // Table holds the table name of the authrequest in the database. Table = "auth_requests" ) @@ -71,6 +77,7 @@ var Columns = []string{ FieldExpiry, FieldCodeChallenge, FieldCodeChallengeMethod, + FieldHmacKey, } // ValidColumn reports if the column name is valid (part of the table columns). @@ -93,3 +100,86 @@ var ( // IDValidator is a validator for the "id" field. It is called by the builders before save. IDValidator func(string) error ) + +// OrderOption defines the ordering options for the AuthRequest queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByClientID orders the results by the client_id field. +func ByClientID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClientID, opts...).ToFunc() +} + +// ByRedirectURI orders the results by the redirect_uri field. +func ByRedirectURI(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldRedirectURI, opts...).ToFunc() +} + +// ByNonce orders the results by the nonce field. +func ByNonce(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldNonce, opts...).ToFunc() +} + +// ByState orders the results by the state field. +func ByState(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldState, opts...).ToFunc() +} + +// ByForceApprovalPrompt orders the results by the force_approval_prompt field. +func ByForceApprovalPrompt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldForceApprovalPrompt, opts...).ToFunc() +} + +// ByLoggedIn orders the results by the logged_in field. +func ByLoggedIn(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldLoggedIn, opts...).ToFunc() +} + +// ByClaimsUserID orders the results by the claims_user_id field. +func ByClaimsUserID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClaimsUserID, opts...).ToFunc() +} + +// ByClaimsUsername orders the results by the claims_username field. +func ByClaimsUsername(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClaimsUsername, opts...).ToFunc() +} + +// ByClaimsEmail orders the results by the claims_email field. +func ByClaimsEmail(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClaimsEmail, opts...).ToFunc() +} + +// ByClaimsEmailVerified orders the results by the claims_email_verified field. +func ByClaimsEmailVerified(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClaimsEmailVerified, opts...).ToFunc() +} + +// ByClaimsPreferredUsername orders the results by the claims_preferred_username field. +func ByClaimsPreferredUsername(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClaimsPreferredUsername, opts...).ToFunc() +} + +// ByConnectorID orders the results by the connector_id field. +func ByConnectorID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldConnectorID, opts...).ToFunc() +} + +// ByExpiry orders the results by the expiry field. +func ByExpiry(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldExpiry, opts...).ToFunc() +} + +// ByCodeChallenge orders the results by the code_challenge field. +func ByCodeChallenge(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldCodeChallenge, opts...).ToFunc() +} + +// ByCodeChallengeMethod orders the results by the code_challenge_method field. +func ByCodeChallengeMethod(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldCodeChallengeMethod, opts...).ToFunc() +} diff --git a/storage/ent/db/authrequest/where.go b/storage/ent/db/authrequest/where.go index e31cdcee0f..4d3a39bec5 100644 --- a/storage/ent/db/authrequest/where.go +++ b/storage/ent/db/authrequest/where.go @@ -11,1530 +11,1060 @@ import ( // ID filters vertices based on their ID field. func ID(id string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldID, id)) } // IDEQ applies the EQ predicate on the ID field. func IDEQ(id string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldID, id)) } // IDNEQ applies the NEQ predicate on the ID field. func IDNEQ(id string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldID), id)) - }) + return predicate.AuthRequest(sql.FieldNEQ(FieldID, id)) } // IDIn applies the In predicate on the ID field. func IDIn(ids ...string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.In(s.C(FieldID), v...)) - }) + return predicate.AuthRequest(sql.FieldIn(FieldID, ids...)) } // IDNotIn applies the NotIn predicate on the ID field. func IDNotIn(ids ...string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.NotIn(s.C(FieldID), v...)) - }) + return predicate.AuthRequest(sql.FieldNotIn(FieldID, ids...)) } // IDGT applies the GT predicate on the ID field. func IDGT(id string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldID), id)) - }) + return predicate.AuthRequest(sql.FieldGT(FieldID, id)) } // IDGTE applies the GTE predicate on the ID field. func IDGTE(id string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldID), id)) - }) + return predicate.AuthRequest(sql.FieldGTE(FieldID, id)) } // IDLT applies the LT predicate on the ID field. func IDLT(id string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldID), id)) - }) + return predicate.AuthRequest(sql.FieldLT(FieldID, id)) } // IDLTE applies the LTE predicate on the ID field. func IDLTE(id string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldID), id)) - }) + return predicate.AuthRequest(sql.FieldLTE(FieldID, id)) +} + +// IDEqualFold applies the EqualFold predicate on the ID field. +func IDEqualFold(id string) predicate.AuthRequest { + return predicate.AuthRequest(sql.FieldEqualFold(FieldID, id)) +} + +// IDContainsFold applies the ContainsFold predicate on the ID field. +func IDContainsFold(id string) predicate.AuthRequest { + return predicate.AuthRequest(sql.FieldContainsFold(FieldID, id)) } // ClientID applies equality check predicate on the "client_id" field. It's identical to ClientIDEQ. func ClientID(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClientID), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldClientID, v)) } // RedirectURI applies equality check predicate on the "redirect_uri" field. It's identical to RedirectURIEQ. func RedirectURI(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldRedirectURI, v)) } // Nonce applies equality check predicate on the "nonce" field. It's identical to NonceEQ. func Nonce(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldNonce), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldNonce, v)) } // State applies equality check predicate on the "state" field. It's identical to StateEQ. func State(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldState), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldState, v)) } // ForceApprovalPrompt applies equality check predicate on the "force_approval_prompt" field. It's identical to ForceApprovalPromptEQ. func ForceApprovalPrompt(v bool) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldForceApprovalPrompt), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldForceApprovalPrompt, v)) } // LoggedIn applies equality check predicate on the "logged_in" field. It's identical to LoggedInEQ. func LoggedIn(v bool) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldLoggedIn), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldLoggedIn, v)) } // ClaimsUserID applies equality check predicate on the "claims_user_id" field. It's identical to ClaimsUserIDEQ. func ClaimsUserID(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldClaimsUserID, v)) } // ClaimsUsername applies equality check predicate on the "claims_username" field. It's identical to ClaimsUsernameEQ. func ClaimsUsername(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldClaimsUsername, v)) } // ClaimsEmail applies equality check predicate on the "claims_email" field. It's identical to ClaimsEmailEQ. func ClaimsEmail(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldClaimsEmail, v)) } // ClaimsEmailVerified applies equality check predicate on the "claims_email_verified" field. It's identical to ClaimsEmailVerifiedEQ. func ClaimsEmailVerified(v bool) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsEmailVerified), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldClaimsEmailVerified, v)) } // ClaimsPreferredUsername applies equality check predicate on the "claims_preferred_username" field. It's identical to ClaimsPreferredUsernameEQ. func ClaimsPreferredUsername(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldClaimsPreferredUsername, v)) } // ConnectorID applies equality check predicate on the "connector_id" field. It's identical to ConnectorIDEQ. func ConnectorID(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldConnectorID), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldConnectorID, v)) } // ConnectorData applies equality check predicate on the "connector_data" field. It's identical to ConnectorDataEQ. func ConnectorData(v []byte) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldConnectorData), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldConnectorData, v)) } // Expiry applies equality check predicate on the "expiry" field. It's identical to ExpiryEQ. func Expiry(v time.Time) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldExpiry), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldExpiry, v)) } // CodeChallenge applies equality check predicate on the "code_challenge" field. It's identical to CodeChallengeEQ. func CodeChallenge(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldCodeChallenge, v)) } // CodeChallengeMethod applies equality check predicate on the "code_challenge_method" field. It's identical to CodeChallengeMethodEQ. func CodeChallengeMethod(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldCodeChallengeMethod, v)) +} + +// HmacKey applies equality check predicate on the "hmac_key" field. It's identical to HmacKeyEQ. +func HmacKey(v []byte) predicate.AuthRequest { + return predicate.AuthRequest(sql.FieldEQ(FieldHmacKey, v)) } // ClientIDEQ applies the EQ predicate on the "client_id" field. func ClientIDEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClientID), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldClientID, v)) } // ClientIDNEQ applies the NEQ predicate on the "client_id" field. func ClientIDNEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClientID), v)) - }) + return predicate.AuthRequest(sql.FieldNEQ(FieldClientID, v)) } // ClientIDIn applies the In predicate on the "client_id" field. func ClientIDIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldClientID), v...)) - }) + return predicate.AuthRequest(sql.FieldIn(FieldClientID, vs...)) } // ClientIDNotIn applies the NotIn predicate on the "client_id" field. func ClientIDNotIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldClientID), v...)) - }) + return predicate.AuthRequest(sql.FieldNotIn(FieldClientID, vs...)) } // ClientIDGT applies the GT predicate on the "client_id" field. func ClientIDGT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldClientID), v)) - }) + return predicate.AuthRequest(sql.FieldGT(FieldClientID, v)) } // ClientIDGTE applies the GTE predicate on the "client_id" field. func ClientIDGTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldClientID), v)) - }) + return predicate.AuthRequest(sql.FieldGTE(FieldClientID, v)) } // ClientIDLT applies the LT predicate on the "client_id" field. func ClientIDLT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldClientID), v)) - }) + return predicate.AuthRequest(sql.FieldLT(FieldClientID, v)) } // ClientIDLTE applies the LTE predicate on the "client_id" field. func ClientIDLTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldClientID), v)) - }) + return predicate.AuthRequest(sql.FieldLTE(FieldClientID, v)) } // ClientIDContains applies the Contains predicate on the "client_id" field. func ClientIDContains(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldClientID), v)) - }) + return predicate.AuthRequest(sql.FieldContains(FieldClientID, v)) } // ClientIDHasPrefix applies the HasPrefix predicate on the "client_id" field. func ClientIDHasPrefix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldClientID), v)) - }) + return predicate.AuthRequest(sql.FieldHasPrefix(FieldClientID, v)) } // ClientIDHasSuffix applies the HasSuffix predicate on the "client_id" field. func ClientIDHasSuffix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldClientID), v)) - }) + return predicate.AuthRequest(sql.FieldHasSuffix(FieldClientID, v)) } // ClientIDEqualFold applies the EqualFold predicate on the "client_id" field. func ClientIDEqualFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldClientID), v)) - }) + return predicate.AuthRequest(sql.FieldEqualFold(FieldClientID, v)) } // ClientIDContainsFold applies the ContainsFold predicate on the "client_id" field. func ClientIDContainsFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldClientID), v)) - }) + return predicate.AuthRequest(sql.FieldContainsFold(FieldClientID, v)) } // ScopesIsNil applies the IsNil predicate on the "scopes" field. func ScopesIsNil() predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.IsNull(s.C(FieldScopes))) - }) + return predicate.AuthRequest(sql.FieldIsNull(FieldScopes)) } // ScopesNotNil applies the NotNil predicate on the "scopes" field. func ScopesNotNil() predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NotNull(s.C(FieldScopes))) - }) + return predicate.AuthRequest(sql.FieldNotNull(FieldScopes)) } // ResponseTypesIsNil applies the IsNil predicate on the "response_types" field. func ResponseTypesIsNil() predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.IsNull(s.C(FieldResponseTypes))) - }) + return predicate.AuthRequest(sql.FieldIsNull(FieldResponseTypes)) } // ResponseTypesNotNil applies the NotNil predicate on the "response_types" field. func ResponseTypesNotNil() predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NotNull(s.C(FieldResponseTypes))) - }) + return predicate.AuthRequest(sql.FieldNotNull(FieldResponseTypes)) } // RedirectURIEQ applies the EQ predicate on the "redirect_uri" field. func RedirectURIEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldRedirectURI, v)) } // RedirectURINEQ applies the NEQ predicate on the "redirect_uri" field. func RedirectURINEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthRequest(sql.FieldNEQ(FieldRedirectURI, v)) } // RedirectURIIn applies the In predicate on the "redirect_uri" field. func RedirectURIIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldRedirectURI), v...)) - }) + return predicate.AuthRequest(sql.FieldIn(FieldRedirectURI, vs...)) } // RedirectURINotIn applies the NotIn predicate on the "redirect_uri" field. func RedirectURINotIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldRedirectURI), v...)) - }) + return predicate.AuthRequest(sql.FieldNotIn(FieldRedirectURI, vs...)) } // RedirectURIGT applies the GT predicate on the "redirect_uri" field. func RedirectURIGT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthRequest(sql.FieldGT(FieldRedirectURI, v)) } // RedirectURIGTE applies the GTE predicate on the "redirect_uri" field. func RedirectURIGTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthRequest(sql.FieldGTE(FieldRedirectURI, v)) } // RedirectURILT applies the LT predicate on the "redirect_uri" field. func RedirectURILT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthRequest(sql.FieldLT(FieldRedirectURI, v)) } // RedirectURILTE applies the LTE predicate on the "redirect_uri" field. func RedirectURILTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthRequest(sql.FieldLTE(FieldRedirectURI, v)) } // RedirectURIContains applies the Contains predicate on the "redirect_uri" field. func RedirectURIContains(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthRequest(sql.FieldContains(FieldRedirectURI, v)) } // RedirectURIHasPrefix applies the HasPrefix predicate on the "redirect_uri" field. func RedirectURIHasPrefix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthRequest(sql.FieldHasPrefix(FieldRedirectURI, v)) } // RedirectURIHasSuffix applies the HasSuffix predicate on the "redirect_uri" field. func RedirectURIHasSuffix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthRequest(sql.FieldHasSuffix(FieldRedirectURI, v)) } // RedirectURIEqualFold applies the EqualFold predicate on the "redirect_uri" field. func RedirectURIEqualFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthRequest(sql.FieldEqualFold(FieldRedirectURI, v)) } // RedirectURIContainsFold applies the ContainsFold predicate on the "redirect_uri" field. func RedirectURIContainsFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldRedirectURI), v)) - }) + return predicate.AuthRequest(sql.FieldContainsFold(FieldRedirectURI, v)) } // NonceEQ applies the EQ predicate on the "nonce" field. func NonceEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldNonce), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldNonce, v)) } // NonceNEQ applies the NEQ predicate on the "nonce" field. func NonceNEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldNonce), v)) - }) + return predicate.AuthRequest(sql.FieldNEQ(FieldNonce, v)) } // NonceIn applies the In predicate on the "nonce" field. func NonceIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldNonce), v...)) - }) + return predicate.AuthRequest(sql.FieldIn(FieldNonce, vs...)) } // NonceNotIn applies the NotIn predicate on the "nonce" field. func NonceNotIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldNonce), v...)) - }) + return predicate.AuthRequest(sql.FieldNotIn(FieldNonce, vs...)) } // NonceGT applies the GT predicate on the "nonce" field. func NonceGT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldNonce), v)) - }) + return predicate.AuthRequest(sql.FieldGT(FieldNonce, v)) } // NonceGTE applies the GTE predicate on the "nonce" field. func NonceGTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldNonce), v)) - }) + return predicate.AuthRequest(sql.FieldGTE(FieldNonce, v)) } // NonceLT applies the LT predicate on the "nonce" field. func NonceLT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldNonce), v)) - }) + return predicate.AuthRequest(sql.FieldLT(FieldNonce, v)) } // NonceLTE applies the LTE predicate on the "nonce" field. func NonceLTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldNonce), v)) - }) + return predicate.AuthRequest(sql.FieldLTE(FieldNonce, v)) } // NonceContains applies the Contains predicate on the "nonce" field. func NonceContains(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldNonce), v)) - }) + return predicate.AuthRequest(sql.FieldContains(FieldNonce, v)) } // NonceHasPrefix applies the HasPrefix predicate on the "nonce" field. func NonceHasPrefix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldNonce), v)) - }) + return predicate.AuthRequest(sql.FieldHasPrefix(FieldNonce, v)) } // NonceHasSuffix applies the HasSuffix predicate on the "nonce" field. func NonceHasSuffix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldNonce), v)) - }) + return predicate.AuthRequest(sql.FieldHasSuffix(FieldNonce, v)) } // NonceEqualFold applies the EqualFold predicate on the "nonce" field. func NonceEqualFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldNonce), v)) - }) + return predicate.AuthRequest(sql.FieldEqualFold(FieldNonce, v)) } // NonceContainsFold applies the ContainsFold predicate on the "nonce" field. func NonceContainsFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldNonce), v)) - }) + return predicate.AuthRequest(sql.FieldContainsFold(FieldNonce, v)) } // StateEQ applies the EQ predicate on the "state" field. func StateEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldState), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldState, v)) } // StateNEQ applies the NEQ predicate on the "state" field. func StateNEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldState), v)) - }) + return predicate.AuthRequest(sql.FieldNEQ(FieldState, v)) } // StateIn applies the In predicate on the "state" field. func StateIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldState), v...)) - }) + return predicate.AuthRequest(sql.FieldIn(FieldState, vs...)) } // StateNotIn applies the NotIn predicate on the "state" field. func StateNotIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldState), v...)) - }) + return predicate.AuthRequest(sql.FieldNotIn(FieldState, vs...)) } // StateGT applies the GT predicate on the "state" field. func StateGT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldState), v)) - }) + return predicate.AuthRequest(sql.FieldGT(FieldState, v)) } // StateGTE applies the GTE predicate on the "state" field. func StateGTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldState), v)) - }) + return predicate.AuthRequest(sql.FieldGTE(FieldState, v)) } // StateLT applies the LT predicate on the "state" field. func StateLT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldState), v)) - }) + return predicate.AuthRequest(sql.FieldLT(FieldState, v)) } // StateLTE applies the LTE predicate on the "state" field. func StateLTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldState), v)) - }) + return predicate.AuthRequest(sql.FieldLTE(FieldState, v)) } // StateContains applies the Contains predicate on the "state" field. func StateContains(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldState), v)) - }) + return predicate.AuthRequest(sql.FieldContains(FieldState, v)) } // StateHasPrefix applies the HasPrefix predicate on the "state" field. func StateHasPrefix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldState), v)) - }) + return predicate.AuthRequest(sql.FieldHasPrefix(FieldState, v)) } // StateHasSuffix applies the HasSuffix predicate on the "state" field. func StateHasSuffix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldState), v)) - }) + return predicate.AuthRequest(sql.FieldHasSuffix(FieldState, v)) } // StateEqualFold applies the EqualFold predicate on the "state" field. func StateEqualFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldState), v)) - }) + return predicate.AuthRequest(sql.FieldEqualFold(FieldState, v)) } // StateContainsFold applies the ContainsFold predicate on the "state" field. func StateContainsFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldState), v)) - }) + return predicate.AuthRequest(sql.FieldContainsFold(FieldState, v)) } // ForceApprovalPromptEQ applies the EQ predicate on the "force_approval_prompt" field. func ForceApprovalPromptEQ(v bool) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldForceApprovalPrompt), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldForceApprovalPrompt, v)) } // ForceApprovalPromptNEQ applies the NEQ predicate on the "force_approval_prompt" field. func ForceApprovalPromptNEQ(v bool) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldForceApprovalPrompt), v)) - }) + return predicate.AuthRequest(sql.FieldNEQ(FieldForceApprovalPrompt, v)) } // LoggedInEQ applies the EQ predicate on the "logged_in" field. func LoggedInEQ(v bool) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldLoggedIn), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldLoggedIn, v)) } // LoggedInNEQ applies the NEQ predicate on the "logged_in" field. func LoggedInNEQ(v bool) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldLoggedIn), v)) - }) + return predicate.AuthRequest(sql.FieldNEQ(FieldLoggedIn, v)) } // ClaimsUserIDEQ applies the EQ predicate on the "claims_user_id" field. func ClaimsUserIDEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldClaimsUserID, v)) } // ClaimsUserIDNEQ applies the NEQ predicate on the "claims_user_id" field. func ClaimsUserIDNEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthRequest(sql.FieldNEQ(FieldClaimsUserID, v)) } // ClaimsUserIDIn applies the In predicate on the "claims_user_id" field. func ClaimsUserIDIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldClaimsUserID), v...)) - }) + return predicate.AuthRequest(sql.FieldIn(FieldClaimsUserID, vs...)) } // ClaimsUserIDNotIn applies the NotIn predicate on the "claims_user_id" field. func ClaimsUserIDNotIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldClaimsUserID), v...)) - }) + return predicate.AuthRequest(sql.FieldNotIn(FieldClaimsUserID, vs...)) } // ClaimsUserIDGT applies the GT predicate on the "claims_user_id" field. func ClaimsUserIDGT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthRequest(sql.FieldGT(FieldClaimsUserID, v)) } // ClaimsUserIDGTE applies the GTE predicate on the "claims_user_id" field. func ClaimsUserIDGTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthRequest(sql.FieldGTE(FieldClaimsUserID, v)) } // ClaimsUserIDLT applies the LT predicate on the "claims_user_id" field. func ClaimsUserIDLT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthRequest(sql.FieldLT(FieldClaimsUserID, v)) } // ClaimsUserIDLTE applies the LTE predicate on the "claims_user_id" field. func ClaimsUserIDLTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthRequest(sql.FieldLTE(FieldClaimsUserID, v)) } // ClaimsUserIDContains applies the Contains predicate on the "claims_user_id" field. func ClaimsUserIDContains(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthRequest(sql.FieldContains(FieldClaimsUserID, v)) } // ClaimsUserIDHasPrefix applies the HasPrefix predicate on the "claims_user_id" field. func ClaimsUserIDHasPrefix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthRequest(sql.FieldHasPrefix(FieldClaimsUserID, v)) } // ClaimsUserIDHasSuffix applies the HasSuffix predicate on the "claims_user_id" field. func ClaimsUserIDHasSuffix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthRequest(sql.FieldHasSuffix(FieldClaimsUserID, v)) } // ClaimsUserIDEqualFold applies the EqualFold predicate on the "claims_user_id" field. func ClaimsUserIDEqualFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthRequest(sql.FieldEqualFold(FieldClaimsUserID, v)) } // ClaimsUserIDContainsFold applies the ContainsFold predicate on the "claims_user_id" field. func ClaimsUserIDContainsFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldClaimsUserID), v)) - }) + return predicate.AuthRequest(sql.FieldContainsFold(FieldClaimsUserID, v)) } // ClaimsUsernameEQ applies the EQ predicate on the "claims_username" field. func ClaimsUsernameEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldClaimsUsername, v)) } // ClaimsUsernameNEQ applies the NEQ predicate on the "claims_username" field. func ClaimsUsernameNEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthRequest(sql.FieldNEQ(FieldClaimsUsername, v)) } // ClaimsUsernameIn applies the In predicate on the "claims_username" field. func ClaimsUsernameIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldClaimsUsername), v...)) - }) + return predicate.AuthRequest(sql.FieldIn(FieldClaimsUsername, vs...)) } // ClaimsUsernameNotIn applies the NotIn predicate on the "claims_username" field. func ClaimsUsernameNotIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldClaimsUsername), v...)) - }) + return predicate.AuthRequest(sql.FieldNotIn(FieldClaimsUsername, vs...)) } // ClaimsUsernameGT applies the GT predicate on the "claims_username" field. func ClaimsUsernameGT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthRequest(sql.FieldGT(FieldClaimsUsername, v)) } // ClaimsUsernameGTE applies the GTE predicate on the "claims_username" field. func ClaimsUsernameGTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthRequest(sql.FieldGTE(FieldClaimsUsername, v)) } // ClaimsUsernameLT applies the LT predicate on the "claims_username" field. func ClaimsUsernameLT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthRequest(sql.FieldLT(FieldClaimsUsername, v)) } // ClaimsUsernameLTE applies the LTE predicate on the "claims_username" field. func ClaimsUsernameLTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthRequest(sql.FieldLTE(FieldClaimsUsername, v)) } // ClaimsUsernameContains applies the Contains predicate on the "claims_username" field. func ClaimsUsernameContains(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthRequest(sql.FieldContains(FieldClaimsUsername, v)) } // ClaimsUsernameHasPrefix applies the HasPrefix predicate on the "claims_username" field. func ClaimsUsernameHasPrefix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthRequest(sql.FieldHasPrefix(FieldClaimsUsername, v)) } // ClaimsUsernameHasSuffix applies the HasSuffix predicate on the "claims_username" field. func ClaimsUsernameHasSuffix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthRequest(sql.FieldHasSuffix(FieldClaimsUsername, v)) } // ClaimsUsernameEqualFold applies the EqualFold predicate on the "claims_username" field. func ClaimsUsernameEqualFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthRequest(sql.FieldEqualFold(FieldClaimsUsername, v)) } // ClaimsUsernameContainsFold applies the ContainsFold predicate on the "claims_username" field. func ClaimsUsernameContainsFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldClaimsUsername), v)) - }) + return predicate.AuthRequest(sql.FieldContainsFold(FieldClaimsUsername, v)) } // ClaimsEmailEQ applies the EQ predicate on the "claims_email" field. func ClaimsEmailEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldClaimsEmail, v)) } // ClaimsEmailNEQ applies the NEQ predicate on the "claims_email" field. func ClaimsEmailNEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthRequest(sql.FieldNEQ(FieldClaimsEmail, v)) } // ClaimsEmailIn applies the In predicate on the "claims_email" field. func ClaimsEmailIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldClaimsEmail), v...)) - }) + return predicate.AuthRequest(sql.FieldIn(FieldClaimsEmail, vs...)) } // ClaimsEmailNotIn applies the NotIn predicate on the "claims_email" field. func ClaimsEmailNotIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldClaimsEmail), v...)) - }) + return predicate.AuthRequest(sql.FieldNotIn(FieldClaimsEmail, vs...)) } // ClaimsEmailGT applies the GT predicate on the "claims_email" field. func ClaimsEmailGT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthRequest(sql.FieldGT(FieldClaimsEmail, v)) } // ClaimsEmailGTE applies the GTE predicate on the "claims_email" field. func ClaimsEmailGTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthRequest(sql.FieldGTE(FieldClaimsEmail, v)) } // ClaimsEmailLT applies the LT predicate on the "claims_email" field. func ClaimsEmailLT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthRequest(sql.FieldLT(FieldClaimsEmail, v)) } // ClaimsEmailLTE applies the LTE predicate on the "claims_email" field. func ClaimsEmailLTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthRequest(sql.FieldLTE(FieldClaimsEmail, v)) } // ClaimsEmailContains applies the Contains predicate on the "claims_email" field. func ClaimsEmailContains(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthRequest(sql.FieldContains(FieldClaimsEmail, v)) } // ClaimsEmailHasPrefix applies the HasPrefix predicate on the "claims_email" field. func ClaimsEmailHasPrefix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthRequest(sql.FieldHasPrefix(FieldClaimsEmail, v)) } // ClaimsEmailHasSuffix applies the HasSuffix predicate on the "claims_email" field. func ClaimsEmailHasSuffix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthRequest(sql.FieldHasSuffix(FieldClaimsEmail, v)) } // ClaimsEmailEqualFold applies the EqualFold predicate on the "claims_email" field. func ClaimsEmailEqualFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthRequest(sql.FieldEqualFold(FieldClaimsEmail, v)) } // ClaimsEmailContainsFold applies the ContainsFold predicate on the "claims_email" field. func ClaimsEmailContainsFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldClaimsEmail), v)) - }) + return predicate.AuthRequest(sql.FieldContainsFold(FieldClaimsEmail, v)) } // ClaimsEmailVerifiedEQ applies the EQ predicate on the "claims_email_verified" field. func ClaimsEmailVerifiedEQ(v bool) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsEmailVerified), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldClaimsEmailVerified, v)) } // ClaimsEmailVerifiedNEQ applies the NEQ predicate on the "claims_email_verified" field. func ClaimsEmailVerifiedNEQ(v bool) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClaimsEmailVerified), v)) - }) + return predicate.AuthRequest(sql.FieldNEQ(FieldClaimsEmailVerified, v)) } // ClaimsGroupsIsNil applies the IsNil predicate on the "claims_groups" field. func ClaimsGroupsIsNil() predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.IsNull(s.C(FieldClaimsGroups))) - }) + return predicate.AuthRequest(sql.FieldIsNull(FieldClaimsGroups)) } // ClaimsGroupsNotNil applies the NotNil predicate on the "claims_groups" field. func ClaimsGroupsNotNil() predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NotNull(s.C(FieldClaimsGroups))) - }) + return predicate.AuthRequest(sql.FieldNotNull(FieldClaimsGroups)) } // ClaimsPreferredUsernameEQ applies the EQ predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameNEQ applies the NEQ predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameNEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthRequest(sql.FieldNEQ(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameIn applies the In predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldClaimsPreferredUsername), v...)) - }) + return predicate.AuthRequest(sql.FieldIn(FieldClaimsPreferredUsername, vs...)) } // ClaimsPreferredUsernameNotIn applies the NotIn predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameNotIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldClaimsPreferredUsername), v...)) - }) + return predicate.AuthRequest(sql.FieldNotIn(FieldClaimsPreferredUsername, vs...)) } // ClaimsPreferredUsernameGT applies the GT predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameGT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthRequest(sql.FieldGT(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameGTE applies the GTE predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameGTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthRequest(sql.FieldGTE(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameLT applies the LT predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameLT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthRequest(sql.FieldLT(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameLTE applies the LTE predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameLTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthRequest(sql.FieldLTE(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameContains applies the Contains predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameContains(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthRequest(sql.FieldContains(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameHasPrefix applies the HasPrefix predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameHasPrefix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthRequest(sql.FieldHasPrefix(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameHasSuffix applies the HasSuffix predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameHasSuffix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthRequest(sql.FieldHasSuffix(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameEqualFold applies the EqualFold predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameEqualFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthRequest(sql.FieldEqualFold(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameContainsFold applies the ContainsFold predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameContainsFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.AuthRequest(sql.FieldContainsFold(FieldClaimsPreferredUsername, v)) } // ConnectorIDEQ applies the EQ predicate on the "connector_id" field. func ConnectorIDEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldConnectorID), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldConnectorID, v)) } // ConnectorIDNEQ applies the NEQ predicate on the "connector_id" field. func ConnectorIDNEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldConnectorID), v)) - }) + return predicate.AuthRequest(sql.FieldNEQ(FieldConnectorID, v)) } // ConnectorIDIn applies the In predicate on the "connector_id" field. func ConnectorIDIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldConnectorID), v...)) - }) + return predicate.AuthRequest(sql.FieldIn(FieldConnectorID, vs...)) } // ConnectorIDNotIn applies the NotIn predicate on the "connector_id" field. func ConnectorIDNotIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldConnectorID), v...)) - }) + return predicate.AuthRequest(sql.FieldNotIn(FieldConnectorID, vs...)) } // ConnectorIDGT applies the GT predicate on the "connector_id" field. func ConnectorIDGT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldConnectorID), v)) - }) + return predicate.AuthRequest(sql.FieldGT(FieldConnectorID, v)) } // ConnectorIDGTE applies the GTE predicate on the "connector_id" field. func ConnectorIDGTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldConnectorID), v)) - }) + return predicate.AuthRequest(sql.FieldGTE(FieldConnectorID, v)) } // ConnectorIDLT applies the LT predicate on the "connector_id" field. func ConnectorIDLT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldConnectorID), v)) - }) + return predicate.AuthRequest(sql.FieldLT(FieldConnectorID, v)) } // ConnectorIDLTE applies the LTE predicate on the "connector_id" field. func ConnectorIDLTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldConnectorID), v)) - }) + return predicate.AuthRequest(sql.FieldLTE(FieldConnectorID, v)) } // ConnectorIDContains applies the Contains predicate on the "connector_id" field. func ConnectorIDContains(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldConnectorID), v)) - }) + return predicate.AuthRequest(sql.FieldContains(FieldConnectorID, v)) } // ConnectorIDHasPrefix applies the HasPrefix predicate on the "connector_id" field. func ConnectorIDHasPrefix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldConnectorID), v)) - }) + return predicate.AuthRequest(sql.FieldHasPrefix(FieldConnectorID, v)) } // ConnectorIDHasSuffix applies the HasSuffix predicate on the "connector_id" field. func ConnectorIDHasSuffix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldConnectorID), v)) - }) + return predicate.AuthRequest(sql.FieldHasSuffix(FieldConnectorID, v)) } // ConnectorIDEqualFold applies the EqualFold predicate on the "connector_id" field. func ConnectorIDEqualFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldConnectorID), v)) - }) + return predicate.AuthRequest(sql.FieldEqualFold(FieldConnectorID, v)) } // ConnectorIDContainsFold applies the ContainsFold predicate on the "connector_id" field. func ConnectorIDContainsFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldConnectorID), v)) - }) + return predicate.AuthRequest(sql.FieldContainsFold(FieldConnectorID, v)) } // ConnectorDataEQ applies the EQ predicate on the "connector_data" field. func ConnectorDataEQ(v []byte) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldConnectorData), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldConnectorData, v)) } // ConnectorDataNEQ applies the NEQ predicate on the "connector_data" field. func ConnectorDataNEQ(v []byte) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldConnectorData), v)) - }) + return predicate.AuthRequest(sql.FieldNEQ(FieldConnectorData, v)) } // ConnectorDataIn applies the In predicate on the "connector_data" field. func ConnectorDataIn(vs ...[]byte) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldConnectorData), v...)) - }) + return predicate.AuthRequest(sql.FieldIn(FieldConnectorData, vs...)) } // ConnectorDataNotIn applies the NotIn predicate on the "connector_data" field. func ConnectorDataNotIn(vs ...[]byte) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldConnectorData), v...)) - }) + return predicate.AuthRequest(sql.FieldNotIn(FieldConnectorData, vs...)) } // ConnectorDataGT applies the GT predicate on the "connector_data" field. func ConnectorDataGT(v []byte) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldConnectorData), v)) - }) + return predicate.AuthRequest(sql.FieldGT(FieldConnectorData, v)) } // ConnectorDataGTE applies the GTE predicate on the "connector_data" field. func ConnectorDataGTE(v []byte) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldConnectorData), v)) - }) + return predicate.AuthRequest(sql.FieldGTE(FieldConnectorData, v)) } // ConnectorDataLT applies the LT predicate on the "connector_data" field. func ConnectorDataLT(v []byte) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldConnectorData), v)) - }) + return predicate.AuthRequest(sql.FieldLT(FieldConnectorData, v)) } // ConnectorDataLTE applies the LTE predicate on the "connector_data" field. func ConnectorDataLTE(v []byte) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldConnectorData), v)) - }) + return predicate.AuthRequest(sql.FieldLTE(FieldConnectorData, v)) } // ConnectorDataIsNil applies the IsNil predicate on the "connector_data" field. func ConnectorDataIsNil() predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.IsNull(s.C(FieldConnectorData))) - }) + return predicate.AuthRequest(sql.FieldIsNull(FieldConnectorData)) } // ConnectorDataNotNil applies the NotNil predicate on the "connector_data" field. func ConnectorDataNotNil() predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NotNull(s.C(FieldConnectorData))) - }) + return predicate.AuthRequest(sql.FieldNotNull(FieldConnectorData)) } // ExpiryEQ applies the EQ predicate on the "expiry" field. func ExpiryEQ(v time.Time) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldExpiry), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldExpiry, v)) } // ExpiryNEQ applies the NEQ predicate on the "expiry" field. func ExpiryNEQ(v time.Time) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldExpiry), v)) - }) + return predicate.AuthRequest(sql.FieldNEQ(FieldExpiry, v)) } // ExpiryIn applies the In predicate on the "expiry" field. func ExpiryIn(vs ...time.Time) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldExpiry), v...)) - }) + return predicate.AuthRequest(sql.FieldIn(FieldExpiry, vs...)) } // ExpiryNotIn applies the NotIn predicate on the "expiry" field. func ExpiryNotIn(vs ...time.Time) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldExpiry), v...)) - }) + return predicate.AuthRequest(sql.FieldNotIn(FieldExpiry, vs...)) } // ExpiryGT applies the GT predicate on the "expiry" field. func ExpiryGT(v time.Time) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldExpiry), v)) - }) + return predicate.AuthRequest(sql.FieldGT(FieldExpiry, v)) } // ExpiryGTE applies the GTE predicate on the "expiry" field. func ExpiryGTE(v time.Time) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldExpiry), v)) - }) + return predicate.AuthRequest(sql.FieldGTE(FieldExpiry, v)) } // ExpiryLT applies the LT predicate on the "expiry" field. func ExpiryLT(v time.Time) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldExpiry), v)) - }) + return predicate.AuthRequest(sql.FieldLT(FieldExpiry, v)) } // ExpiryLTE applies the LTE predicate on the "expiry" field. func ExpiryLTE(v time.Time) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldExpiry), v)) - }) + return predicate.AuthRequest(sql.FieldLTE(FieldExpiry, v)) } // CodeChallengeEQ applies the EQ predicate on the "code_challenge" field. func CodeChallengeEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldCodeChallenge, v)) } // CodeChallengeNEQ applies the NEQ predicate on the "code_challenge" field. func CodeChallengeNEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthRequest(sql.FieldNEQ(FieldCodeChallenge, v)) } // CodeChallengeIn applies the In predicate on the "code_challenge" field. func CodeChallengeIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldCodeChallenge), v...)) - }) + return predicate.AuthRequest(sql.FieldIn(FieldCodeChallenge, vs...)) } // CodeChallengeNotIn applies the NotIn predicate on the "code_challenge" field. func CodeChallengeNotIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldCodeChallenge), v...)) - }) + return predicate.AuthRequest(sql.FieldNotIn(FieldCodeChallenge, vs...)) } // CodeChallengeGT applies the GT predicate on the "code_challenge" field. func CodeChallengeGT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthRequest(sql.FieldGT(FieldCodeChallenge, v)) } // CodeChallengeGTE applies the GTE predicate on the "code_challenge" field. func CodeChallengeGTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthRequest(sql.FieldGTE(FieldCodeChallenge, v)) } // CodeChallengeLT applies the LT predicate on the "code_challenge" field. func CodeChallengeLT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthRequest(sql.FieldLT(FieldCodeChallenge, v)) } // CodeChallengeLTE applies the LTE predicate on the "code_challenge" field. func CodeChallengeLTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthRequest(sql.FieldLTE(FieldCodeChallenge, v)) } // CodeChallengeContains applies the Contains predicate on the "code_challenge" field. func CodeChallengeContains(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthRequest(sql.FieldContains(FieldCodeChallenge, v)) } // CodeChallengeHasPrefix applies the HasPrefix predicate on the "code_challenge" field. func CodeChallengeHasPrefix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthRequest(sql.FieldHasPrefix(FieldCodeChallenge, v)) } // CodeChallengeHasSuffix applies the HasSuffix predicate on the "code_challenge" field. func CodeChallengeHasSuffix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthRequest(sql.FieldHasSuffix(FieldCodeChallenge, v)) } // CodeChallengeEqualFold applies the EqualFold predicate on the "code_challenge" field. func CodeChallengeEqualFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthRequest(sql.FieldEqualFold(FieldCodeChallenge, v)) } // CodeChallengeContainsFold applies the ContainsFold predicate on the "code_challenge" field. func CodeChallengeContainsFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldCodeChallenge), v)) - }) + return predicate.AuthRequest(sql.FieldContainsFold(FieldCodeChallenge, v)) } // CodeChallengeMethodEQ applies the EQ predicate on the "code_challenge_method" field. func CodeChallengeMethodEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthRequest(sql.FieldEQ(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodNEQ applies the NEQ predicate on the "code_challenge_method" field. func CodeChallengeMethodNEQ(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthRequest(sql.FieldNEQ(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodIn applies the In predicate on the "code_challenge_method" field. func CodeChallengeMethodIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldCodeChallengeMethod), v...)) - }) + return predicate.AuthRequest(sql.FieldIn(FieldCodeChallengeMethod, vs...)) } // CodeChallengeMethodNotIn applies the NotIn predicate on the "code_challenge_method" field. func CodeChallengeMethodNotIn(vs ...string) predicate.AuthRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldCodeChallengeMethod), v...)) - }) + return predicate.AuthRequest(sql.FieldNotIn(FieldCodeChallengeMethod, vs...)) } // CodeChallengeMethodGT applies the GT predicate on the "code_challenge_method" field. func CodeChallengeMethodGT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthRequest(sql.FieldGT(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodGTE applies the GTE predicate on the "code_challenge_method" field. func CodeChallengeMethodGTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthRequest(sql.FieldGTE(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodLT applies the LT predicate on the "code_challenge_method" field. func CodeChallengeMethodLT(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthRequest(sql.FieldLT(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodLTE applies the LTE predicate on the "code_challenge_method" field. func CodeChallengeMethodLTE(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthRequest(sql.FieldLTE(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodContains applies the Contains predicate on the "code_challenge_method" field. func CodeChallengeMethodContains(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthRequest(sql.FieldContains(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodHasPrefix applies the HasPrefix predicate on the "code_challenge_method" field. func CodeChallengeMethodHasPrefix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthRequest(sql.FieldHasPrefix(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodHasSuffix applies the HasSuffix predicate on the "code_challenge_method" field. func CodeChallengeMethodHasSuffix(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthRequest(sql.FieldHasSuffix(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodEqualFold applies the EqualFold predicate on the "code_challenge_method" field. func CodeChallengeMethodEqualFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthRequest(sql.FieldEqualFold(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodContainsFold applies the ContainsFold predicate on the "code_challenge_method" field. func CodeChallengeMethodContainsFold(v string) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.AuthRequest(sql.FieldContainsFold(FieldCodeChallengeMethod, v)) +} + +// HmacKeyEQ applies the EQ predicate on the "hmac_key" field. +func HmacKeyEQ(v []byte) predicate.AuthRequest { + return predicate.AuthRequest(sql.FieldEQ(FieldHmacKey, v)) +} + +// HmacKeyNEQ applies the NEQ predicate on the "hmac_key" field. +func HmacKeyNEQ(v []byte) predicate.AuthRequest { + return predicate.AuthRequest(sql.FieldNEQ(FieldHmacKey, v)) +} + +// HmacKeyIn applies the In predicate on the "hmac_key" field. +func HmacKeyIn(vs ...[]byte) predicate.AuthRequest { + return predicate.AuthRequest(sql.FieldIn(FieldHmacKey, vs...)) +} + +// HmacKeyNotIn applies the NotIn predicate on the "hmac_key" field. +func HmacKeyNotIn(vs ...[]byte) predicate.AuthRequest { + return predicate.AuthRequest(sql.FieldNotIn(FieldHmacKey, vs...)) +} + +// HmacKeyGT applies the GT predicate on the "hmac_key" field. +func HmacKeyGT(v []byte) predicate.AuthRequest { + return predicate.AuthRequest(sql.FieldGT(FieldHmacKey, v)) +} + +// HmacKeyGTE applies the GTE predicate on the "hmac_key" field. +func HmacKeyGTE(v []byte) predicate.AuthRequest { + return predicate.AuthRequest(sql.FieldGTE(FieldHmacKey, v)) +} + +// HmacKeyLT applies the LT predicate on the "hmac_key" field. +func HmacKeyLT(v []byte) predicate.AuthRequest { + return predicate.AuthRequest(sql.FieldLT(FieldHmacKey, v)) +} + +// HmacKeyLTE applies the LTE predicate on the "hmac_key" field. +func HmacKeyLTE(v []byte) predicate.AuthRequest { + return predicate.AuthRequest(sql.FieldLTE(FieldHmacKey, v)) } // And groups predicates with the AND operator between them. func And(predicates ...predicate.AuthRequest) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for _, p := range predicates { - p(s1) - } - s.Where(s1.P()) - }) + return predicate.AuthRequest(sql.AndPredicates(predicates...)) } // Or groups predicates with the OR operator between them. func Or(predicates ...predicate.AuthRequest) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for i, p := range predicates { - if i > 0 { - s1.Or() - } - p(s1) - } - s.Where(s1.P()) - }) + return predicate.AuthRequest(sql.OrPredicates(predicates...)) } // Not applies the not operator on the given predicate. func Not(p predicate.AuthRequest) predicate.AuthRequest { - return predicate.AuthRequest(func(s *sql.Selector) { - p(s.Not()) - }) + return predicate.AuthRequest(sql.NotPredicates(p)) } diff --git a/storage/ent/db/authrequest_create.go b/storage/ent/db/authrequest_create.go index 63e0357dc5..6224ef8eb0 100644 --- a/storage/ent/db/authrequest_create.go +++ b/storage/ent/db/authrequest_create.go @@ -21,205 +21,169 @@ type AuthRequestCreate struct { } // SetClientID sets the "client_id" field. -func (arc *AuthRequestCreate) SetClientID(s string) *AuthRequestCreate { - arc.mutation.SetClientID(s) - return arc +func (_c *AuthRequestCreate) SetClientID(v string) *AuthRequestCreate { + _c.mutation.SetClientID(v) + return _c } // SetScopes sets the "scopes" field. -func (arc *AuthRequestCreate) SetScopes(s []string) *AuthRequestCreate { - arc.mutation.SetScopes(s) - return arc +func (_c *AuthRequestCreate) SetScopes(v []string) *AuthRequestCreate { + _c.mutation.SetScopes(v) + return _c } // SetResponseTypes sets the "response_types" field. -func (arc *AuthRequestCreate) SetResponseTypes(s []string) *AuthRequestCreate { - arc.mutation.SetResponseTypes(s) - return arc +func (_c *AuthRequestCreate) SetResponseTypes(v []string) *AuthRequestCreate { + _c.mutation.SetResponseTypes(v) + return _c } // SetRedirectURI sets the "redirect_uri" field. -func (arc *AuthRequestCreate) SetRedirectURI(s string) *AuthRequestCreate { - arc.mutation.SetRedirectURI(s) - return arc +func (_c *AuthRequestCreate) SetRedirectURI(v string) *AuthRequestCreate { + _c.mutation.SetRedirectURI(v) + return _c } // SetNonce sets the "nonce" field. -func (arc *AuthRequestCreate) SetNonce(s string) *AuthRequestCreate { - arc.mutation.SetNonce(s) - return arc +func (_c *AuthRequestCreate) SetNonce(v string) *AuthRequestCreate { + _c.mutation.SetNonce(v) + return _c } // SetState sets the "state" field. -func (arc *AuthRequestCreate) SetState(s string) *AuthRequestCreate { - arc.mutation.SetState(s) - return arc +func (_c *AuthRequestCreate) SetState(v string) *AuthRequestCreate { + _c.mutation.SetState(v) + return _c } // SetForceApprovalPrompt sets the "force_approval_prompt" field. -func (arc *AuthRequestCreate) SetForceApprovalPrompt(b bool) *AuthRequestCreate { - arc.mutation.SetForceApprovalPrompt(b) - return arc +func (_c *AuthRequestCreate) SetForceApprovalPrompt(v bool) *AuthRequestCreate { + _c.mutation.SetForceApprovalPrompt(v) + return _c } // SetLoggedIn sets the "logged_in" field. -func (arc *AuthRequestCreate) SetLoggedIn(b bool) *AuthRequestCreate { - arc.mutation.SetLoggedIn(b) - return arc +func (_c *AuthRequestCreate) SetLoggedIn(v bool) *AuthRequestCreate { + _c.mutation.SetLoggedIn(v) + return _c } // SetClaimsUserID sets the "claims_user_id" field. -func (arc *AuthRequestCreate) SetClaimsUserID(s string) *AuthRequestCreate { - arc.mutation.SetClaimsUserID(s) - return arc +func (_c *AuthRequestCreate) SetClaimsUserID(v string) *AuthRequestCreate { + _c.mutation.SetClaimsUserID(v) + return _c } // SetClaimsUsername sets the "claims_username" field. -func (arc *AuthRequestCreate) SetClaimsUsername(s string) *AuthRequestCreate { - arc.mutation.SetClaimsUsername(s) - return arc +func (_c *AuthRequestCreate) SetClaimsUsername(v string) *AuthRequestCreate { + _c.mutation.SetClaimsUsername(v) + return _c } // SetClaimsEmail sets the "claims_email" field. -func (arc *AuthRequestCreate) SetClaimsEmail(s string) *AuthRequestCreate { - arc.mutation.SetClaimsEmail(s) - return arc +func (_c *AuthRequestCreate) SetClaimsEmail(v string) *AuthRequestCreate { + _c.mutation.SetClaimsEmail(v) + return _c } // SetClaimsEmailVerified sets the "claims_email_verified" field. -func (arc *AuthRequestCreate) SetClaimsEmailVerified(b bool) *AuthRequestCreate { - arc.mutation.SetClaimsEmailVerified(b) - return arc +func (_c *AuthRequestCreate) SetClaimsEmailVerified(v bool) *AuthRequestCreate { + _c.mutation.SetClaimsEmailVerified(v) + return _c } // SetClaimsGroups sets the "claims_groups" field. -func (arc *AuthRequestCreate) SetClaimsGroups(s []string) *AuthRequestCreate { - arc.mutation.SetClaimsGroups(s) - return arc +func (_c *AuthRequestCreate) SetClaimsGroups(v []string) *AuthRequestCreate { + _c.mutation.SetClaimsGroups(v) + return _c } // SetClaimsPreferredUsername sets the "claims_preferred_username" field. -func (arc *AuthRequestCreate) SetClaimsPreferredUsername(s string) *AuthRequestCreate { - arc.mutation.SetClaimsPreferredUsername(s) - return arc +func (_c *AuthRequestCreate) SetClaimsPreferredUsername(v string) *AuthRequestCreate { + _c.mutation.SetClaimsPreferredUsername(v) + return _c } // SetNillableClaimsPreferredUsername sets the "claims_preferred_username" field if the given value is not nil. -func (arc *AuthRequestCreate) SetNillableClaimsPreferredUsername(s *string) *AuthRequestCreate { - if s != nil { - arc.SetClaimsPreferredUsername(*s) +func (_c *AuthRequestCreate) SetNillableClaimsPreferredUsername(v *string) *AuthRequestCreate { + if v != nil { + _c.SetClaimsPreferredUsername(*v) } - return arc + return _c } // SetConnectorID sets the "connector_id" field. -func (arc *AuthRequestCreate) SetConnectorID(s string) *AuthRequestCreate { - arc.mutation.SetConnectorID(s) - return arc +func (_c *AuthRequestCreate) SetConnectorID(v string) *AuthRequestCreate { + _c.mutation.SetConnectorID(v) + return _c } // SetConnectorData sets the "connector_data" field. -func (arc *AuthRequestCreate) SetConnectorData(b []byte) *AuthRequestCreate { - arc.mutation.SetConnectorData(b) - return arc +func (_c *AuthRequestCreate) SetConnectorData(v []byte) *AuthRequestCreate { + _c.mutation.SetConnectorData(v) + return _c } // SetExpiry sets the "expiry" field. -func (arc *AuthRequestCreate) SetExpiry(t time.Time) *AuthRequestCreate { - arc.mutation.SetExpiry(t) - return arc +func (_c *AuthRequestCreate) SetExpiry(v time.Time) *AuthRequestCreate { + _c.mutation.SetExpiry(v) + return _c } // SetCodeChallenge sets the "code_challenge" field. -func (arc *AuthRequestCreate) SetCodeChallenge(s string) *AuthRequestCreate { - arc.mutation.SetCodeChallenge(s) - return arc +func (_c *AuthRequestCreate) SetCodeChallenge(v string) *AuthRequestCreate { + _c.mutation.SetCodeChallenge(v) + return _c } // SetNillableCodeChallenge sets the "code_challenge" field if the given value is not nil. -func (arc *AuthRequestCreate) SetNillableCodeChallenge(s *string) *AuthRequestCreate { - if s != nil { - arc.SetCodeChallenge(*s) +func (_c *AuthRequestCreate) SetNillableCodeChallenge(v *string) *AuthRequestCreate { + if v != nil { + _c.SetCodeChallenge(*v) } - return arc + return _c } // SetCodeChallengeMethod sets the "code_challenge_method" field. -func (arc *AuthRequestCreate) SetCodeChallengeMethod(s string) *AuthRequestCreate { - arc.mutation.SetCodeChallengeMethod(s) - return arc +func (_c *AuthRequestCreate) SetCodeChallengeMethod(v string) *AuthRequestCreate { + _c.mutation.SetCodeChallengeMethod(v) + return _c } // SetNillableCodeChallengeMethod sets the "code_challenge_method" field if the given value is not nil. -func (arc *AuthRequestCreate) SetNillableCodeChallengeMethod(s *string) *AuthRequestCreate { - if s != nil { - arc.SetCodeChallengeMethod(*s) +func (_c *AuthRequestCreate) SetNillableCodeChallengeMethod(v *string) *AuthRequestCreate { + if v != nil { + _c.SetCodeChallengeMethod(*v) } - return arc + return _c +} + +// SetHmacKey sets the "hmac_key" field. +func (_c *AuthRequestCreate) SetHmacKey(v []byte) *AuthRequestCreate { + _c.mutation.SetHmacKey(v) + return _c } // SetID sets the "id" field. -func (arc *AuthRequestCreate) SetID(s string) *AuthRequestCreate { - arc.mutation.SetID(s) - return arc +func (_c *AuthRequestCreate) SetID(v string) *AuthRequestCreate { + _c.mutation.SetID(v) + return _c } // Mutation returns the AuthRequestMutation object of the builder. -func (arc *AuthRequestCreate) Mutation() *AuthRequestMutation { - return arc.mutation +func (_c *AuthRequestCreate) Mutation() *AuthRequestMutation { + return _c.mutation } // Save creates the AuthRequest in the database. -func (arc *AuthRequestCreate) Save(ctx context.Context) (*AuthRequest, error) { - var ( - err error - node *AuthRequest - ) - arc.defaults() - if len(arc.hooks) == 0 { - if err = arc.check(); err != nil { - return nil, err - } - node, err = arc.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*AuthRequestMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = arc.check(); err != nil { - return nil, err - } - arc.mutation = mutation - if node, err = arc.sqlSave(ctx); err != nil { - return nil, err - } - mutation.id = &node.ID - mutation.done = true - return node, err - }) - for i := len(arc.hooks) - 1; i >= 0; i-- { - if arc.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = arc.hooks[i](mut) - } - v, err := mut.Mutate(ctx, arc.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*AuthRequest) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from AuthRequestMutation", v) - } - node = nv - } - return node, err +func (_c *AuthRequestCreate) Save(ctx context.Context) (*AuthRequest, error) { + _c.defaults() + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) } // SaveX calls Save and panics if Save returns an error. -func (arc *AuthRequestCreate) SaveX(ctx context.Context) *AuthRequest { - v, err := arc.Save(ctx) +func (_c *AuthRequestCreate) SaveX(ctx context.Context) *AuthRequest { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -227,82 +191,85 @@ func (arc *AuthRequestCreate) SaveX(ctx context.Context) *AuthRequest { } // Exec executes the query. -func (arc *AuthRequestCreate) Exec(ctx context.Context) error { - _, err := arc.Save(ctx) +func (_c *AuthRequestCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (arc *AuthRequestCreate) ExecX(ctx context.Context) { - if err := arc.Exec(ctx); err != nil { +func (_c *AuthRequestCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } // defaults sets the default values of the builder before save. -func (arc *AuthRequestCreate) defaults() { - if _, ok := arc.mutation.ClaimsPreferredUsername(); !ok { +func (_c *AuthRequestCreate) defaults() { + if _, ok := _c.mutation.ClaimsPreferredUsername(); !ok { v := authrequest.DefaultClaimsPreferredUsername - arc.mutation.SetClaimsPreferredUsername(v) + _c.mutation.SetClaimsPreferredUsername(v) } - if _, ok := arc.mutation.CodeChallenge(); !ok { + if _, ok := _c.mutation.CodeChallenge(); !ok { v := authrequest.DefaultCodeChallenge - arc.mutation.SetCodeChallenge(v) + _c.mutation.SetCodeChallenge(v) } - if _, ok := arc.mutation.CodeChallengeMethod(); !ok { + if _, ok := _c.mutation.CodeChallengeMethod(); !ok { v := authrequest.DefaultCodeChallengeMethod - arc.mutation.SetCodeChallengeMethod(v) + _c.mutation.SetCodeChallengeMethod(v) } } // check runs all checks and user-defined validators on the builder. -func (arc *AuthRequestCreate) check() error { - if _, ok := arc.mutation.ClientID(); !ok { +func (_c *AuthRequestCreate) check() error { + if _, ok := _c.mutation.ClientID(); !ok { return &ValidationError{Name: "client_id", err: errors.New(`db: missing required field "AuthRequest.client_id"`)} } - if _, ok := arc.mutation.RedirectURI(); !ok { + if _, ok := _c.mutation.RedirectURI(); !ok { return &ValidationError{Name: "redirect_uri", err: errors.New(`db: missing required field "AuthRequest.redirect_uri"`)} } - if _, ok := arc.mutation.Nonce(); !ok { + if _, ok := _c.mutation.Nonce(); !ok { return &ValidationError{Name: "nonce", err: errors.New(`db: missing required field "AuthRequest.nonce"`)} } - if _, ok := arc.mutation.State(); !ok { + if _, ok := _c.mutation.State(); !ok { return &ValidationError{Name: "state", err: errors.New(`db: missing required field "AuthRequest.state"`)} } - if _, ok := arc.mutation.ForceApprovalPrompt(); !ok { + if _, ok := _c.mutation.ForceApprovalPrompt(); !ok { return &ValidationError{Name: "force_approval_prompt", err: errors.New(`db: missing required field "AuthRequest.force_approval_prompt"`)} } - if _, ok := arc.mutation.LoggedIn(); !ok { + if _, ok := _c.mutation.LoggedIn(); !ok { return &ValidationError{Name: "logged_in", err: errors.New(`db: missing required field "AuthRequest.logged_in"`)} } - if _, ok := arc.mutation.ClaimsUserID(); !ok { + if _, ok := _c.mutation.ClaimsUserID(); !ok { return &ValidationError{Name: "claims_user_id", err: errors.New(`db: missing required field "AuthRequest.claims_user_id"`)} } - if _, ok := arc.mutation.ClaimsUsername(); !ok { + if _, ok := _c.mutation.ClaimsUsername(); !ok { return &ValidationError{Name: "claims_username", err: errors.New(`db: missing required field "AuthRequest.claims_username"`)} } - if _, ok := arc.mutation.ClaimsEmail(); !ok { + if _, ok := _c.mutation.ClaimsEmail(); !ok { return &ValidationError{Name: "claims_email", err: errors.New(`db: missing required field "AuthRequest.claims_email"`)} } - if _, ok := arc.mutation.ClaimsEmailVerified(); !ok { + if _, ok := _c.mutation.ClaimsEmailVerified(); !ok { return &ValidationError{Name: "claims_email_verified", err: errors.New(`db: missing required field "AuthRequest.claims_email_verified"`)} } - if _, ok := arc.mutation.ClaimsPreferredUsername(); !ok { + if _, ok := _c.mutation.ClaimsPreferredUsername(); !ok { return &ValidationError{Name: "claims_preferred_username", err: errors.New(`db: missing required field "AuthRequest.claims_preferred_username"`)} } - if _, ok := arc.mutation.ConnectorID(); !ok { + if _, ok := _c.mutation.ConnectorID(); !ok { return &ValidationError{Name: "connector_id", err: errors.New(`db: missing required field "AuthRequest.connector_id"`)} } - if _, ok := arc.mutation.Expiry(); !ok { + if _, ok := _c.mutation.Expiry(); !ok { return &ValidationError{Name: "expiry", err: errors.New(`db: missing required field "AuthRequest.expiry"`)} } - if _, ok := arc.mutation.CodeChallenge(); !ok { + if _, ok := _c.mutation.CodeChallenge(); !ok { return &ValidationError{Name: "code_challenge", err: errors.New(`db: missing required field "AuthRequest.code_challenge"`)} } - if _, ok := arc.mutation.CodeChallengeMethod(); !ok { + if _, ok := _c.mutation.CodeChallengeMethod(); !ok { return &ValidationError{Name: "code_challenge_method", err: errors.New(`db: missing required field "AuthRequest.code_challenge_method"`)} } - if v, ok := arc.mutation.ID(); ok { + if _, ok := _c.mutation.HmacKey(); !ok { + return &ValidationError{Name: "hmac_key", err: errors.New(`db: missing required field "AuthRequest.hmac_key"`)} + } + if v, ok := _c.mutation.ID(); ok { if err := authrequest.IDValidator(v); err != nil { return &ValidationError{Name: "id", err: fmt.Errorf(`db: validator failed for field "AuthRequest.id": %w`, err)} } @@ -310,9 +277,12 @@ func (arc *AuthRequestCreate) check() error { return nil } -func (arc *AuthRequestCreate) sqlSave(ctx context.Context) (*AuthRequest, error) { - _node, _spec := arc.createSpec() - if err := sqlgraph.CreateNode(ctx, arc.driver, _spec); err != nil { +func (_c *AuthRequestCreate) sqlSave(ctx context.Context) (*AuthRequest, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -325,193 +295,121 @@ func (arc *AuthRequestCreate) sqlSave(ctx context.Context) (*AuthRequest, error) return nil, fmt.Errorf("unexpected AuthRequest.ID type: %T", _spec.ID.Value) } } + _c.mutation.id = &_node.ID + _c.mutation.done = true return _node, nil } -func (arc *AuthRequestCreate) createSpec() (*AuthRequest, *sqlgraph.CreateSpec) { +func (_c *AuthRequestCreate) createSpec() (*AuthRequest, *sqlgraph.CreateSpec) { var ( - _node = &AuthRequest{config: arc.config} - _spec = &sqlgraph.CreateSpec{ - Table: authrequest.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: authrequest.FieldID, - }, - } + _node = &AuthRequest{config: _c.config} + _spec = sqlgraph.NewCreateSpec(authrequest.Table, sqlgraph.NewFieldSpec(authrequest.FieldID, field.TypeString)) ) - if id, ok := arc.mutation.ID(); ok { + if id, ok := _c.mutation.ID(); ok { _node.ID = id _spec.ID.Value = id } - if value, ok := arc.mutation.ClientID(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldClientID, - }) + if value, ok := _c.mutation.ClientID(); ok { + _spec.SetField(authrequest.FieldClientID, field.TypeString, value) _node.ClientID = value } - if value, ok := arc.mutation.Scopes(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: authrequest.FieldScopes, - }) + if value, ok := _c.mutation.Scopes(); ok { + _spec.SetField(authrequest.FieldScopes, field.TypeJSON, value) _node.Scopes = value } - if value, ok := arc.mutation.ResponseTypes(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: authrequest.FieldResponseTypes, - }) + if value, ok := _c.mutation.ResponseTypes(); ok { + _spec.SetField(authrequest.FieldResponseTypes, field.TypeJSON, value) _node.ResponseTypes = value } - if value, ok := arc.mutation.RedirectURI(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldRedirectURI, - }) + if value, ok := _c.mutation.RedirectURI(); ok { + _spec.SetField(authrequest.FieldRedirectURI, field.TypeString, value) _node.RedirectURI = value } - if value, ok := arc.mutation.Nonce(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldNonce, - }) + if value, ok := _c.mutation.Nonce(); ok { + _spec.SetField(authrequest.FieldNonce, field.TypeString, value) _node.Nonce = value } - if value, ok := arc.mutation.State(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldState, - }) + if value, ok := _c.mutation.State(); ok { + _spec.SetField(authrequest.FieldState, field.TypeString, value) _node.State = value } - if value, ok := arc.mutation.ForceApprovalPrompt(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeBool, - Value: value, - Column: authrequest.FieldForceApprovalPrompt, - }) + if value, ok := _c.mutation.ForceApprovalPrompt(); ok { + _spec.SetField(authrequest.FieldForceApprovalPrompt, field.TypeBool, value) _node.ForceApprovalPrompt = value } - if value, ok := arc.mutation.LoggedIn(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeBool, - Value: value, - Column: authrequest.FieldLoggedIn, - }) + if value, ok := _c.mutation.LoggedIn(); ok { + _spec.SetField(authrequest.FieldLoggedIn, field.TypeBool, value) _node.LoggedIn = value } - if value, ok := arc.mutation.ClaimsUserID(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldClaimsUserID, - }) + if value, ok := _c.mutation.ClaimsUserID(); ok { + _spec.SetField(authrequest.FieldClaimsUserID, field.TypeString, value) _node.ClaimsUserID = value } - if value, ok := arc.mutation.ClaimsUsername(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldClaimsUsername, - }) + if value, ok := _c.mutation.ClaimsUsername(); ok { + _spec.SetField(authrequest.FieldClaimsUsername, field.TypeString, value) _node.ClaimsUsername = value } - if value, ok := arc.mutation.ClaimsEmail(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldClaimsEmail, - }) + if value, ok := _c.mutation.ClaimsEmail(); ok { + _spec.SetField(authrequest.FieldClaimsEmail, field.TypeString, value) _node.ClaimsEmail = value } - if value, ok := arc.mutation.ClaimsEmailVerified(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeBool, - Value: value, - Column: authrequest.FieldClaimsEmailVerified, - }) + if value, ok := _c.mutation.ClaimsEmailVerified(); ok { + _spec.SetField(authrequest.FieldClaimsEmailVerified, field.TypeBool, value) _node.ClaimsEmailVerified = value } - if value, ok := arc.mutation.ClaimsGroups(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: authrequest.FieldClaimsGroups, - }) + if value, ok := _c.mutation.ClaimsGroups(); ok { + _spec.SetField(authrequest.FieldClaimsGroups, field.TypeJSON, value) _node.ClaimsGroups = value } - if value, ok := arc.mutation.ClaimsPreferredUsername(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldClaimsPreferredUsername, - }) + if value, ok := _c.mutation.ClaimsPreferredUsername(); ok { + _spec.SetField(authrequest.FieldClaimsPreferredUsername, field.TypeString, value) _node.ClaimsPreferredUsername = value } - if value, ok := arc.mutation.ConnectorID(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldConnectorID, - }) + if value, ok := _c.mutation.ConnectorID(); ok { + _spec.SetField(authrequest.FieldConnectorID, field.TypeString, value) _node.ConnectorID = value } - if value, ok := arc.mutation.ConnectorData(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: authrequest.FieldConnectorData, - }) + if value, ok := _c.mutation.ConnectorData(); ok { + _spec.SetField(authrequest.FieldConnectorData, field.TypeBytes, value) _node.ConnectorData = &value } - if value, ok := arc.mutation.Expiry(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: authrequest.FieldExpiry, - }) + if value, ok := _c.mutation.Expiry(); ok { + _spec.SetField(authrequest.FieldExpiry, field.TypeTime, value) _node.Expiry = value } - if value, ok := arc.mutation.CodeChallenge(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldCodeChallenge, - }) + if value, ok := _c.mutation.CodeChallenge(); ok { + _spec.SetField(authrequest.FieldCodeChallenge, field.TypeString, value) _node.CodeChallenge = value } - if value, ok := arc.mutation.CodeChallengeMethod(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldCodeChallengeMethod, - }) + if value, ok := _c.mutation.CodeChallengeMethod(); ok { + _spec.SetField(authrequest.FieldCodeChallengeMethod, field.TypeString, value) _node.CodeChallengeMethod = value } + if value, ok := _c.mutation.HmacKey(); ok { + _spec.SetField(authrequest.FieldHmacKey, field.TypeBytes, value) + _node.HmacKey = value + } return _node, _spec } // AuthRequestCreateBulk is the builder for creating many AuthRequest entities in bulk. type AuthRequestCreateBulk struct { config + err error builders []*AuthRequestCreate } // Save creates the AuthRequest entities in the database. -func (arcb *AuthRequestCreateBulk) Save(ctx context.Context) ([]*AuthRequest, error) { - specs := make([]*sqlgraph.CreateSpec, len(arcb.builders)) - nodes := make([]*AuthRequest, len(arcb.builders)) - mutators := make([]Mutator, len(arcb.builders)) - for i := range arcb.builders { +func (_c *AuthRequestCreateBulk) Save(ctx context.Context) ([]*AuthRequest, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*AuthRequest, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { func(i int, root context.Context) { - builder := arcb.builders[i] + builder := _c.builders[i] builder.defaults() var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { mutation, ok := m.(*AuthRequestMutation) @@ -522,14 +420,14 @@ func (arcb *AuthRequestCreateBulk) Save(ctx context.Context) ([]*AuthRequest, er return nil, err } builder.mutation = mutation - nodes[i], specs[i] = builder.createSpec() var err error + nodes[i], specs[i] = builder.createSpec() if i < len(mutators)-1 { - _, err = mutators[i+1].Mutate(root, arcb.builders[i+1].mutation) + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} // Invoke the actual operation on the latest mutation in the chain. - if err = sqlgraph.BatchCreate(ctx, arcb.driver, spec); err != nil { + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -549,7 +447,7 @@ func (arcb *AuthRequestCreateBulk) Save(ctx context.Context) ([]*AuthRequest, er }(i, ctx) } if len(mutators) > 0 { - if _, err := mutators[0].Mutate(ctx, arcb.builders[0].mutation); err != nil { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { return nil, err } } @@ -557,8 +455,8 @@ func (arcb *AuthRequestCreateBulk) Save(ctx context.Context) ([]*AuthRequest, er } // SaveX is like Save, but panics if an error occurs. -func (arcb *AuthRequestCreateBulk) SaveX(ctx context.Context) []*AuthRequest { - v, err := arcb.Save(ctx) +func (_c *AuthRequestCreateBulk) SaveX(ctx context.Context) []*AuthRequest { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -566,14 +464,14 @@ func (arcb *AuthRequestCreateBulk) SaveX(ctx context.Context) []*AuthRequest { } // Exec executes the query. -func (arcb *AuthRequestCreateBulk) Exec(ctx context.Context) error { - _, err := arcb.Save(ctx) +func (_c *AuthRequestCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (arcb *AuthRequestCreateBulk) ExecX(ctx context.Context) { - if err := arcb.Exec(ctx); err != nil { +func (_c *AuthRequestCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } diff --git a/storage/ent/db/authrequest_delete.go b/storage/ent/db/authrequest_delete.go index 495f467609..b9e2cd59a3 100644 --- a/storage/ent/db/authrequest_delete.go +++ b/storage/ent/db/authrequest_delete.go @@ -4,7 +4,6 @@ package db import ( "context" - "fmt" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" @@ -21,84 +20,56 @@ type AuthRequestDelete struct { } // Where appends a list predicates to the AuthRequestDelete builder. -func (ard *AuthRequestDelete) Where(ps ...predicate.AuthRequest) *AuthRequestDelete { - ard.mutation.Where(ps...) - return ard +func (_d *AuthRequestDelete) Where(ps ...predicate.AuthRequest) *AuthRequestDelete { + _d.mutation.Where(ps...) + return _d } // Exec executes the deletion query and returns how many vertices were deleted. -func (ard *AuthRequestDelete) Exec(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(ard.hooks) == 0 { - affected, err = ard.sqlExec(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*AuthRequestMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - ard.mutation = mutation - affected, err = ard.sqlExec(ctx) - mutation.done = true - return affected, err - }) - for i := len(ard.hooks) - 1; i >= 0; i-- { - if ard.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = ard.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, ard.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_d *AuthRequestDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) } // ExecX is like Exec, but panics if an error occurs. -func (ard *AuthRequestDelete) ExecX(ctx context.Context) int { - n, err := ard.Exec(ctx) +func (_d *AuthRequestDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) if err != nil { panic(err) } return n } -func (ard *AuthRequestDelete) sqlExec(ctx context.Context) (int, error) { - _spec := &sqlgraph.DeleteSpec{ - Node: &sqlgraph.NodeSpec{ - Table: authrequest.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: authrequest.FieldID, - }, - }, - } - if ps := ard.mutation.predicates; len(ps) > 0 { +func (_d *AuthRequestDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(authrequest.Table, sqlgraph.NewFieldSpec(authrequest.FieldID, field.TypeString)) + if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - affected, err := sqlgraph.DeleteNodes(ctx, ard.driver, _spec) + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) if err != nil && sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } + _d.mutation.done = true return affected, err } // AuthRequestDeleteOne is the builder for deleting a single AuthRequest entity. type AuthRequestDeleteOne struct { - ard *AuthRequestDelete + _d *AuthRequestDelete +} + +// Where appends a list predicates to the AuthRequestDelete builder. +func (_d *AuthRequestDeleteOne) Where(ps ...predicate.AuthRequest) *AuthRequestDeleteOne { + _d._d.mutation.Where(ps...) + return _d } // Exec executes the deletion query. -func (ardo *AuthRequestDeleteOne) Exec(ctx context.Context) error { - n, err := ardo.ard.Exec(ctx) +func (_d *AuthRequestDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) switch { case err != nil: return err @@ -110,6 +81,8 @@ func (ardo *AuthRequestDeleteOne) Exec(ctx context.Context) error { } // ExecX is like Exec, but panics if an error occurs. -func (ardo *AuthRequestDeleteOne) ExecX(ctx context.Context) { - ardo.ard.ExecX(ctx) +func (_d *AuthRequestDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } } diff --git a/storage/ent/db/authrequest_query.go b/storage/ent/db/authrequest_query.go index 577da17b06..22fd3fb1d2 100644 --- a/storage/ent/db/authrequest_query.go +++ b/storage/ent/db/authrequest_query.go @@ -7,6 +7,7 @@ import ( "fmt" "math" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" @@ -17,11 +18,9 @@ import ( // AuthRequestQuery is the builder for querying AuthRequest entities. type AuthRequestQuery struct { config - limit *int - offset *int - unique *bool - order []OrderFunc - fields []string + ctx *QueryContext + order []authrequest.OrderOption + inters []Interceptor predicates []predicate.AuthRequest // intermediate query (i.e. traversal path). sql *sql.Selector @@ -29,40 +28,40 @@ type AuthRequestQuery struct { } // Where adds a new predicate for the AuthRequestQuery builder. -func (arq *AuthRequestQuery) Where(ps ...predicate.AuthRequest) *AuthRequestQuery { - arq.predicates = append(arq.predicates, ps...) - return arq +func (_q *AuthRequestQuery) Where(ps ...predicate.AuthRequest) *AuthRequestQuery { + _q.predicates = append(_q.predicates, ps...) + return _q } -// Limit adds a limit step to the query. -func (arq *AuthRequestQuery) Limit(limit int) *AuthRequestQuery { - arq.limit = &limit - return arq +// Limit the number of records to be returned by this query. +func (_q *AuthRequestQuery) Limit(limit int) *AuthRequestQuery { + _q.ctx.Limit = &limit + return _q } -// Offset adds an offset step to the query. -func (arq *AuthRequestQuery) Offset(offset int) *AuthRequestQuery { - arq.offset = &offset - return arq +// Offset to start from. +func (_q *AuthRequestQuery) Offset(offset int) *AuthRequestQuery { + _q.ctx.Offset = &offset + return _q } // Unique configures the query builder to filter duplicate records on query. // By default, unique is set to true, and can be disabled using this method. -func (arq *AuthRequestQuery) Unique(unique bool) *AuthRequestQuery { - arq.unique = &unique - return arq +func (_q *AuthRequestQuery) Unique(unique bool) *AuthRequestQuery { + _q.ctx.Unique = &unique + return _q } -// Order adds an order step to the query. -func (arq *AuthRequestQuery) Order(o ...OrderFunc) *AuthRequestQuery { - arq.order = append(arq.order, o...) - return arq +// Order specifies how the records should be ordered. +func (_q *AuthRequestQuery) Order(o ...authrequest.OrderOption) *AuthRequestQuery { + _q.order = append(_q.order, o...) + return _q } // First returns the first AuthRequest entity from the query. // Returns a *NotFoundError when no AuthRequest was found. -func (arq *AuthRequestQuery) First(ctx context.Context) (*AuthRequest, error) { - nodes, err := arq.Limit(1).All(ctx) +func (_q *AuthRequestQuery) First(ctx context.Context) (*AuthRequest, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) if err != nil { return nil, err } @@ -73,8 +72,8 @@ func (arq *AuthRequestQuery) First(ctx context.Context) (*AuthRequest, error) { } // FirstX is like First, but panics if an error occurs. -func (arq *AuthRequestQuery) FirstX(ctx context.Context) *AuthRequest { - node, err := arq.First(ctx) +func (_q *AuthRequestQuery) FirstX(ctx context.Context) *AuthRequest { + node, err := _q.First(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -83,9 +82,9 @@ func (arq *AuthRequestQuery) FirstX(ctx context.Context) *AuthRequest { // FirstID returns the first AuthRequest ID from the query. // Returns a *NotFoundError when no AuthRequest ID was found. -func (arq *AuthRequestQuery) FirstID(ctx context.Context) (id string, err error) { +func (_q *AuthRequestQuery) FirstID(ctx context.Context) (id string, err error) { var ids []string - if ids, err = arq.Limit(1).IDs(ctx); err != nil { + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { return } if len(ids) == 0 { @@ -96,8 +95,8 @@ func (arq *AuthRequestQuery) FirstID(ctx context.Context) (id string, err error) } // FirstIDX is like FirstID, but panics if an error occurs. -func (arq *AuthRequestQuery) FirstIDX(ctx context.Context) string { - id, err := arq.FirstID(ctx) +func (_q *AuthRequestQuery) FirstIDX(ctx context.Context) string { + id, err := _q.FirstID(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -107,8 +106,8 @@ func (arq *AuthRequestQuery) FirstIDX(ctx context.Context) string { // Only returns a single AuthRequest entity found by the query, ensuring it only returns one. // Returns a *NotSingularError when more than one AuthRequest entity is found. // Returns a *NotFoundError when no AuthRequest entities are found. -func (arq *AuthRequestQuery) Only(ctx context.Context) (*AuthRequest, error) { - nodes, err := arq.Limit(2).All(ctx) +func (_q *AuthRequestQuery) Only(ctx context.Context) (*AuthRequest, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) if err != nil { return nil, err } @@ -123,8 +122,8 @@ func (arq *AuthRequestQuery) Only(ctx context.Context) (*AuthRequest, error) { } // OnlyX is like Only, but panics if an error occurs. -func (arq *AuthRequestQuery) OnlyX(ctx context.Context) *AuthRequest { - node, err := arq.Only(ctx) +func (_q *AuthRequestQuery) OnlyX(ctx context.Context) *AuthRequest { + node, err := _q.Only(ctx) if err != nil { panic(err) } @@ -134,9 +133,9 @@ func (arq *AuthRequestQuery) OnlyX(ctx context.Context) *AuthRequest { // OnlyID is like Only, but returns the only AuthRequest ID in the query. // Returns a *NotSingularError when more than one AuthRequest ID is found. // Returns a *NotFoundError when no entities are found. -func (arq *AuthRequestQuery) OnlyID(ctx context.Context) (id string, err error) { +func (_q *AuthRequestQuery) OnlyID(ctx context.Context) (id string, err error) { var ids []string - if ids, err = arq.Limit(2).IDs(ctx); err != nil { + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { return } switch len(ids) { @@ -151,8 +150,8 @@ func (arq *AuthRequestQuery) OnlyID(ctx context.Context) (id string, err error) } // OnlyIDX is like OnlyID, but panics if an error occurs. -func (arq *AuthRequestQuery) OnlyIDX(ctx context.Context) string { - id, err := arq.OnlyID(ctx) +func (_q *AuthRequestQuery) OnlyIDX(ctx context.Context) string { + id, err := _q.OnlyID(ctx) if err != nil { panic(err) } @@ -160,16 +159,18 @@ func (arq *AuthRequestQuery) OnlyIDX(ctx context.Context) string { } // All executes the query and returns a list of AuthRequests. -func (arq *AuthRequestQuery) All(ctx context.Context) ([]*AuthRequest, error) { - if err := arq.prepareQuery(ctx); err != nil { +func (_q *AuthRequestQuery) All(ctx context.Context) ([]*AuthRequest, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { return nil, err } - return arq.sqlAll(ctx) + qr := querierAll[[]*AuthRequest, *AuthRequestQuery]() + return withInterceptors[[]*AuthRequest](ctx, _q, qr, _q.inters) } // AllX is like All, but panics if an error occurs. -func (arq *AuthRequestQuery) AllX(ctx context.Context) []*AuthRequest { - nodes, err := arq.All(ctx) +func (_q *AuthRequestQuery) AllX(ctx context.Context) []*AuthRequest { + nodes, err := _q.All(ctx) if err != nil { panic(err) } @@ -177,17 +178,20 @@ func (arq *AuthRequestQuery) AllX(ctx context.Context) []*AuthRequest { } // IDs executes the query and returns a list of AuthRequest IDs. -func (arq *AuthRequestQuery) IDs(ctx context.Context) ([]string, error) { - var ids []string - if err := arq.Select(authrequest.FieldID).Scan(ctx, &ids); err != nil { +func (_q *AuthRequestQuery) IDs(ctx context.Context) (ids []string, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(authrequest.FieldID).Scan(ctx, &ids); err != nil { return nil, err } return ids, nil } // IDsX is like IDs, but panics if an error occurs. -func (arq *AuthRequestQuery) IDsX(ctx context.Context) []string { - ids, err := arq.IDs(ctx) +func (_q *AuthRequestQuery) IDsX(ctx context.Context) []string { + ids, err := _q.IDs(ctx) if err != nil { panic(err) } @@ -195,16 +199,17 @@ func (arq *AuthRequestQuery) IDsX(ctx context.Context) []string { } // Count returns the count of the given query. -func (arq *AuthRequestQuery) Count(ctx context.Context) (int, error) { - if err := arq.prepareQuery(ctx); err != nil { +func (_q *AuthRequestQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { return 0, err } - return arq.sqlCount(ctx) + return withInterceptors[int](ctx, _q, querierCount[*AuthRequestQuery](), _q.inters) } // CountX is like Count, but panics if an error occurs. -func (arq *AuthRequestQuery) CountX(ctx context.Context) int { - count, err := arq.Count(ctx) +func (_q *AuthRequestQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) if err != nil { panic(err) } @@ -212,16 +217,21 @@ func (arq *AuthRequestQuery) CountX(ctx context.Context) int { } // Exist returns true if the query has elements in the graph. -func (arq *AuthRequestQuery) Exist(ctx context.Context) (bool, error) { - if err := arq.prepareQuery(ctx); err != nil { - return false, err +func (_q *AuthRequestQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("db: check existence: %w", err) + default: + return true, nil } - return arq.sqlExist(ctx) } // ExistX is like Exist, but panics if an error occurs. -func (arq *AuthRequestQuery) ExistX(ctx context.Context) bool { - exist, err := arq.Exist(ctx) +func (_q *AuthRequestQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) if err != nil { panic(err) } @@ -230,20 +240,19 @@ func (arq *AuthRequestQuery) ExistX(ctx context.Context) bool { // Clone returns a duplicate of the AuthRequestQuery builder, including all associated steps. It can be // used to prepare common query builders and use them differently after the clone is made. -func (arq *AuthRequestQuery) Clone() *AuthRequestQuery { - if arq == nil { +func (_q *AuthRequestQuery) Clone() *AuthRequestQuery { + if _q == nil { return nil } return &AuthRequestQuery{ - config: arq.config, - limit: arq.limit, - offset: arq.offset, - order: append([]OrderFunc{}, arq.order...), - predicates: append([]predicate.AuthRequest{}, arq.predicates...), + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]authrequest.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.AuthRequest{}, _q.predicates...), // clone intermediate query. - sql: arq.sql.Clone(), - path: arq.path, - unique: arq.unique, + sql: _q.sql.Clone(), + path: _q.path, } } @@ -261,18 +270,12 @@ func (arq *AuthRequestQuery) Clone() *AuthRequestQuery { // GroupBy(authrequest.FieldClientID). // Aggregate(db.Count()). // Scan(ctx, &v) -// -func (arq *AuthRequestQuery) GroupBy(field string, fields ...string) *AuthRequestGroupBy { - grbuild := &AuthRequestGroupBy{config: arq.config} - grbuild.fields = append([]string{field}, fields...) - grbuild.path = func(ctx context.Context) (prev *sql.Selector, err error) { - if err := arq.prepareQuery(ctx); err != nil { - return nil, err - } - return arq.sqlQuery(ctx), nil - } +func (_q *AuthRequestQuery) GroupBy(field string, fields ...string) *AuthRequestGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &AuthRequestGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields grbuild.label = authrequest.Label - grbuild.flds, grbuild.scan = &grbuild.fields, grbuild.Scan + grbuild.scan = grbuild.Scan return grbuild } @@ -288,48 +291,62 @@ func (arq *AuthRequestQuery) GroupBy(field string, fields ...string) *AuthReques // client.AuthRequest.Query(). // Select(authrequest.FieldClientID). // Scan(ctx, &v) -// -func (arq *AuthRequestQuery) Select(fields ...string) *AuthRequestSelect { - arq.fields = append(arq.fields, fields...) - selbuild := &AuthRequestSelect{AuthRequestQuery: arq} - selbuild.label = authrequest.Label - selbuild.flds, selbuild.scan = &arq.fields, selbuild.Scan - return selbuild +func (_q *AuthRequestQuery) Select(fields ...string) *AuthRequestSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &AuthRequestSelect{AuthRequestQuery: _q} + sbuild.label = authrequest.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a AuthRequestSelect configured with the given aggregations. +func (_q *AuthRequestQuery) Aggregate(fns ...AggregateFunc) *AuthRequestSelect { + return _q.Select().Aggregate(fns...) } -func (arq *AuthRequestQuery) prepareQuery(ctx context.Context) error { - for _, f := range arq.fields { +func (_q *AuthRequestQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("db: uninitialized interceptor (forgotten import db/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { if !authrequest.ValidColumn(f) { return &ValidationError{Name: f, err: fmt.Errorf("db: invalid field %q for query", f)} } } - if arq.path != nil { - prev, err := arq.path(ctx) + if _q.path != nil { + prev, err := _q.path(ctx) if err != nil { return err } - arq.sql = prev + _q.sql = prev } return nil } -func (arq *AuthRequestQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*AuthRequest, error) { +func (_q *AuthRequestQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*AuthRequest, error) { var ( nodes = []*AuthRequest{} - _spec = arq.querySpec() + _spec = _q.querySpec() ) - _spec.ScanValues = func(columns []string) ([]interface{}, error) { + _spec.ScanValues = func(columns []string) ([]any, error) { return (*AuthRequest).scanValues(nil, columns) } - _spec.Assign = func(columns []string, values []interface{}) error { - node := &AuthRequest{config: arq.config} + _spec.Assign = func(columns []string, values []any) error { + node := &AuthRequest{config: _q.config} nodes = append(nodes, node) return node.assignValues(columns, values) } for i := range hooks { hooks[i](ctx, _spec) } - if err := sqlgraph.QueryNodes(ctx, arq.driver, _spec); err != nil { + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { return nil, err } if len(nodes) == 0 { @@ -338,40 +355,24 @@ func (arq *AuthRequestQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([] return nodes, nil } -func (arq *AuthRequestQuery) sqlCount(ctx context.Context) (int, error) { - _spec := arq.querySpec() - _spec.Node.Columns = arq.fields - if len(arq.fields) > 0 { - _spec.Unique = arq.unique != nil && *arq.unique - } - return sqlgraph.CountNodes(ctx, arq.driver, _spec) -} - -func (arq *AuthRequestQuery) sqlExist(ctx context.Context) (bool, error) { - n, err := arq.sqlCount(ctx) - if err != nil { - return false, fmt.Errorf("db: check existence: %w", err) +func (_q *AuthRequestQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique } - return n > 0, nil + return sqlgraph.CountNodes(ctx, _q.driver, _spec) } -func (arq *AuthRequestQuery) querySpec() *sqlgraph.QuerySpec { - _spec := &sqlgraph.QuerySpec{ - Node: &sqlgraph.NodeSpec{ - Table: authrequest.Table, - Columns: authrequest.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: authrequest.FieldID, - }, - }, - From: arq.sql, - Unique: true, - } - if unique := arq.unique; unique != nil { +func (_q *AuthRequestQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(authrequest.Table, authrequest.Columns, sqlgraph.NewFieldSpec(authrequest.FieldID, field.TypeString)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true } - if fields := arq.fields; len(fields) > 0 { + if fields := _q.ctx.Fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, authrequest.FieldID) for i := range fields { @@ -380,20 +381,20 @@ func (arq *AuthRequestQuery) querySpec() *sqlgraph.QuerySpec { } } } - if ps := arq.predicates; len(ps) > 0 { + if ps := _q.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if limit := arq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { _spec.Limit = *limit } - if offset := arq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { _spec.Offset = *offset } - if ps := arq.order; len(ps) > 0 { + if ps := _q.order; len(ps) > 0 { _spec.Order = func(selector *sql.Selector) { for i := range ps { ps[i](selector) @@ -403,33 +404,33 @@ func (arq *AuthRequestQuery) querySpec() *sqlgraph.QuerySpec { return _spec } -func (arq *AuthRequestQuery) sqlQuery(ctx context.Context) *sql.Selector { - builder := sql.Dialect(arq.driver.Dialect()) +func (_q *AuthRequestQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) t1 := builder.Table(authrequest.Table) - columns := arq.fields + columns := _q.ctx.Fields if len(columns) == 0 { columns = authrequest.Columns } selector := builder.Select(t1.Columns(columns...)...).From(t1) - if arq.sql != nil { - selector = arq.sql + if _q.sql != nil { + selector = _q.sql selector.Select(selector.Columns(columns...)...) } - if arq.unique != nil && *arq.unique { + if _q.ctx.Unique != nil && *_q.ctx.Unique { selector.Distinct() } - for _, p := range arq.predicates { + for _, p := range _q.predicates { p(selector) } - for _, p := range arq.order { + for _, p := range _q.order { p(selector) } - if offset := arq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { // limit is mandatory for offset clause. We start // with default value, and override it below if needed. selector.Offset(*offset).Limit(math.MaxInt32) } - if limit := arq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { selector.Limit(*limit) } return selector @@ -437,90 +438,88 @@ func (arq *AuthRequestQuery) sqlQuery(ctx context.Context) *sql.Selector { // AuthRequestGroupBy is the group-by builder for AuthRequest entities. type AuthRequestGroupBy struct { - config selector - fields []string - fns []AggregateFunc - // intermediate query (i.e. traversal path). - sql *sql.Selector - path func(context.Context) (*sql.Selector, error) + build *AuthRequestQuery } // Aggregate adds the given aggregation functions to the group-by query. -func (argb *AuthRequestGroupBy) Aggregate(fns ...AggregateFunc) *AuthRequestGroupBy { - argb.fns = append(argb.fns, fns...) - return argb +func (_g *AuthRequestGroupBy) Aggregate(fns ...AggregateFunc) *AuthRequestGroupBy { + _g.fns = append(_g.fns, fns...) + return _g } -// Scan applies the group-by query and scans the result into the given value. -func (argb *AuthRequestGroupBy) Scan(ctx context.Context, v interface{}) error { - query, err := argb.path(ctx) - if err != nil { +// Scan applies the selector query and scans the result into the given value. +func (_g *AuthRequestGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { return err } - argb.sql = query - return argb.sqlScan(ctx, v) + return scanWithInterceptors[*AuthRequestQuery, *AuthRequestGroupBy](ctx, _g.build, _g, _g.build.inters, v) } -func (argb *AuthRequestGroupBy) sqlScan(ctx context.Context, v interface{}) error { - for _, f := range argb.fields { - if !authrequest.ValidColumn(f) { - return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)} +func (_g *AuthRequestGroupBy) sqlScan(ctx context.Context, root *AuthRequestQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) } + columns = append(columns, aggregation...) + selector.Select(columns...) } - selector := argb.sqlQuery() + selector.GroupBy(selector.Columns(*_g.flds...)...) if err := selector.Err(); err != nil { return err } rows := &sql.Rows{} query, args := selector.Query() - if err := argb.driver.Query(ctx, query, args, rows); err != nil { + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() return sql.ScanSlice(rows, v) } -func (argb *AuthRequestGroupBy) sqlQuery() *sql.Selector { - selector := argb.sql.Select() - aggregation := make([]string, 0, len(argb.fns)) - for _, fn := range argb.fns { - aggregation = append(aggregation, fn(selector)) - } - // If no columns were selected in a custom aggregation function, the default - // selection is the fields used for "group-by", and the aggregation functions. - if len(selector.SelectedColumns()) == 0 { - columns := make([]string, 0, len(argb.fields)+len(argb.fns)) - for _, f := range argb.fields { - columns = append(columns, selector.C(f)) - } - columns = append(columns, aggregation...) - selector.Select(columns...) - } - return selector.GroupBy(selector.Columns(argb.fields...)...) -} - // AuthRequestSelect is the builder for selecting fields of AuthRequest entities. type AuthRequestSelect struct { *AuthRequestQuery selector - // intermediate query (i.e. traversal path). - sql *sql.Selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *AuthRequestSelect) Aggregate(fns ...AggregateFunc) *AuthRequestSelect { + _s.fns = append(_s.fns, fns...) + return _s } // Scan applies the selector query and scans the result into the given value. -func (ars *AuthRequestSelect) Scan(ctx context.Context, v interface{}) error { - if err := ars.prepareQuery(ctx); err != nil { +func (_s *AuthRequestSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { return err } - ars.sql = ars.AuthRequestQuery.sqlQuery(ctx) - return ars.sqlScan(ctx, v) + return scanWithInterceptors[*AuthRequestQuery, *AuthRequestSelect](ctx, _s.AuthRequestQuery, _s, _s.inters, v) } -func (ars *AuthRequestSelect) sqlScan(ctx context.Context, v interface{}) error { +func (_s *AuthRequestSelect) sqlScan(ctx context.Context, root *AuthRequestQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } rows := &sql.Rows{} - query, args := ars.sql.Query() - if err := ars.driver.Query(ctx, query, args, rows); err != nil { + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() diff --git a/storage/ent/db/authrequest_update.go b/storage/ent/db/authrequest_update.go index 22dbb24b7c..e1fa678a80 100644 --- a/storage/ent/db/authrequest_update.go +++ b/storage/ent/db/authrequest_update.go @@ -10,6 +10,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/dialect/sql/sqljson" "entgo.io/ent/schema/field" "github.com/dexidp/dex/storage/ent/db/authrequest" "github.com/dexidp/dex/storage/ent/db/predicate" @@ -23,213 +24,306 @@ type AuthRequestUpdate struct { } // Where appends a list predicates to the AuthRequestUpdate builder. -func (aru *AuthRequestUpdate) Where(ps ...predicate.AuthRequest) *AuthRequestUpdate { - aru.mutation.Where(ps...) - return aru +func (_u *AuthRequestUpdate) Where(ps ...predicate.AuthRequest) *AuthRequestUpdate { + _u.mutation.Where(ps...) + return _u } // SetClientID sets the "client_id" field. -func (aru *AuthRequestUpdate) SetClientID(s string) *AuthRequestUpdate { - aru.mutation.SetClientID(s) - return aru +func (_u *AuthRequestUpdate) SetClientID(v string) *AuthRequestUpdate { + _u.mutation.SetClientID(v) + return _u +} + +// SetNillableClientID sets the "client_id" field if the given value is not nil. +func (_u *AuthRequestUpdate) SetNillableClientID(v *string) *AuthRequestUpdate { + if v != nil { + _u.SetClientID(*v) + } + return _u } // SetScopes sets the "scopes" field. -func (aru *AuthRequestUpdate) SetScopes(s []string) *AuthRequestUpdate { - aru.mutation.SetScopes(s) - return aru +func (_u *AuthRequestUpdate) SetScopes(v []string) *AuthRequestUpdate { + _u.mutation.SetScopes(v) + return _u +} + +// AppendScopes appends value to the "scopes" field. +func (_u *AuthRequestUpdate) AppendScopes(v []string) *AuthRequestUpdate { + _u.mutation.AppendScopes(v) + return _u } // ClearScopes clears the value of the "scopes" field. -func (aru *AuthRequestUpdate) ClearScopes() *AuthRequestUpdate { - aru.mutation.ClearScopes() - return aru +func (_u *AuthRequestUpdate) ClearScopes() *AuthRequestUpdate { + _u.mutation.ClearScopes() + return _u } // SetResponseTypes sets the "response_types" field. -func (aru *AuthRequestUpdate) SetResponseTypes(s []string) *AuthRequestUpdate { - aru.mutation.SetResponseTypes(s) - return aru +func (_u *AuthRequestUpdate) SetResponseTypes(v []string) *AuthRequestUpdate { + _u.mutation.SetResponseTypes(v) + return _u +} + +// AppendResponseTypes appends value to the "response_types" field. +func (_u *AuthRequestUpdate) AppendResponseTypes(v []string) *AuthRequestUpdate { + _u.mutation.AppendResponseTypes(v) + return _u } // ClearResponseTypes clears the value of the "response_types" field. -func (aru *AuthRequestUpdate) ClearResponseTypes() *AuthRequestUpdate { - aru.mutation.ClearResponseTypes() - return aru +func (_u *AuthRequestUpdate) ClearResponseTypes() *AuthRequestUpdate { + _u.mutation.ClearResponseTypes() + return _u } // SetRedirectURI sets the "redirect_uri" field. -func (aru *AuthRequestUpdate) SetRedirectURI(s string) *AuthRequestUpdate { - aru.mutation.SetRedirectURI(s) - return aru +func (_u *AuthRequestUpdate) SetRedirectURI(v string) *AuthRequestUpdate { + _u.mutation.SetRedirectURI(v) + return _u +} + +// SetNillableRedirectURI sets the "redirect_uri" field if the given value is not nil. +func (_u *AuthRequestUpdate) SetNillableRedirectURI(v *string) *AuthRequestUpdate { + if v != nil { + _u.SetRedirectURI(*v) + } + return _u } // SetNonce sets the "nonce" field. -func (aru *AuthRequestUpdate) SetNonce(s string) *AuthRequestUpdate { - aru.mutation.SetNonce(s) - return aru +func (_u *AuthRequestUpdate) SetNonce(v string) *AuthRequestUpdate { + _u.mutation.SetNonce(v) + return _u +} + +// SetNillableNonce sets the "nonce" field if the given value is not nil. +func (_u *AuthRequestUpdate) SetNillableNonce(v *string) *AuthRequestUpdate { + if v != nil { + _u.SetNonce(*v) + } + return _u } // SetState sets the "state" field. -func (aru *AuthRequestUpdate) SetState(s string) *AuthRequestUpdate { - aru.mutation.SetState(s) - return aru +func (_u *AuthRequestUpdate) SetState(v string) *AuthRequestUpdate { + _u.mutation.SetState(v) + return _u +} + +// SetNillableState sets the "state" field if the given value is not nil. +func (_u *AuthRequestUpdate) SetNillableState(v *string) *AuthRequestUpdate { + if v != nil { + _u.SetState(*v) + } + return _u } // SetForceApprovalPrompt sets the "force_approval_prompt" field. -func (aru *AuthRequestUpdate) SetForceApprovalPrompt(b bool) *AuthRequestUpdate { - aru.mutation.SetForceApprovalPrompt(b) - return aru +func (_u *AuthRequestUpdate) SetForceApprovalPrompt(v bool) *AuthRequestUpdate { + _u.mutation.SetForceApprovalPrompt(v) + return _u +} + +// SetNillableForceApprovalPrompt sets the "force_approval_prompt" field if the given value is not nil. +func (_u *AuthRequestUpdate) SetNillableForceApprovalPrompt(v *bool) *AuthRequestUpdate { + if v != nil { + _u.SetForceApprovalPrompt(*v) + } + return _u } // SetLoggedIn sets the "logged_in" field. -func (aru *AuthRequestUpdate) SetLoggedIn(b bool) *AuthRequestUpdate { - aru.mutation.SetLoggedIn(b) - return aru +func (_u *AuthRequestUpdate) SetLoggedIn(v bool) *AuthRequestUpdate { + _u.mutation.SetLoggedIn(v) + return _u +} + +// SetNillableLoggedIn sets the "logged_in" field if the given value is not nil. +func (_u *AuthRequestUpdate) SetNillableLoggedIn(v *bool) *AuthRequestUpdate { + if v != nil { + _u.SetLoggedIn(*v) + } + return _u } // SetClaimsUserID sets the "claims_user_id" field. -func (aru *AuthRequestUpdate) SetClaimsUserID(s string) *AuthRequestUpdate { - aru.mutation.SetClaimsUserID(s) - return aru +func (_u *AuthRequestUpdate) SetClaimsUserID(v string) *AuthRequestUpdate { + _u.mutation.SetClaimsUserID(v) + return _u +} + +// SetNillableClaimsUserID sets the "claims_user_id" field if the given value is not nil. +func (_u *AuthRequestUpdate) SetNillableClaimsUserID(v *string) *AuthRequestUpdate { + if v != nil { + _u.SetClaimsUserID(*v) + } + return _u } // SetClaimsUsername sets the "claims_username" field. -func (aru *AuthRequestUpdate) SetClaimsUsername(s string) *AuthRequestUpdate { - aru.mutation.SetClaimsUsername(s) - return aru +func (_u *AuthRequestUpdate) SetClaimsUsername(v string) *AuthRequestUpdate { + _u.mutation.SetClaimsUsername(v) + return _u +} + +// SetNillableClaimsUsername sets the "claims_username" field if the given value is not nil. +func (_u *AuthRequestUpdate) SetNillableClaimsUsername(v *string) *AuthRequestUpdate { + if v != nil { + _u.SetClaimsUsername(*v) + } + return _u } // SetClaimsEmail sets the "claims_email" field. -func (aru *AuthRequestUpdate) SetClaimsEmail(s string) *AuthRequestUpdate { - aru.mutation.SetClaimsEmail(s) - return aru +func (_u *AuthRequestUpdate) SetClaimsEmail(v string) *AuthRequestUpdate { + _u.mutation.SetClaimsEmail(v) + return _u +} + +// SetNillableClaimsEmail sets the "claims_email" field if the given value is not nil. +func (_u *AuthRequestUpdate) SetNillableClaimsEmail(v *string) *AuthRequestUpdate { + if v != nil { + _u.SetClaimsEmail(*v) + } + return _u } // SetClaimsEmailVerified sets the "claims_email_verified" field. -func (aru *AuthRequestUpdate) SetClaimsEmailVerified(b bool) *AuthRequestUpdate { - aru.mutation.SetClaimsEmailVerified(b) - return aru +func (_u *AuthRequestUpdate) SetClaimsEmailVerified(v bool) *AuthRequestUpdate { + _u.mutation.SetClaimsEmailVerified(v) + return _u +} + +// SetNillableClaimsEmailVerified sets the "claims_email_verified" field if the given value is not nil. +func (_u *AuthRequestUpdate) SetNillableClaimsEmailVerified(v *bool) *AuthRequestUpdate { + if v != nil { + _u.SetClaimsEmailVerified(*v) + } + return _u } // SetClaimsGroups sets the "claims_groups" field. -func (aru *AuthRequestUpdate) SetClaimsGroups(s []string) *AuthRequestUpdate { - aru.mutation.SetClaimsGroups(s) - return aru +func (_u *AuthRequestUpdate) SetClaimsGroups(v []string) *AuthRequestUpdate { + _u.mutation.SetClaimsGroups(v) + return _u +} + +// AppendClaimsGroups appends value to the "claims_groups" field. +func (_u *AuthRequestUpdate) AppendClaimsGroups(v []string) *AuthRequestUpdate { + _u.mutation.AppendClaimsGroups(v) + return _u } // ClearClaimsGroups clears the value of the "claims_groups" field. -func (aru *AuthRequestUpdate) ClearClaimsGroups() *AuthRequestUpdate { - aru.mutation.ClearClaimsGroups() - return aru +func (_u *AuthRequestUpdate) ClearClaimsGroups() *AuthRequestUpdate { + _u.mutation.ClearClaimsGroups() + return _u } // SetClaimsPreferredUsername sets the "claims_preferred_username" field. -func (aru *AuthRequestUpdate) SetClaimsPreferredUsername(s string) *AuthRequestUpdate { - aru.mutation.SetClaimsPreferredUsername(s) - return aru +func (_u *AuthRequestUpdate) SetClaimsPreferredUsername(v string) *AuthRequestUpdate { + _u.mutation.SetClaimsPreferredUsername(v) + return _u } // SetNillableClaimsPreferredUsername sets the "claims_preferred_username" field if the given value is not nil. -func (aru *AuthRequestUpdate) SetNillableClaimsPreferredUsername(s *string) *AuthRequestUpdate { - if s != nil { - aru.SetClaimsPreferredUsername(*s) +func (_u *AuthRequestUpdate) SetNillableClaimsPreferredUsername(v *string) *AuthRequestUpdate { + if v != nil { + _u.SetClaimsPreferredUsername(*v) } - return aru + return _u } // SetConnectorID sets the "connector_id" field. -func (aru *AuthRequestUpdate) SetConnectorID(s string) *AuthRequestUpdate { - aru.mutation.SetConnectorID(s) - return aru +func (_u *AuthRequestUpdate) SetConnectorID(v string) *AuthRequestUpdate { + _u.mutation.SetConnectorID(v) + return _u +} + +// SetNillableConnectorID sets the "connector_id" field if the given value is not nil. +func (_u *AuthRequestUpdate) SetNillableConnectorID(v *string) *AuthRequestUpdate { + if v != nil { + _u.SetConnectorID(*v) + } + return _u } // SetConnectorData sets the "connector_data" field. -func (aru *AuthRequestUpdate) SetConnectorData(b []byte) *AuthRequestUpdate { - aru.mutation.SetConnectorData(b) - return aru +func (_u *AuthRequestUpdate) SetConnectorData(v []byte) *AuthRequestUpdate { + _u.mutation.SetConnectorData(v) + return _u } // ClearConnectorData clears the value of the "connector_data" field. -func (aru *AuthRequestUpdate) ClearConnectorData() *AuthRequestUpdate { - aru.mutation.ClearConnectorData() - return aru +func (_u *AuthRequestUpdate) ClearConnectorData() *AuthRequestUpdate { + _u.mutation.ClearConnectorData() + return _u } // SetExpiry sets the "expiry" field. -func (aru *AuthRequestUpdate) SetExpiry(t time.Time) *AuthRequestUpdate { - aru.mutation.SetExpiry(t) - return aru +func (_u *AuthRequestUpdate) SetExpiry(v time.Time) *AuthRequestUpdate { + _u.mutation.SetExpiry(v) + return _u +} + +// SetNillableExpiry sets the "expiry" field if the given value is not nil. +func (_u *AuthRequestUpdate) SetNillableExpiry(v *time.Time) *AuthRequestUpdate { + if v != nil { + _u.SetExpiry(*v) + } + return _u } // SetCodeChallenge sets the "code_challenge" field. -func (aru *AuthRequestUpdate) SetCodeChallenge(s string) *AuthRequestUpdate { - aru.mutation.SetCodeChallenge(s) - return aru +func (_u *AuthRequestUpdate) SetCodeChallenge(v string) *AuthRequestUpdate { + _u.mutation.SetCodeChallenge(v) + return _u } // SetNillableCodeChallenge sets the "code_challenge" field if the given value is not nil. -func (aru *AuthRequestUpdate) SetNillableCodeChallenge(s *string) *AuthRequestUpdate { - if s != nil { - aru.SetCodeChallenge(*s) +func (_u *AuthRequestUpdate) SetNillableCodeChallenge(v *string) *AuthRequestUpdate { + if v != nil { + _u.SetCodeChallenge(*v) } - return aru + return _u } // SetCodeChallengeMethod sets the "code_challenge_method" field. -func (aru *AuthRequestUpdate) SetCodeChallengeMethod(s string) *AuthRequestUpdate { - aru.mutation.SetCodeChallengeMethod(s) - return aru +func (_u *AuthRequestUpdate) SetCodeChallengeMethod(v string) *AuthRequestUpdate { + _u.mutation.SetCodeChallengeMethod(v) + return _u } // SetNillableCodeChallengeMethod sets the "code_challenge_method" field if the given value is not nil. -func (aru *AuthRequestUpdate) SetNillableCodeChallengeMethod(s *string) *AuthRequestUpdate { - if s != nil { - aru.SetCodeChallengeMethod(*s) +func (_u *AuthRequestUpdate) SetNillableCodeChallengeMethod(v *string) *AuthRequestUpdate { + if v != nil { + _u.SetCodeChallengeMethod(*v) } - return aru + return _u +} + +// SetHmacKey sets the "hmac_key" field. +func (_u *AuthRequestUpdate) SetHmacKey(v []byte) *AuthRequestUpdate { + _u.mutation.SetHmacKey(v) + return _u } // Mutation returns the AuthRequestMutation object of the builder. -func (aru *AuthRequestUpdate) Mutation() *AuthRequestMutation { - return aru.mutation +func (_u *AuthRequestUpdate) Mutation() *AuthRequestMutation { + return _u.mutation } // Save executes the query and returns the number of nodes affected by the update operation. -func (aru *AuthRequestUpdate) Save(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(aru.hooks) == 0 { - affected, err = aru.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*AuthRequestMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - aru.mutation = mutation - affected, err = aru.sqlSave(ctx) - mutation.done = true - return affected, err - }) - for i := len(aru.hooks) - 1; i >= 0; i-- { - if aru.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = aru.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, aru.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_u *AuthRequestUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (aru *AuthRequestUpdate) SaveX(ctx context.Context) int { - affected, err := aru.Save(ctx) +func (_u *AuthRequestUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) if err != nil { panic(err) } @@ -237,194 +331,115 @@ func (aru *AuthRequestUpdate) SaveX(ctx context.Context) int { } // Exec executes the query. -func (aru *AuthRequestUpdate) Exec(ctx context.Context) error { - _, err := aru.Save(ctx) +func (_u *AuthRequestUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (aru *AuthRequestUpdate) ExecX(ctx context.Context) { - if err := aru.Exec(ctx); err != nil { +func (_u *AuthRequestUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } -func (aru *AuthRequestUpdate) sqlSave(ctx context.Context) (n int, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: authrequest.Table, - Columns: authrequest.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: authrequest.FieldID, - }, - }, - } - if ps := aru.mutation.predicates; len(ps) > 0 { +func (_u *AuthRequestUpdate) sqlSave(ctx context.Context) (_node int, err error) { + _spec := sqlgraph.NewUpdateSpec(authrequest.Table, authrequest.Columns, sqlgraph.NewFieldSpec(authrequest.FieldID, field.TypeString)) + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := aru.mutation.ClientID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldClientID, - }) + if value, ok := _u.mutation.ClientID(); ok { + _spec.SetField(authrequest.FieldClientID, field.TypeString, value) } - if value, ok := aru.mutation.Scopes(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: authrequest.FieldScopes, - }) + if value, ok := _u.mutation.Scopes(); ok { + _spec.SetField(authrequest.FieldScopes, field.TypeJSON, value) } - if aru.mutation.ScopesCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: authrequest.FieldScopes, + if value, ok := _u.mutation.AppendedScopes(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, authrequest.FieldScopes, value) }) } - if value, ok := aru.mutation.ResponseTypes(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: authrequest.FieldResponseTypes, - }) + if _u.mutation.ScopesCleared() { + _spec.ClearField(authrequest.FieldScopes, field.TypeJSON) } - if aru.mutation.ResponseTypesCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: authrequest.FieldResponseTypes, - }) + if value, ok := _u.mutation.ResponseTypes(); ok { + _spec.SetField(authrequest.FieldResponseTypes, field.TypeJSON, value) } - if value, ok := aru.mutation.RedirectURI(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldRedirectURI, + if value, ok := _u.mutation.AppendedResponseTypes(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, authrequest.FieldResponseTypes, value) }) } - if value, ok := aru.mutation.Nonce(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldNonce, - }) + if _u.mutation.ResponseTypesCleared() { + _spec.ClearField(authrequest.FieldResponseTypes, field.TypeJSON) } - if value, ok := aru.mutation.State(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldState, - }) + if value, ok := _u.mutation.RedirectURI(); ok { + _spec.SetField(authrequest.FieldRedirectURI, field.TypeString, value) } - if value, ok := aru.mutation.ForceApprovalPrompt(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBool, - Value: value, - Column: authrequest.FieldForceApprovalPrompt, - }) + if value, ok := _u.mutation.Nonce(); ok { + _spec.SetField(authrequest.FieldNonce, field.TypeString, value) } - if value, ok := aru.mutation.LoggedIn(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBool, - Value: value, - Column: authrequest.FieldLoggedIn, - }) + if value, ok := _u.mutation.State(); ok { + _spec.SetField(authrequest.FieldState, field.TypeString, value) } - if value, ok := aru.mutation.ClaimsUserID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldClaimsUserID, - }) + if value, ok := _u.mutation.ForceApprovalPrompt(); ok { + _spec.SetField(authrequest.FieldForceApprovalPrompt, field.TypeBool, value) } - if value, ok := aru.mutation.ClaimsUsername(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldClaimsUsername, - }) + if value, ok := _u.mutation.LoggedIn(); ok { + _spec.SetField(authrequest.FieldLoggedIn, field.TypeBool, value) } - if value, ok := aru.mutation.ClaimsEmail(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldClaimsEmail, - }) + if value, ok := _u.mutation.ClaimsUserID(); ok { + _spec.SetField(authrequest.FieldClaimsUserID, field.TypeString, value) } - if value, ok := aru.mutation.ClaimsEmailVerified(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBool, - Value: value, - Column: authrequest.FieldClaimsEmailVerified, - }) + if value, ok := _u.mutation.ClaimsUsername(); ok { + _spec.SetField(authrequest.FieldClaimsUsername, field.TypeString, value) } - if value, ok := aru.mutation.ClaimsGroups(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: authrequest.FieldClaimsGroups, - }) + if value, ok := _u.mutation.ClaimsEmail(); ok { + _spec.SetField(authrequest.FieldClaimsEmail, field.TypeString, value) } - if aru.mutation.ClaimsGroupsCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: authrequest.FieldClaimsGroups, - }) + if value, ok := _u.mutation.ClaimsEmailVerified(); ok { + _spec.SetField(authrequest.FieldClaimsEmailVerified, field.TypeBool, value) } - if value, ok := aru.mutation.ClaimsPreferredUsername(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldClaimsPreferredUsername, - }) + if value, ok := _u.mutation.ClaimsGroups(); ok { + _spec.SetField(authrequest.FieldClaimsGroups, field.TypeJSON, value) } - if value, ok := aru.mutation.ConnectorID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldConnectorID, + if value, ok := _u.mutation.AppendedClaimsGroups(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, authrequest.FieldClaimsGroups, value) }) } - if value, ok := aru.mutation.ConnectorData(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: authrequest.FieldConnectorData, - }) + if _u.mutation.ClaimsGroupsCleared() { + _spec.ClearField(authrequest.FieldClaimsGroups, field.TypeJSON) } - if aru.mutation.ConnectorDataCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Column: authrequest.FieldConnectorData, - }) + if value, ok := _u.mutation.ClaimsPreferredUsername(); ok { + _spec.SetField(authrequest.FieldClaimsPreferredUsername, field.TypeString, value) } - if value, ok := aru.mutation.Expiry(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: authrequest.FieldExpiry, - }) + if value, ok := _u.mutation.ConnectorID(); ok { + _spec.SetField(authrequest.FieldConnectorID, field.TypeString, value) } - if value, ok := aru.mutation.CodeChallenge(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldCodeChallenge, - }) + if value, ok := _u.mutation.ConnectorData(); ok { + _spec.SetField(authrequest.FieldConnectorData, field.TypeBytes, value) } - if value, ok := aru.mutation.CodeChallengeMethod(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldCodeChallengeMethod, - }) + if _u.mutation.ConnectorDataCleared() { + _spec.ClearField(authrequest.FieldConnectorData, field.TypeBytes) + } + if value, ok := _u.mutation.Expiry(); ok { + _spec.SetField(authrequest.FieldExpiry, field.TypeTime, value) + } + if value, ok := _u.mutation.CodeChallenge(); ok { + _spec.SetField(authrequest.FieldCodeChallenge, field.TypeString, value) + } + if value, ok := _u.mutation.CodeChallengeMethod(); ok { + _spec.SetField(authrequest.FieldCodeChallengeMethod, field.TypeString, value) } - if n, err = sqlgraph.UpdateNodes(ctx, aru.driver, _spec); err != nil { + if value, ok := _u.mutation.HmacKey(); ok { + _spec.SetField(authrequest.FieldHmacKey, field.TypeBytes, value) + } + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{authrequest.Label} } else if sqlgraph.IsConstraintError(err) { @@ -432,7 +447,8 @@ func (aru *AuthRequestUpdate) sqlSave(ctx context.Context) (n int, err error) { } return 0, err } - return n, nil + _u.mutation.done = true + return _node, nil } // AuthRequestUpdateOne is the builder for updating a single AuthRequest entity. @@ -444,220 +460,313 @@ type AuthRequestUpdateOne struct { } // SetClientID sets the "client_id" field. -func (aruo *AuthRequestUpdateOne) SetClientID(s string) *AuthRequestUpdateOne { - aruo.mutation.SetClientID(s) - return aruo +func (_u *AuthRequestUpdateOne) SetClientID(v string) *AuthRequestUpdateOne { + _u.mutation.SetClientID(v) + return _u +} + +// SetNillableClientID sets the "client_id" field if the given value is not nil. +func (_u *AuthRequestUpdateOne) SetNillableClientID(v *string) *AuthRequestUpdateOne { + if v != nil { + _u.SetClientID(*v) + } + return _u } // SetScopes sets the "scopes" field. -func (aruo *AuthRequestUpdateOne) SetScopes(s []string) *AuthRequestUpdateOne { - aruo.mutation.SetScopes(s) - return aruo +func (_u *AuthRequestUpdateOne) SetScopes(v []string) *AuthRequestUpdateOne { + _u.mutation.SetScopes(v) + return _u +} + +// AppendScopes appends value to the "scopes" field. +func (_u *AuthRequestUpdateOne) AppendScopes(v []string) *AuthRequestUpdateOne { + _u.mutation.AppendScopes(v) + return _u } // ClearScopes clears the value of the "scopes" field. -func (aruo *AuthRequestUpdateOne) ClearScopes() *AuthRequestUpdateOne { - aruo.mutation.ClearScopes() - return aruo +func (_u *AuthRequestUpdateOne) ClearScopes() *AuthRequestUpdateOne { + _u.mutation.ClearScopes() + return _u } // SetResponseTypes sets the "response_types" field. -func (aruo *AuthRequestUpdateOne) SetResponseTypes(s []string) *AuthRequestUpdateOne { - aruo.mutation.SetResponseTypes(s) - return aruo +func (_u *AuthRequestUpdateOne) SetResponseTypes(v []string) *AuthRequestUpdateOne { + _u.mutation.SetResponseTypes(v) + return _u +} + +// AppendResponseTypes appends value to the "response_types" field. +func (_u *AuthRequestUpdateOne) AppendResponseTypes(v []string) *AuthRequestUpdateOne { + _u.mutation.AppendResponseTypes(v) + return _u } // ClearResponseTypes clears the value of the "response_types" field. -func (aruo *AuthRequestUpdateOne) ClearResponseTypes() *AuthRequestUpdateOne { - aruo.mutation.ClearResponseTypes() - return aruo +func (_u *AuthRequestUpdateOne) ClearResponseTypes() *AuthRequestUpdateOne { + _u.mutation.ClearResponseTypes() + return _u } // SetRedirectURI sets the "redirect_uri" field. -func (aruo *AuthRequestUpdateOne) SetRedirectURI(s string) *AuthRequestUpdateOne { - aruo.mutation.SetRedirectURI(s) - return aruo +func (_u *AuthRequestUpdateOne) SetRedirectURI(v string) *AuthRequestUpdateOne { + _u.mutation.SetRedirectURI(v) + return _u +} + +// SetNillableRedirectURI sets the "redirect_uri" field if the given value is not nil. +func (_u *AuthRequestUpdateOne) SetNillableRedirectURI(v *string) *AuthRequestUpdateOne { + if v != nil { + _u.SetRedirectURI(*v) + } + return _u } // SetNonce sets the "nonce" field. -func (aruo *AuthRequestUpdateOne) SetNonce(s string) *AuthRequestUpdateOne { - aruo.mutation.SetNonce(s) - return aruo +func (_u *AuthRequestUpdateOne) SetNonce(v string) *AuthRequestUpdateOne { + _u.mutation.SetNonce(v) + return _u +} + +// SetNillableNonce sets the "nonce" field if the given value is not nil. +func (_u *AuthRequestUpdateOne) SetNillableNonce(v *string) *AuthRequestUpdateOne { + if v != nil { + _u.SetNonce(*v) + } + return _u } // SetState sets the "state" field. -func (aruo *AuthRequestUpdateOne) SetState(s string) *AuthRequestUpdateOne { - aruo.mutation.SetState(s) - return aruo +func (_u *AuthRequestUpdateOne) SetState(v string) *AuthRequestUpdateOne { + _u.mutation.SetState(v) + return _u +} + +// SetNillableState sets the "state" field if the given value is not nil. +func (_u *AuthRequestUpdateOne) SetNillableState(v *string) *AuthRequestUpdateOne { + if v != nil { + _u.SetState(*v) + } + return _u } // SetForceApprovalPrompt sets the "force_approval_prompt" field. -func (aruo *AuthRequestUpdateOne) SetForceApprovalPrompt(b bool) *AuthRequestUpdateOne { - aruo.mutation.SetForceApprovalPrompt(b) - return aruo +func (_u *AuthRequestUpdateOne) SetForceApprovalPrompt(v bool) *AuthRequestUpdateOne { + _u.mutation.SetForceApprovalPrompt(v) + return _u +} + +// SetNillableForceApprovalPrompt sets the "force_approval_prompt" field if the given value is not nil. +func (_u *AuthRequestUpdateOne) SetNillableForceApprovalPrompt(v *bool) *AuthRequestUpdateOne { + if v != nil { + _u.SetForceApprovalPrompt(*v) + } + return _u } // SetLoggedIn sets the "logged_in" field. -func (aruo *AuthRequestUpdateOne) SetLoggedIn(b bool) *AuthRequestUpdateOne { - aruo.mutation.SetLoggedIn(b) - return aruo +func (_u *AuthRequestUpdateOne) SetLoggedIn(v bool) *AuthRequestUpdateOne { + _u.mutation.SetLoggedIn(v) + return _u +} + +// SetNillableLoggedIn sets the "logged_in" field if the given value is not nil. +func (_u *AuthRequestUpdateOne) SetNillableLoggedIn(v *bool) *AuthRequestUpdateOne { + if v != nil { + _u.SetLoggedIn(*v) + } + return _u } // SetClaimsUserID sets the "claims_user_id" field. -func (aruo *AuthRequestUpdateOne) SetClaimsUserID(s string) *AuthRequestUpdateOne { - aruo.mutation.SetClaimsUserID(s) - return aruo +func (_u *AuthRequestUpdateOne) SetClaimsUserID(v string) *AuthRequestUpdateOne { + _u.mutation.SetClaimsUserID(v) + return _u +} + +// SetNillableClaimsUserID sets the "claims_user_id" field if the given value is not nil. +func (_u *AuthRequestUpdateOne) SetNillableClaimsUserID(v *string) *AuthRequestUpdateOne { + if v != nil { + _u.SetClaimsUserID(*v) + } + return _u } // SetClaimsUsername sets the "claims_username" field. -func (aruo *AuthRequestUpdateOne) SetClaimsUsername(s string) *AuthRequestUpdateOne { - aruo.mutation.SetClaimsUsername(s) - return aruo +func (_u *AuthRequestUpdateOne) SetClaimsUsername(v string) *AuthRequestUpdateOne { + _u.mutation.SetClaimsUsername(v) + return _u +} + +// SetNillableClaimsUsername sets the "claims_username" field if the given value is not nil. +func (_u *AuthRequestUpdateOne) SetNillableClaimsUsername(v *string) *AuthRequestUpdateOne { + if v != nil { + _u.SetClaimsUsername(*v) + } + return _u } // SetClaimsEmail sets the "claims_email" field. -func (aruo *AuthRequestUpdateOne) SetClaimsEmail(s string) *AuthRequestUpdateOne { - aruo.mutation.SetClaimsEmail(s) - return aruo +func (_u *AuthRequestUpdateOne) SetClaimsEmail(v string) *AuthRequestUpdateOne { + _u.mutation.SetClaimsEmail(v) + return _u +} + +// SetNillableClaimsEmail sets the "claims_email" field if the given value is not nil. +func (_u *AuthRequestUpdateOne) SetNillableClaimsEmail(v *string) *AuthRequestUpdateOne { + if v != nil { + _u.SetClaimsEmail(*v) + } + return _u } // SetClaimsEmailVerified sets the "claims_email_verified" field. -func (aruo *AuthRequestUpdateOne) SetClaimsEmailVerified(b bool) *AuthRequestUpdateOne { - aruo.mutation.SetClaimsEmailVerified(b) - return aruo +func (_u *AuthRequestUpdateOne) SetClaimsEmailVerified(v bool) *AuthRequestUpdateOne { + _u.mutation.SetClaimsEmailVerified(v) + return _u +} + +// SetNillableClaimsEmailVerified sets the "claims_email_verified" field if the given value is not nil. +func (_u *AuthRequestUpdateOne) SetNillableClaimsEmailVerified(v *bool) *AuthRequestUpdateOne { + if v != nil { + _u.SetClaimsEmailVerified(*v) + } + return _u } // SetClaimsGroups sets the "claims_groups" field. -func (aruo *AuthRequestUpdateOne) SetClaimsGroups(s []string) *AuthRequestUpdateOne { - aruo.mutation.SetClaimsGroups(s) - return aruo +func (_u *AuthRequestUpdateOne) SetClaimsGroups(v []string) *AuthRequestUpdateOne { + _u.mutation.SetClaimsGroups(v) + return _u +} + +// AppendClaimsGroups appends value to the "claims_groups" field. +func (_u *AuthRequestUpdateOne) AppendClaimsGroups(v []string) *AuthRequestUpdateOne { + _u.mutation.AppendClaimsGroups(v) + return _u } // ClearClaimsGroups clears the value of the "claims_groups" field. -func (aruo *AuthRequestUpdateOne) ClearClaimsGroups() *AuthRequestUpdateOne { - aruo.mutation.ClearClaimsGroups() - return aruo +func (_u *AuthRequestUpdateOne) ClearClaimsGroups() *AuthRequestUpdateOne { + _u.mutation.ClearClaimsGroups() + return _u } // SetClaimsPreferredUsername sets the "claims_preferred_username" field. -func (aruo *AuthRequestUpdateOne) SetClaimsPreferredUsername(s string) *AuthRequestUpdateOne { - aruo.mutation.SetClaimsPreferredUsername(s) - return aruo +func (_u *AuthRequestUpdateOne) SetClaimsPreferredUsername(v string) *AuthRequestUpdateOne { + _u.mutation.SetClaimsPreferredUsername(v) + return _u } // SetNillableClaimsPreferredUsername sets the "claims_preferred_username" field if the given value is not nil. -func (aruo *AuthRequestUpdateOne) SetNillableClaimsPreferredUsername(s *string) *AuthRequestUpdateOne { - if s != nil { - aruo.SetClaimsPreferredUsername(*s) +func (_u *AuthRequestUpdateOne) SetNillableClaimsPreferredUsername(v *string) *AuthRequestUpdateOne { + if v != nil { + _u.SetClaimsPreferredUsername(*v) } - return aruo + return _u } // SetConnectorID sets the "connector_id" field. -func (aruo *AuthRequestUpdateOne) SetConnectorID(s string) *AuthRequestUpdateOne { - aruo.mutation.SetConnectorID(s) - return aruo +func (_u *AuthRequestUpdateOne) SetConnectorID(v string) *AuthRequestUpdateOne { + _u.mutation.SetConnectorID(v) + return _u +} + +// SetNillableConnectorID sets the "connector_id" field if the given value is not nil. +func (_u *AuthRequestUpdateOne) SetNillableConnectorID(v *string) *AuthRequestUpdateOne { + if v != nil { + _u.SetConnectorID(*v) + } + return _u } // SetConnectorData sets the "connector_data" field. -func (aruo *AuthRequestUpdateOne) SetConnectorData(b []byte) *AuthRequestUpdateOne { - aruo.mutation.SetConnectorData(b) - return aruo +func (_u *AuthRequestUpdateOne) SetConnectorData(v []byte) *AuthRequestUpdateOne { + _u.mutation.SetConnectorData(v) + return _u } // ClearConnectorData clears the value of the "connector_data" field. -func (aruo *AuthRequestUpdateOne) ClearConnectorData() *AuthRequestUpdateOne { - aruo.mutation.ClearConnectorData() - return aruo +func (_u *AuthRequestUpdateOne) ClearConnectorData() *AuthRequestUpdateOne { + _u.mutation.ClearConnectorData() + return _u } // SetExpiry sets the "expiry" field. -func (aruo *AuthRequestUpdateOne) SetExpiry(t time.Time) *AuthRequestUpdateOne { - aruo.mutation.SetExpiry(t) - return aruo +func (_u *AuthRequestUpdateOne) SetExpiry(v time.Time) *AuthRequestUpdateOne { + _u.mutation.SetExpiry(v) + return _u +} + +// SetNillableExpiry sets the "expiry" field if the given value is not nil. +func (_u *AuthRequestUpdateOne) SetNillableExpiry(v *time.Time) *AuthRequestUpdateOne { + if v != nil { + _u.SetExpiry(*v) + } + return _u } // SetCodeChallenge sets the "code_challenge" field. -func (aruo *AuthRequestUpdateOne) SetCodeChallenge(s string) *AuthRequestUpdateOne { - aruo.mutation.SetCodeChallenge(s) - return aruo +func (_u *AuthRequestUpdateOne) SetCodeChallenge(v string) *AuthRequestUpdateOne { + _u.mutation.SetCodeChallenge(v) + return _u } // SetNillableCodeChallenge sets the "code_challenge" field if the given value is not nil. -func (aruo *AuthRequestUpdateOne) SetNillableCodeChallenge(s *string) *AuthRequestUpdateOne { - if s != nil { - aruo.SetCodeChallenge(*s) +func (_u *AuthRequestUpdateOne) SetNillableCodeChallenge(v *string) *AuthRequestUpdateOne { + if v != nil { + _u.SetCodeChallenge(*v) } - return aruo + return _u } // SetCodeChallengeMethod sets the "code_challenge_method" field. -func (aruo *AuthRequestUpdateOne) SetCodeChallengeMethod(s string) *AuthRequestUpdateOne { - aruo.mutation.SetCodeChallengeMethod(s) - return aruo +func (_u *AuthRequestUpdateOne) SetCodeChallengeMethod(v string) *AuthRequestUpdateOne { + _u.mutation.SetCodeChallengeMethod(v) + return _u } // SetNillableCodeChallengeMethod sets the "code_challenge_method" field if the given value is not nil. -func (aruo *AuthRequestUpdateOne) SetNillableCodeChallengeMethod(s *string) *AuthRequestUpdateOne { - if s != nil { - aruo.SetCodeChallengeMethod(*s) +func (_u *AuthRequestUpdateOne) SetNillableCodeChallengeMethod(v *string) *AuthRequestUpdateOne { + if v != nil { + _u.SetCodeChallengeMethod(*v) } - return aruo + return _u +} + +// SetHmacKey sets the "hmac_key" field. +func (_u *AuthRequestUpdateOne) SetHmacKey(v []byte) *AuthRequestUpdateOne { + _u.mutation.SetHmacKey(v) + return _u } // Mutation returns the AuthRequestMutation object of the builder. -func (aruo *AuthRequestUpdateOne) Mutation() *AuthRequestMutation { - return aruo.mutation +func (_u *AuthRequestUpdateOne) Mutation() *AuthRequestMutation { + return _u.mutation +} + +// Where appends a list predicates to the AuthRequestUpdate builder. +func (_u *AuthRequestUpdateOne) Where(ps ...predicate.AuthRequest) *AuthRequestUpdateOne { + _u.mutation.Where(ps...) + return _u } // Select allows selecting one or more fields (columns) of the returned entity. // The default is selecting all fields defined in the entity schema. -func (aruo *AuthRequestUpdateOne) Select(field string, fields ...string) *AuthRequestUpdateOne { - aruo.fields = append([]string{field}, fields...) - return aruo +func (_u *AuthRequestUpdateOne) Select(field string, fields ...string) *AuthRequestUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u } // Save executes the query and returns the updated AuthRequest entity. -func (aruo *AuthRequestUpdateOne) Save(ctx context.Context) (*AuthRequest, error) { - var ( - err error - node *AuthRequest - ) - if len(aruo.hooks) == 0 { - node, err = aruo.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*AuthRequestMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - aruo.mutation = mutation - node, err = aruo.sqlSave(ctx) - mutation.done = true - return node, err - }) - for i := len(aruo.hooks) - 1; i >= 0; i-- { - if aruo.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = aruo.hooks[i](mut) - } - v, err := mut.Mutate(ctx, aruo.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*AuthRequest) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from AuthRequestMutation", v) - } - node = nv - } - return node, err +func (_u *AuthRequestUpdateOne) Save(ctx context.Context) (*AuthRequest, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (aruo *AuthRequestUpdateOne) SaveX(ctx context.Context) *AuthRequest { - node, err := aruo.Save(ctx) +func (_u *AuthRequestUpdateOne) SaveX(ctx context.Context) *AuthRequest { + node, err := _u.Save(ctx) if err != nil { panic(err) } @@ -665,35 +774,26 @@ func (aruo *AuthRequestUpdateOne) SaveX(ctx context.Context) *AuthRequest { } // Exec executes the query on the entity. -func (aruo *AuthRequestUpdateOne) Exec(ctx context.Context) error { - _, err := aruo.Save(ctx) +func (_u *AuthRequestUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (aruo *AuthRequestUpdateOne) ExecX(ctx context.Context) { - if err := aruo.Exec(ctx); err != nil { +func (_u *AuthRequestUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } -func (aruo *AuthRequestUpdateOne) sqlSave(ctx context.Context) (_node *AuthRequest, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: authrequest.Table, - Columns: authrequest.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: authrequest.FieldID, - }, - }, - } - id, ok := aruo.mutation.ID() +func (_u *AuthRequestUpdateOne) sqlSave(ctx context.Context) (_node *AuthRequest, err error) { + _spec := sqlgraph.NewUpdateSpec(authrequest.Table, authrequest.Columns, sqlgraph.NewFieldSpec(authrequest.FieldID, field.TypeString)) + id, ok := _u.mutation.ID() if !ok { return nil, &ValidationError{Name: "id", err: errors.New(`db: missing "AuthRequest.id" for update`)} } _spec.Node.ID.Value = id - if fields := aruo.fields; len(fields) > 0 { + if fields := _u.fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, authrequest.FieldID) for _, f := range fields { @@ -705,174 +805,104 @@ func (aruo *AuthRequestUpdateOne) sqlSave(ctx context.Context) (_node *AuthReque } } } - if ps := aruo.mutation.predicates; len(ps) > 0 { + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := aruo.mutation.ClientID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldClientID, - }) + if value, ok := _u.mutation.ClientID(); ok { + _spec.SetField(authrequest.FieldClientID, field.TypeString, value) } - if value, ok := aruo.mutation.Scopes(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: authrequest.FieldScopes, - }) + if value, ok := _u.mutation.Scopes(); ok { + _spec.SetField(authrequest.FieldScopes, field.TypeJSON, value) } - if aruo.mutation.ScopesCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: authrequest.FieldScopes, + if value, ok := _u.mutation.AppendedScopes(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, authrequest.FieldScopes, value) }) } - if value, ok := aruo.mutation.ResponseTypes(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: authrequest.FieldResponseTypes, - }) + if _u.mutation.ScopesCleared() { + _spec.ClearField(authrequest.FieldScopes, field.TypeJSON) } - if aruo.mutation.ResponseTypesCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: authrequest.FieldResponseTypes, - }) + if value, ok := _u.mutation.ResponseTypes(); ok { + _spec.SetField(authrequest.FieldResponseTypes, field.TypeJSON, value) } - if value, ok := aruo.mutation.RedirectURI(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldRedirectURI, + if value, ok := _u.mutation.AppendedResponseTypes(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, authrequest.FieldResponseTypes, value) }) } - if value, ok := aruo.mutation.Nonce(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldNonce, - }) + if _u.mutation.ResponseTypesCleared() { + _spec.ClearField(authrequest.FieldResponseTypes, field.TypeJSON) } - if value, ok := aruo.mutation.State(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldState, - }) + if value, ok := _u.mutation.RedirectURI(); ok { + _spec.SetField(authrequest.FieldRedirectURI, field.TypeString, value) } - if value, ok := aruo.mutation.ForceApprovalPrompt(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBool, - Value: value, - Column: authrequest.FieldForceApprovalPrompt, - }) + if value, ok := _u.mutation.Nonce(); ok { + _spec.SetField(authrequest.FieldNonce, field.TypeString, value) } - if value, ok := aruo.mutation.LoggedIn(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBool, - Value: value, - Column: authrequest.FieldLoggedIn, - }) + if value, ok := _u.mutation.State(); ok { + _spec.SetField(authrequest.FieldState, field.TypeString, value) } - if value, ok := aruo.mutation.ClaimsUserID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldClaimsUserID, - }) + if value, ok := _u.mutation.ForceApprovalPrompt(); ok { + _spec.SetField(authrequest.FieldForceApprovalPrompt, field.TypeBool, value) } - if value, ok := aruo.mutation.ClaimsUsername(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldClaimsUsername, - }) + if value, ok := _u.mutation.LoggedIn(); ok { + _spec.SetField(authrequest.FieldLoggedIn, field.TypeBool, value) } - if value, ok := aruo.mutation.ClaimsEmail(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldClaimsEmail, - }) + if value, ok := _u.mutation.ClaimsUserID(); ok { + _spec.SetField(authrequest.FieldClaimsUserID, field.TypeString, value) } - if value, ok := aruo.mutation.ClaimsEmailVerified(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBool, - Value: value, - Column: authrequest.FieldClaimsEmailVerified, - }) + if value, ok := _u.mutation.ClaimsUsername(); ok { + _spec.SetField(authrequest.FieldClaimsUsername, field.TypeString, value) } - if value, ok := aruo.mutation.ClaimsGroups(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: authrequest.FieldClaimsGroups, - }) + if value, ok := _u.mutation.ClaimsEmail(); ok { + _spec.SetField(authrequest.FieldClaimsEmail, field.TypeString, value) } - if aruo.mutation.ClaimsGroupsCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: authrequest.FieldClaimsGroups, - }) + if value, ok := _u.mutation.ClaimsEmailVerified(); ok { + _spec.SetField(authrequest.FieldClaimsEmailVerified, field.TypeBool, value) } - if value, ok := aruo.mutation.ClaimsPreferredUsername(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldClaimsPreferredUsername, - }) + if value, ok := _u.mutation.ClaimsGroups(); ok { + _spec.SetField(authrequest.FieldClaimsGroups, field.TypeJSON, value) } - if value, ok := aruo.mutation.ConnectorID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldConnectorID, + if value, ok := _u.mutation.AppendedClaimsGroups(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, authrequest.FieldClaimsGroups, value) }) } - if value, ok := aruo.mutation.ConnectorData(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: authrequest.FieldConnectorData, - }) + if _u.mutation.ClaimsGroupsCleared() { + _spec.ClearField(authrequest.FieldClaimsGroups, field.TypeJSON) } - if aruo.mutation.ConnectorDataCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Column: authrequest.FieldConnectorData, - }) + if value, ok := _u.mutation.ClaimsPreferredUsername(); ok { + _spec.SetField(authrequest.FieldClaimsPreferredUsername, field.TypeString, value) } - if value, ok := aruo.mutation.Expiry(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: authrequest.FieldExpiry, - }) + if value, ok := _u.mutation.ConnectorID(); ok { + _spec.SetField(authrequest.FieldConnectorID, field.TypeString, value) } - if value, ok := aruo.mutation.CodeChallenge(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldCodeChallenge, - }) + if value, ok := _u.mutation.ConnectorData(); ok { + _spec.SetField(authrequest.FieldConnectorData, field.TypeBytes, value) } - if value, ok := aruo.mutation.CodeChallengeMethod(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: authrequest.FieldCodeChallengeMethod, - }) + if _u.mutation.ConnectorDataCleared() { + _spec.ClearField(authrequest.FieldConnectorData, field.TypeBytes) + } + if value, ok := _u.mutation.Expiry(); ok { + _spec.SetField(authrequest.FieldExpiry, field.TypeTime, value) + } + if value, ok := _u.mutation.CodeChallenge(); ok { + _spec.SetField(authrequest.FieldCodeChallenge, field.TypeString, value) + } + if value, ok := _u.mutation.CodeChallengeMethod(); ok { + _spec.SetField(authrequest.FieldCodeChallengeMethod, field.TypeString, value) + } + if value, ok := _u.mutation.HmacKey(); ok { + _spec.SetField(authrequest.FieldHmacKey, field.TypeBytes, value) } - _node = &AuthRequest{config: aruo.config} + _node = &AuthRequest{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues - if err = sqlgraph.UpdateNode(ctx, aruo.driver, _spec); err != nil { + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{authrequest.Label} } else if sqlgraph.IsConstraintError(err) { @@ -880,5 +910,6 @@ func (aruo *AuthRequestUpdateOne) sqlSave(ctx context.Context) (_node *AuthReque } return nil, err } + _u.mutation.done = true return _node, nil } diff --git a/storage/ent/db/client.go b/storage/ent/db/client.go index 4bf5586513..4fb28cb3c5 100644 --- a/storage/ent/db/client.go +++ b/storage/ent/db/client.go @@ -7,9 +7,13 @@ import ( "errors" "fmt" "log" + "reflect" "github.com/dexidp/dex/storage/ent/db/migrate" + "entgo.io/ent" + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/sql" "github.com/dexidp/dex/storage/ent/db/authcode" "github.com/dexidp/dex/storage/ent/db/authrequest" "github.com/dexidp/dex/storage/ent/db/connector" @@ -20,9 +24,6 @@ import ( "github.com/dexidp/dex/storage/ent/db/offlinesession" "github.com/dexidp/dex/storage/ent/db/password" "github.com/dexidp/dex/storage/ent/db/refreshtoken" - - "entgo.io/ent/dialect" - "entgo.io/ent/dialect/sql" ) // Client is the client that holds all ent builders. @@ -54,9 +55,7 @@ type Client struct { // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { - cfg := config{log: log.Println, hooks: &hooks{}} - cfg.options(opts...) - client := &Client{config: cfg} + client := &Client{config: newConfig(opts...)} client.init() return client } @@ -75,6 +74,62 @@ func (c *Client) init() { c.RefreshToken = NewRefreshTokenClient(c.config) } +type ( + // config is the configuration for the client and its builder. + config struct { + // driver used for executing database requests. + driver dialect.Driver + // debug enable a debug logging. + debug bool + // log used for logging on debug mode. + log func(...any) + // hooks to execute on mutations. + hooks *hooks + // interceptors to execute on queries. + inters *inters + } + // Option function to configure the client. + Option func(*config) +) + +// newConfig creates a new config for the client. +func newConfig(opts ...Option) config { + cfg := config{log: log.Println, hooks: &hooks{}, inters: &inters{}} + cfg.options(opts...) + return cfg +} + +// options applies the options on the config object. +func (c *config) options(opts ...Option) { + for _, opt := range opts { + opt(c) + } + if c.debug { + c.driver = dialect.Debug(c.driver, c.log) + } +} + +// Debug enables debug logging on the ent.Driver. +func Debug() Option { + return func(c *config) { + c.debug = true + } +} + +// Log sets the logging function for debug mode. +func Log(fn func(...any)) Option { + return func(c *config) { + c.log = fn + } +} + +// Driver configures the client driver. +func Driver(driver dialect.Driver) Option { + return func(c *config) { + c.driver = driver + } +} + // Open opens a database/sql.DB specified by the driver name and // the data source name, and returns a new client attached to it. // Optional parameters can be added for configuring the client. @@ -91,11 +146,14 @@ func Open(driverName, dataSourceName string, options ...Option) (*Client, error) } } +// ErrTxStarted is returned when trying to start a new transaction from a transactional client. +var ErrTxStarted = errors.New("db: cannot start a transaction within a transaction") + // Tx returns a new transactional client. The provided context // is used until the transaction is committed or rolled back. func (c *Client) Tx(ctx context.Context) (*Tx, error) { if _, ok := c.driver.(*txDriver); ok { - return nil, errors.New("db: cannot start a transaction within a transaction") + return nil, ErrTxStarted } tx, err := newTx(ctx, c.driver) if err != nil { @@ -154,7 +212,6 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) // AuthCode. // Query(). // Count(ctx) -// func (c *Client) Debug() *Client { if c.debug { return c @@ -174,16 +231,51 @@ func (c *Client) Close() error { // Use adds the mutation hooks to all the entity clients. // In order to add hooks to a specific client, call: `client.Node.Use(...)`. func (c *Client) Use(hooks ...Hook) { - c.AuthCode.Use(hooks...) - c.AuthRequest.Use(hooks...) - c.Connector.Use(hooks...) - c.DeviceRequest.Use(hooks...) - c.DeviceToken.Use(hooks...) - c.Keys.Use(hooks...) - c.OAuth2Client.Use(hooks...) - c.OfflineSession.Use(hooks...) - c.Password.Use(hooks...) - c.RefreshToken.Use(hooks...) + for _, n := range []interface{ Use(...Hook) }{ + c.AuthCode, c.AuthRequest, c.Connector, c.DeviceRequest, c.DeviceToken, c.Keys, + c.OAuth2Client, c.OfflineSession, c.Password, c.RefreshToken, + } { + n.Use(hooks...) + } +} + +// Intercept adds the query interceptors to all the entity clients. +// In order to add interceptors to a specific client, call: `client.Node.Intercept(...)`. +func (c *Client) Intercept(interceptors ...Interceptor) { + for _, n := range []interface{ Intercept(...Interceptor) }{ + c.AuthCode, c.AuthRequest, c.Connector, c.DeviceRequest, c.DeviceToken, c.Keys, + c.OAuth2Client, c.OfflineSession, c.Password, c.RefreshToken, + } { + n.Intercept(interceptors...) + } +} + +// Mutate implements the ent.Mutator interface. +func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) { + switch m := m.(type) { + case *AuthCodeMutation: + return c.AuthCode.mutate(ctx, m) + case *AuthRequestMutation: + return c.AuthRequest.mutate(ctx, m) + case *ConnectorMutation: + return c.Connector.mutate(ctx, m) + case *DeviceRequestMutation: + return c.DeviceRequest.mutate(ctx, m) + case *DeviceTokenMutation: + return c.DeviceToken.mutate(ctx, m) + case *KeysMutation: + return c.Keys.mutate(ctx, m) + case *OAuth2ClientMutation: + return c.OAuth2Client.mutate(ctx, m) + case *OfflineSessionMutation: + return c.OfflineSession.mutate(ctx, m) + case *PasswordMutation: + return c.Password.mutate(ctx, m) + case *RefreshTokenMutation: + return c.RefreshToken.mutate(ctx, m) + default: + return nil, fmt.Errorf("db: unknown mutation type %T", m) + } } // AuthCodeClient is a client for the AuthCode schema. @@ -202,6 +294,12 @@ func (c *AuthCodeClient) Use(hooks ...Hook) { c.hooks.AuthCode = append(c.hooks.AuthCode, hooks...) } +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `authcode.Intercept(f(g(h())))`. +func (c *AuthCodeClient) Intercept(interceptors ...Interceptor) { + c.inters.AuthCode = append(c.inters.AuthCode, interceptors...) +} + // Create returns a builder for creating a AuthCode entity. func (c *AuthCodeClient) Create() *AuthCodeCreate { mutation := newAuthCodeMutation(c.config, OpCreate) @@ -213,6 +311,21 @@ func (c *AuthCodeClient) CreateBulk(builders ...*AuthCodeCreate) *AuthCodeCreate return &AuthCodeCreateBulk{config: c.config, builders: builders} } +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *AuthCodeClient) MapCreateBulk(slice any, setFunc func(*AuthCodeCreate, int)) *AuthCodeCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &AuthCodeCreateBulk{err: fmt.Errorf("calling to AuthCodeClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*AuthCodeCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &AuthCodeCreateBulk{config: c.config, builders: builders} +} + // Update returns an update builder for AuthCode. func (c *AuthCodeClient) Update() *AuthCodeUpdate { mutation := newAuthCodeMutation(c.config, OpUpdate) @@ -220,8 +333,8 @@ func (c *AuthCodeClient) Update() *AuthCodeUpdate { } // UpdateOne returns an update builder for the given entity. -func (c *AuthCodeClient) UpdateOne(ac *AuthCode) *AuthCodeUpdateOne { - mutation := newAuthCodeMutation(c.config, OpUpdateOne, withAuthCode(ac)) +func (c *AuthCodeClient) UpdateOne(_m *AuthCode) *AuthCodeUpdateOne { + mutation := newAuthCodeMutation(c.config, OpUpdateOne, withAuthCode(_m)) return &AuthCodeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } @@ -238,11 +351,11 @@ func (c *AuthCodeClient) Delete() *AuthCodeDelete { } // DeleteOne returns a builder for deleting the given entity. -func (c *AuthCodeClient) DeleteOne(ac *AuthCode) *AuthCodeDeleteOne { - return c.DeleteOneID(ac.ID) +func (c *AuthCodeClient) DeleteOne(_m *AuthCode) *AuthCodeDeleteOne { + return c.DeleteOneID(_m.ID) } -// DeleteOne returns a builder for deleting the given entity by its id. +// DeleteOneID returns a builder for deleting the given entity by its id. func (c *AuthCodeClient) DeleteOneID(id string) *AuthCodeDeleteOne { builder := c.Delete().Where(authcode.ID(id)) builder.mutation.id = &id @@ -254,6 +367,8 @@ func (c *AuthCodeClient) DeleteOneID(id string) *AuthCodeDeleteOne { func (c *AuthCodeClient) Query() *AuthCodeQuery { return &AuthCodeQuery{ config: c.config, + ctx: &QueryContext{Type: TypeAuthCode}, + inters: c.Interceptors(), } } @@ -276,6 +391,26 @@ func (c *AuthCodeClient) Hooks() []Hook { return c.hooks.AuthCode } +// Interceptors returns the client interceptors. +func (c *AuthCodeClient) Interceptors() []Interceptor { + return c.inters.AuthCode +} + +func (c *AuthCodeClient) mutate(ctx context.Context, m *AuthCodeMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&AuthCodeCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&AuthCodeUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&AuthCodeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&AuthCodeDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("db: unknown AuthCode mutation op: %q", m.Op()) + } +} + // AuthRequestClient is a client for the AuthRequest schema. type AuthRequestClient struct { config @@ -292,6 +427,12 @@ func (c *AuthRequestClient) Use(hooks ...Hook) { c.hooks.AuthRequest = append(c.hooks.AuthRequest, hooks...) } +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `authrequest.Intercept(f(g(h())))`. +func (c *AuthRequestClient) Intercept(interceptors ...Interceptor) { + c.inters.AuthRequest = append(c.inters.AuthRequest, interceptors...) +} + // Create returns a builder for creating a AuthRequest entity. func (c *AuthRequestClient) Create() *AuthRequestCreate { mutation := newAuthRequestMutation(c.config, OpCreate) @@ -303,6 +444,21 @@ func (c *AuthRequestClient) CreateBulk(builders ...*AuthRequestCreate) *AuthRequ return &AuthRequestCreateBulk{config: c.config, builders: builders} } +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *AuthRequestClient) MapCreateBulk(slice any, setFunc func(*AuthRequestCreate, int)) *AuthRequestCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &AuthRequestCreateBulk{err: fmt.Errorf("calling to AuthRequestClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*AuthRequestCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &AuthRequestCreateBulk{config: c.config, builders: builders} +} + // Update returns an update builder for AuthRequest. func (c *AuthRequestClient) Update() *AuthRequestUpdate { mutation := newAuthRequestMutation(c.config, OpUpdate) @@ -310,8 +466,8 @@ func (c *AuthRequestClient) Update() *AuthRequestUpdate { } // UpdateOne returns an update builder for the given entity. -func (c *AuthRequestClient) UpdateOne(ar *AuthRequest) *AuthRequestUpdateOne { - mutation := newAuthRequestMutation(c.config, OpUpdateOne, withAuthRequest(ar)) +func (c *AuthRequestClient) UpdateOne(_m *AuthRequest) *AuthRequestUpdateOne { + mutation := newAuthRequestMutation(c.config, OpUpdateOne, withAuthRequest(_m)) return &AuthRequestUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } @@ -328,11 +484,11 @@ func (c *AuthRequestClient) Delete() *AuthRequestDelete { } // DeleteOne returns a builder for deleting the given entity. -func (c *AuthRequestClient) DeleteOne(ar *AuthRequest) *AuthRequestDeleteOne { - return c.DeleteOneID(ar.ID) +func (c *AuthRequestClient) DeleteOne(_m *AuthRequest) *AuthRequestDeleteOne { + return c.DeleteOneID(_m.ID) } -// DeleteOne returns a builder for deleting the given entity by its id. +// DeleteOneID returns a builder for deleting the given entity by its id. func (c *AuthRequestClient) DeleteOneID(id string) *AuthRequestDeleteOne { builder := c.Delete().Where(authrequest.ID(id)) builder.mutation.id = &id @@ -344,6 +500,8 @@ func (c *AuthRequestClient) DeleteOneID(id string) *AuthRequestDeleteOne { func (c *AuthRequestClient) Query() *AuthRequestQuery { return &AuthRequestQuery{ config: c.config, + ctx: &QueryContext{Type: TypeAuthRequest}, + inters: c.Interceptors(), } } @@ -366,6 +524,26 @@ func (c *AuthRequestClient) Hooks() []Hook { return c.hooks.AuthRequest } +// Interceptors returns the client interceptors. +func (c *AuthRequestClient) Interceptors() []Interceptor { + return c.inters.AuthRequest +} + +func (c *AuthRequestClient) mutate(ctx context.Context, m *AuthRequestMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&AuthRequestCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&AuthRequestUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&AuthRequestUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&AuthRequestDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("db: unknown AuthRequest mutation op: %q", m.Op()) + } +} + // ConnectorClient is a client for the Connector schema. type ConnectorClient struct { config @@ -382,6 +560,12 @@ func (c *ConnectorClient) Use(hooks ...Hook) { c.hooks.Connector = append(c.hooks.Connector, hooks...) } +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `connector.Intercept(f(g(h())))`. +func (c *ConnectorClient) Intercept(interceptors ...Interceptor) { + c.inters.Connector = append(c.inters.Connector, interceptors...) +} + // Create returns a builder for creating a Connector entity. func (c *ConnectorClient) Create() *ConnectorCreate { mutation := newConnectorMutation(c.config, OpCreate) @@ -393,6 +577,21 @@ func (c *ConnectorClient) CreateBulk(builders ...*ConnectorCreate) *ConnectorCre return &ConnectorCreateBulk{config: c.config, builders: builders} } +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *ConnectorClient) MapCreateBulk(slice any, setFunc func(*ConnectorCreate, int)) *ConnectorCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &ConnectorCreateBulk{err: fmt.Errorf("calling to ConnectorClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*ConnectorCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &ConnectorCreateBulk{config: c.config, builders: builders} +} + // Update returns an update builder for Connector. func (c *ConnectorClient) Update() *ConnectorUpdate { mutation := newConnectorMutation(c.config, OpUpdate) @@ -400,8 +599,8 @@ func (c *ConnectorClient) Update() *ConnectorUpdate { } // UpdateOne returns an update builder for the given entity. -func (c *ConnectorClient) UpdateOne(co *Connector) *ConnectorUpdateOne { - mutation := newConnectorMutation(c.config, OpUpdateOne, withConnector(co)) +func (c *ConnectorClient) UpdateOne(_m *Connector) *ConnectorUpdateOne { + mutation := newConnectorMutation(c.config, OpUpdateOne, withConnector(_m)) return &ConnectorUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } @@ -418,11 +617,11 @@ func (c *ConnectorClient) Delete() *ConnectorDelete { } // DeleteOne returns a builder for deleting the given entity. -func (c *ConnectorClient) DeleteOne(co *Connector) *ConnectorDeleteOne { - return c.DeleteOneID(co.ID) +func (c *ConnectorClient) DeleteOne(_m *Connector) *ConnectorDeleteOne { + return c.DeleteOneID(_m.ID) } -// DeleteOne returns a builder for deleting the given entity by its id. +// DeleteOneID returns a builder for deleting the given entity by its id. func (c *ConnectorClient) DeleteOneID(id string) *ConnectorDeleteOne { builder := c.Delete().Where(connector.ID(id)) builder.mutation.id = &id @@ -434,6 +633,8 @@ func (c *ConnectorClient) DeleteOneID(id string) *ConnectorDeleteOne { func (c *ConnectorClient) Query() *ConnectorQuery { return &ConnectorQuery{ config: c.config, + ctx: &QueryContext{Type: TypeConnector}, + inters: c.Interceptors(), } } @@ -456,6 +657,26 @@ func (c *ConnectorClient) Hooks() []Hook { return c.hooks.Connector } +// Interceptors returns the client interceptors. +func (c *ConnectorClient) Interceptors() []Interceptor { + return c.inters.Connector +} + +func (c *ConnectorClient) mutate(ctx context.Context, m *ConnectorMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&ConnectorCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&ConnectorUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&ConnectorUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&ConnectorDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("db: unknown Connector mutation op: %q", m.Op()) + } +} + // DeviceRequestClient is a client for the DeviceRequest schema. type DeviceRequestClient struct { config @@ -472,6 +693,12 @@ func (c *DeviceRequestClient) Use(hooks ...Hook) { c.hooks.DeviceRequest = append(c.hooks.DeviceRequest, hooks...) } +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `devicerequest.Intercept(f(g(h())))`. +func (c *DeviceRequestClient) Intercept(interceptors ...Interceptor) { + c.inters.DeviceRequest = append(c.inters.DeviceRequest, interceptors...) +} + // Create returns a builder for creating a DeviceRequest entity. func (c *DeviceRequestClient) Create() *DeviceRequestCreate { mutation := newDeviceRequestMutation(c.config, OpCreate) @@ -483,6 +710,21 @@ func (c *DeviceRequestClient) CreateBulk(builders ...*DeviceRequestCreate) *Devi return &DeviceRequestCreateBulk{config: c.config, builders: builders} } +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *DeviceRequestClient) MapCreateBulk(slice any, setFunc func(*DeviceRequestCreate, int)) *DeviceRequestCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &DeviceRequestCreateBulk{err: fmt.Errorf("calling to DeviceRequestClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*DeviceRequestCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &DeviceRequestCreateBulk{config: c.config, builders: builders} +} + // Update returns an update builder for DeviceRequest. func (c *DeviceRequestClient) Update() *DeviceRequestUpdate { mutation := newDeviceRequestMutation(c.config, OpUpdate) @@ -490,8 +732,8 @@ func (c *DeviceRequestClient) Update() *DeviceRequestUpdate { } // UpdateOne returns an update builder for the given entity. -func (c *DeviceRequestClient) UpdateOne(dr *DeviceRequest) *DeviceRequestUpdateOne { - mutation := newDeviceRequestMutation(c.config, OpUpdateOne, withDeviceRequest(dr)) +func (c *DeviceRequestClient) UpdateOne(_m *DeviceRequest) *DeviceRequestUpdateOne { + mutation := newDeviceRequestMutation(c.config, OpUpdateOne, withDeviceRequest(_m)) return &DeviceRequestUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } @@ -508,11 +750,11 @@ func (c *DeviceRequestClient) Delete() *DeviceRequestDelete { } // DeleteOne returns a builder for deleting the given entity. -func (c *DeviceRequestClient) DeleteOne(dr *DeviceRequest) *DeviceRequestDeleteOne { - return c.DeleteOneID(dr.ID) +func (c *DeviceRequestClient) DeleteOne(_m *DeviceRequest) *DeviceRequestDeleteOne { + return c.DeleteOneID(_m.ID) } -// DeleteOne returns a builder for deleting the given entity by its id. +// DeleteOneID returns a builder for deleting the given entity by its id. func (c *DeviceRequestClient) DeleteOneID(id int) *DeviceRequestDeleteOne { builder := c.Delete().Where(devicerequest.ID(id)) builder.mutation.id = &id @@ -524,6 +766,8 @@ func (c *DeviceRequestClient) DeleteOneID(id int) *DeviceRequestDeleteOne { func (c *DeviceRequestClient) Query() *DeviceRequestQuery { return &DeviceRequestQuery{ config: c.config, + ctx: &QueryContext{Type: TypeDeviceRequest}, + inters: c.Interceptors(), } } @@ -546,6 +790,26 @@ func (c *DeviceRequestClient) Hooks() []Hook { return c.hooks.DeviceRequest } +// Interceptors returns the client interceptors. +func (c *DeviceRequestClient) Interceptors() []Interceptor { + return c.inters.DeviceRequest +} + +func (c *DeviceRequestClient) mutate(ctx context.Context, m *DeviceRequestMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&DeviceRequestCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&DeviceRequestUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&DeviceRequestUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&DeviceRequestDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("db: unknown DeviceRequest mutation op: %q", m.Op()) + } +} + // DeviceTokenClient is a client for the DeviceToken schema. type DeviceTokenClient struct { config @@ -562,6 +826,12 @@ func (c *DeviceTokenClient) Use(hooks ...Hook) { c.hooks.DeviceToken = append(c.hooks.DeviceToken, hooks...) } +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `devicetoken.Intercept(f(g(h())))`. +func (c *DeviceTokenClient) Intercept(interceptors ...Interceptor) { + c.inters.DeviceToken = append(c.inters.DeviceToken, interceptors...) +} + // Create returns a builder for creating a DeviceToken entity. func (c *DeviceTokenClient) Create() *DeviceTokenCreate { mutation := newDeviceTokenMutation(c.config, OpCreate) @@ -573,6 +843,21 @@ func (c *DeviceTokenClient) CreateBulk(builders ...*DeviceTokenCreate) *DeviceTo return &DeviceTokenCreateBulk{config: c.config, builders: builders} } +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *DeviceTokenClient) MapCreateBulk(slice any, setFunc func(*DeviceTokenCreate, int)) *DeviceTokenCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &DeviceTokenCreateBulk{err: fmt.Errorf("calling to DeviceTokenClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*DeviceTokenCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &DeviceTokenCreateBulk{config: c.config, builders: builders} +} + // Update returns an update builder for DeviceToken. func (c *DeviceTokenClient) Update() *DeviceTokenUpdate { mutation := newDeviceTokenMutation(c.config, OpUpdate) @@ -580,8 +865,8 @@ func (c *DeviceTokenClient) Update() *DeviceTokenUpdate { } // UpdateOne returns an update builder for the given entity. -func (c *DeviceTokenClient) UpdateOne(dt *DeviceToken) *DeviceTokenUpdateOne { - mutation := newDeviceTokenMutation(c.config, OpUpdateOne, withDeviceToken(dt)) +func (c *DeviceTokenClient) UpdateOne(_m *DeviceToken) *DeviceTokenUpdateOne { + mutation := newDeviceTokenMutation(c.config, OpUpdateOne, withDeviceToken(_m)) return &DeviceTokenUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } @@ -598,11 +883,11 @@ func (c *DeviceTokenClient) Delete() *DeviceTokenDelete { } // DeleteOne returns a builder for deleting the given entity. -func (c *DeviceTokenClient) DeleteOne(dt *DeviceToken) *DeviceTokenDeleteOne { - return c.DeleteOneID(dt.ID) +func (c *DeviceTokenClient) DeleteOne(_m *DeviceToken) *DeviceTokenDeleteOne { + return c.DeleteOneID(_m.ID) } -// DeleteOne returns a builder for deleting the given entity by its id. +// DeleteOneID returns a builder for deleting the given entity by its id. func (c *DeviceTokenClient) DeleteOneID(id int) *DeviceTokenDeleteOne { builder := c.Delete().Where(devicetoken.ID(id)) builder.mutation.id = &id @@ -614,6 +899,8 @@ func (c *DeviceTokenClient) DeleteOneID(id int) *DeviceTokenDeleteOne { func (c *DeviceTokenClient) Query() *DeviceTokenQuery { return &DeviceTokenQuery{ config: c.config, + ctx: &QueryContext{Type: TypeDeviceToken}, + inters: c.Interceptors(), } } @@ -636,6 +923,26 @@ func (c *DeviceTokenClient) Hooks() []Hook { return c.hooks.DeviceToken } +// Interceptors returns the client interceptors. +func (c *DeviceTokenClient) Interceptors() []Interceptor { + return c.inters.DeviceToken +} + +func (c *DeviceTokenClient) mutate(ctx context.Context, m *DeviceTokenMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&DeviceTokenCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&DeviceTokenUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&DeviceTokenUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&DeviceTokenDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("db: unknown DeviceToken mutation op: %q", m.Op()) + } +} + // KeysClient is a client for the Keys schema. type KeysClient struct { config @@ -652,6 +959,12 @@ func (c *KeysClient) Use(hooks ...Hook) { c.hooks.Keys = append(c.hooks.Keys, hooks...) } +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `keys.Intercept(f(g(h())))`. +func (c *KeysClient) Intercept(interceptors ...Interceptor) { + c.inters.Keys = append(c.inters.Keys, interceptors...) +} + // Create returns a builder for creating a Keys entity. func (c *KeysClient) Create() *KeysCreate { mutation := newKeysMutation(c.config, OpCreate) @@ -663,6 +976,21 @@ func (c *KeysClient) CreateBulk(builders ...*KeysCreate) *KeysCreateBulk { return &KeysCreateBulk{config: c.config, builders: builders} } +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *KeysClient) MapCreateBulk(slice any, setFunc func(*KeysCreate, int)) *KeysCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &KeysCreateBulk{err: fmt.Errorf("calling to KeysClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*KeysCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &KeysCreateBulk{config: c.config, builders: builders} +} + // Update returns an update builder for Keys. func (c *KeysClient) Update() *KeysUpdate { mutation := newKeysMutation(c.config, OpUpdate) @@ -670,8 +998,8 @@ func (c *KeysClient) Update() *KeysUpdate { } // UpdateOne returns an update builder for the given entity. -func (c *KeysClient) UpdateOne(k *Keys) *KeysUpdateOne { - mutation := newKeysMutation(c.config, OpUpdateOne, withKeys(k)) +func (c *KeysClient) UpdateOne(_m *Keys) *KeysUpdateOne { + mutation := newKeysMutation(c.config, OpUpdateOne, withKeys(_m)) return &KeysUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } @@ -688,11 +1016,11 @@ func (c *KeysClient) Delete() *KeysDelete { } // DeleteOne returns a builder for deleting the given entity. -func (c *KeysClient) DeleteOne(k *Keys) *KeysDeleteOne { - return c.DeleteOneID(k.ID) +func (c *KeysClient) DeleteOne(_m *Keys) *KeysDeleteOne { + return c.DeleteOneID(_m.ID) } -// DeleteOne returns a builder for deleting the given entity by its id. +// DeleteOneID returns a builder for deleting the given entity by its id. func (c *KeysClient) DeleteOneID(id string) *KeysDeleteOne { builder := c.Delete().Where(keys.ID(id)) builder.mutation.id = &id @@ -704,6 +1032,8 @@ func (c *KeysClient) DeleteOneID(id string) *KeysDeleteOne { func (c *KeysClient) Query() *KeysQuery { return &KeysQuery{ config: c.config, + ctx: &QueryContext{Type: TypeKeys}, + inters: c.Interceptors(), } } @@ -726,6 +1056,26 @@ func (c *KeysClient) Hooks() []Hook { return c.hooks.Keys } +// Interceptors returns the client interceptors. +func (c *KeysClient) Interceptors() []Interceptor { + return c.inters.Keys +} + +func (c *KeysClient) mutate(ctx context.Context, m *KeysMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&KeysCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&KeysUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&KeysUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&KeysDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("db: unknown Keys mutation op: %q", m.Op()) + } +} + // OAuth2ClientClient is a client for the OAuth2Client schema. type OAuth2ClientClient struct { config @@ -742,6 +1092,12 @@ func (c *OAuth2ClientClient) Use(hooks ...Hook) { c.hooks.OAuth2Client = append(c.hooks.OAuth2Client, hooks...) } +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `oauth2client.Intercept(f(g(h())))`. +func (c *OAuth2ClientClient) Intercept(interceptors ...Interceptor) { + c.inters.OAuth2Client = append(c.inters.OAuth2Client, interceptors...) +} + // Create returns a builder for creating a OAuth2Client entity. func (c *OAuth2ClientClient) Create() *OAuth2ClientCreate { mutation := newOAuth2ClientMutation(c.config, OpCreate) @@ -753,6 +1109,21 @@ func (c *OAuth2ClientClient) CreateBulk(builders ...*OAuth2ClientCreate) *OAuth2 return &OAuth2ClientCreateBulk{config: c.config, builders: builders} } +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *OAuth2ClientClient) MapCreateBulk(slice any, setFunc func(*OAuth2ClientCreate, int)) *OAuth2ClientCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &OAuth2ClientCreateBulk{err: fmt.Errorf("calling to OAuth2ClientClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*OAuth2ClientCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &OAuth2ClientCreateBulk{config: c.config, builders: builders} +} + // Update returns an update builder for OAuth2Client. func (c *OAuth2ClientClient) Update() *OAuth2ClientUpdate { mutation := newOAuth2ClientMutation(c.config, OpUpdate) @@ -760,8 +1131,8 @@ func (c *OAuth2ClientClient) Update() *OAuth2ClientUpdate { } // UpdateOne returns an update builder for the given entity. -func (c *OAuth2ClientClient) UpdateOne(o *OAuth2Client) *OAuth2ClientUpdateOne { - mutation := newOAuth2ClientMutation(c.config, OpUpdateOne, withOAuth2Client(o)) +func (c *OAuth2ClientClient) UpdateOne(_m *OAuth2Client) *OAuth2ClientUpdateOne { + mutation := newOAuth2ClientMutation(c.config, OpUpdateOne, withOAuth2Client(_m)) return &OAuth2ClientUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } @@ -778,11 +1149,11 @@ func (c *OAuth2ClientClient) Delete() *OAuth2ClientDelete { } // DeleteOne returns a builder for deleting the given entity. -func (c *OAuth2ClientClient) DeleteOne(o *OAuth2Client) *OAuth2ClientDeleteOne { - return c.DeleteOneID(o.ID) +func (c *OAuth2ClientClient) DeleteOne(_m *OAuth2Client) *OAuth2ClientDeleteOne { + return c.DeleteOneID(_m.ID) } -// DeleteOne returns a builder for deleting the given entity by its id. +// DeleteOneID returns a builder for deleting the given entity by its id. func (c *OAuth2ClientClient) DeleteOneID(id string) *OAuth2ClientDeleteOne { builder := c.Delete().Where(oauth2client.ID(id)) builder.mutation.id = &id @@ -794,6 +1165,8 @@ func (c *OAuth2ClientClient) DeleteOneID(id string) *OAuth2ClientDeleteOne { func (c *OAuth2ClientClient) Query() *OAuth2ClientQuery { return &OAuth2ClientQuery{ config: c.config, + ctx: &QueryContext{Type: TypeOAuth2Client}, + inters: c.Interceptors(), } } @@ -816,6 +1189,26 @@ func (c *OAuth2ClientClient) Hooks() []Hook { return c.hooks.OAuth2Client } +// Interceptors returns the client interceptors. +func (c *OAuth2ClientClient) Interceptors() []Interceptor { + return c.inters.OAuth2Client +} + +func (c *OAuth2ClientClient) mutate(ctx context.Context, m *OAuth2ClientMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&OAuth2ClientCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&OAuth2ClientUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&OAuth2ClientUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&OAuth2ClientDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("db: unknown OAuth2Client mutation op: %q", m.Op()) + } +} + // OfflineSessionClient is a client for the OfflineSession schema. type OfflineSessionClient struct { config @@ -832,6 +1225,12 @@ func (c *OfflineSessionClient) Use(hooks ...Hook) { c.hooks.OfflineSession = append(c.hooks.OfflineSession, hooks...) } +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `offlinesession.Intercept(f(g(h())))`. +func (c *OfflineSessionClient) Intercept(interceptors ...Interceptor) { + c.inters.OfflineSession = append(c.inters.OfflineSession, interceptors...) +} + // Create returns a builder for creating a OfflineSession entity. func (c *OfflineSessionClient) Create() *OfflineSessionCreate { mutation := newOfflineSessionMutation(c.config, OpCreate) @@ -843,6 +1242,21 @@ func (c *OfflineSessionClient) CreateBulk(builders ...*OfflineSessionCreate) *Of return &OfflineSessionCreateBulk{config: c.config, builders: builders} } +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *OfflineSessionClient) MapCreateBulk(slice any, setFunc func(*OfflineSessionCreate, int)) *OfflineSessionCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &OfflineSessionCreateBulk{err: fmt.Errorf("calling to OfflineSessionClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*OfflineSessionCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &OfflineSessionCreateBulk{config: c.config, builders: builders} +} + // Update returns an update builder for OfflineSession. func (c *OfflineSessionClient) Update() *OfflineSessionUpdate { mutation := newOfflineSessionMutation(c.config, OpUpdate) @@ -850,8 +1264,8 @@ func (c *OfflineSessionClient) Update() *OfflineSessionUpdate { } // UpdateOne returns an update builder for the given entity. -func (c *OfflineSessionClient) UpdateOne(os *OfflineSession) *OfflineSessionUpdateOne { - mutation := newOfflineSessionMutation(c.config, OpUpdateOne, withOfflineSession(os)) +func (c *OfflineSessionClient) UpdateOne(_m *OfflineSession) *OfflineSessionUpdateOne { + mutation := newOfflineSessionMutation(c.config, OpUpdateOne, withOfflineSession(_m)) return &OfflineSessionUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } @@ -868,11 +1282,11 @@ func (c *OfflineSessionClient) Delete() *OfflineSessionDelete { } // DeleteOne returns a builder for deleting the given entity. -func (c *OfflineSessionClient) DeleteOne(os *OfflineSession) *OfflineSessionDeleteOne { - return c.DeleteOneID(os.ID) +func (c *OfflineSessionClient) DeleteOne(_m *OfflineSession) *OfflineSessionDeleteOne { + return c.DeleteOneID(_m.ID) } -// DeleteOne returns a builder for deleting the given entity by its id. +// DeleteOneID returns a builder for deleting the given entity by its id. func (c *OfflineSessionClient) DeleteOneID(id string) *OfflineSessionDeleteOne { builder := c.Delete().Where(offlinesession.ID(id)) builder.mutation.id = &id @@ -884,6 +1298,8 @@ func (c *OfflineSessionClient) DeleteOneID(id string) *OfflineSessionDeleteOne { func (c *OfflineSessionClient) Query() *OfflineSessionQuery { return &OfflineSessionQuery{ config: c.config, + ctx: &QueryContext{Type: TypeOfflineSession}, + inters: c.Interceptors(), } } @@ -906,6 +1322,26 @@ func (c *OfflineSessionClient) Hooks() []Hook { return c.hooks.OfflineSession } +// Interceptors returns the client interceptors. +func (c *OfflineSessionClient) Interceptors() []Interceptor { + return c.inters.OfflineSession +} + +func (c *OfflineSessionClient) mutate(ctx context.Context, m *OfflineSessionMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&OfflineSessionCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&OfflineSessionUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&OfflineSessionUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&OfflineSessionDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("db: unknown OfflineSession mutation op: %q", m.Op()) + } +} + // PasswordClient is a client for the Password schema. type PasswordClient struct { config @@ -922,6 +1358,12 @@ func (c *PasswordClient) Use(hooks ...Hook) { c.hooks.Password = append(c.hooks.Password, hooks...) } +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `password.Intercept(f(g(h())))`. +func (c *PasswordClient) Intercept(interceptors ...Interceptor) { + c.inters.Password = append(c.inters.Password, interceptors...) +} + // Create returns a builder for creating a Password entity. func (c *PasswordClient) Create() *PasswordCreate { mutation := newPasswordMutation(c.config, OpCreate) @@ -933,6 +1375,21 @@ func (c *PasswordClient) CreateBulk(builders ...*PasswordCreate) *PasswordCreate return &PasswordCreateBulk{config: c.config, builders: builders} } +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *PasswordClient) MapCreateBulk(slice any, setFunc func(*PasswordCreate, int)) *PasswordCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &PasswordCreateBulk{err: fmt.Errorf("calling to PasswordClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*PasswordCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &PasswordCreateBulk{config: c.config, builders: builders} +} + // Update returns an update builder for Password. func (c *PasswordClient) Update() *PasswordUpdate { mutation := newPasswordMutation(c.config, OpUpdate) @@ -940,8 +1397,8 @@ func (c *PasswordClient) Update() *PasswordUpdate { } // UpdateOne returns an update builder for the given entity. -func (c *PasswordClient) UpdateOne(pa *Password) *PasswordUpdateOne { - mutation := newPasswordMutation(c.config, OpUpdateOne, withPassword(pa)) +func (c *PasswordClient) UpdateOne(_m *Password) *PasswordUpdateOne { + mutation := newPasswordMutation(c.config, OpUpdateOne, withPassword(_m)) return &PasswordUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } @@ -958,11 +1415,11 @@ func (c *PasswordClient) Delete() *PasswordDelete { } // DeleteOne returns a builder for deleting the given entity. -func (c *PasswordClient) DeleteOne(pa *Password) *PasswordDeleteOne { - return c.DeleteOneID(pa.ID) +func (c *PasswordClient) DeleteOne(_m *Password) *PasswordDeleteOne { + return c.DeleteOneID(_m.ID) } -// DeleteOne returns a builder for deleting the given entity by its id. +// DeleteOneID returns a builder for deleting the given entity by its id. func (c *PasswordClient) DeleteOneID(id int) *PasswordDeleteOne { builder := c.Delete().Where(password.ID(id)) builder.mutation.id = &id @@ -974,6 +1431,8 @@ func (c *PasswordClient) DeleteOneID(id int) *PasswordDeleteOne { func (c *PasswordClient) Query() *PasswordQuery { return &PasswordQuery{ config: c.config, + ctx: &QueryContext{Type: TypePassword}, + inters: c.Interceptors(), } } @@ -996,6 +1455,26 @@ func (c *PasswordClient) Hooks() []Hook { return c.hooks.Password } +// Interceptors returns the client interceptors. +func (c *PasswordClient) Interceptors() []Interceptor { + return c.inters.Password +} + +func (c *PasswordClient) mutate(ctx context.Context, m *PasswordMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&PasswordCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&PasswordUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&PasswordUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&PasswordDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("db: unknown Password mutation op: %q", m.Op()) + } +} + // RefreshTokenClient is a client for the RefreshToken schema. type RefreshTokenClient struct { config @@ -1012,6 +1491,12 @@ func (c *RefreshTokenClient) Use(hooks ...Hook) { c.hooks.RefreshToken = append(c.hooks.RefreshToken, hooks...) } +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `refreshtoken.Intercept(f(g(h())))`. +func (c *RefreshTokenClient) Intercept(interceptors ...Interceptor) { + c.inters.RefreshToken = append(c.inters.RefreshToken, interceptors...) +} + // Create returns a builder for creating a RefreshToken entity. func (c *RefreshTokenClient) Create() *RefreshTokenCreate { mutation := newRefreshTokenMutation(c.config, OpCreate) @@ -1023,6 +1508,21 @@ func (c *RefreshTokenClient) CreateBulk(builders ...*RefreshTokenCreate) *Refres return &RefreshTokenCreateBulk{config: c.config, builders: builders} } +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *RefreshTokenClient) MapCreateBulk(slice any, setFunc func(*RefreshTokenCreate, int)) *RefreshTokenCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &RefreshTokenCreateBulk{err: fmt.Errorf("calling to RefreshTokenClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*RefreshTokenCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &RefreshTokenCreateBulk{config: c.config, builders: builders} +} + // Update returns an update builder for RefreshToken. func (c *RefreshTokenClient) Update() *RefreshTokenUpdate { mutation := newRefreshTokenMutation(c.config, OpUpdate) @@ -1030,8 +1530,8 @@ func (c *RefreshTokenClient) Update() *RefreshTokenUpdate { } // UpdateOne returns an update builder for the given entity. -func (c *RefreshTokenClient) UpdateOne(rt *RefreshToken) *RefreshTokenUpdateOne { - mutation := newRefreshTokenMutation(c.config, OpUpdateOne, withRefreshToken(rt)) +func (c *RefreshTokenClient) UpdateOne(_m *RefreshToken) *RefreshTokenUpdateOne { + mutation := newRefreshTokenMutation(c.config, OpUpdateOne, withRefreshToken(_m)) return &RefreshTokenUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } @@ -1048,11 +1548,11 @@ func (c *RefreshTokenClient) Delete() *RefreshTokenDelete { } // DeleteOne returns a builder for deleting the given entity. -func (c *RefreshTokenClient) DeleteOne(rt *RefreshToken) *RefreshTokenDeleteOne { - return c.DeleteOneID(rt.ID) +func (c *RefreshTokenClient) DeleteOne(_m *RefreshToken) *RefreshTokenDeleteOne { + return c.DeleteOneID(_m.ID) } -// DeleteOne returns a builder for deleting the given entity by its id. +// DeleteOneID returns a builder for deleting the given entity by its id. func (c *RefreshTokenClient) DeleteOneID(id string) *RefreshTokenDeleteOne { builder := c.Delete().Where(refreshtoken.ID(id)) builder.mutation.id = &id @@ -1064,6 +1564,8 @@ func (c *RefreshTokenClient) DeleteOneID(id string) *RefreshTokenDeleteOne { func (c *RefreshTokenClient) Query() *RefreshTokenQuery { return &RefreshTokenQuery{ config: c.config, + ctx: &QueryContext{Type: TypeRefreshToken}, + inters: c.Interceptors(), } } @@ -1085,3 +1587,35 @@ func (c *RefreshTokenClient) GetX(ctx context.Context, id string) *RefreshToken func (c *RefreshTokenClient) Hooks() []Hook { return c.hooks.RefreshToken } + +// Interceptors returns the client interceptors. +func (c *RefreshTokenClient) Interceptors() []Interceptor { + return c.inters.RefreshToken +} + +func (c *RefreshTokenClient) mutate(ctx context.Context, m *RefreshTokenMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&RefreshTokenCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&RefreshTokenUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&RefreshTokenUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&RefreshTokenDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("db: unknown RefreshToken mutation op: %q", m.Op()) + } +} + +// hooks and interceptors per client, for fast access. +type ( + hooks struct { + AuthCode, AuthRequest, Connector, DeviceRequest, DeviceToken, Keys, + OAuth2Client, OfflineSession, Password, RefreshToken []ent.Hook + } + inters struct { + AuthCode, AuthRequest, Connector, DeviceRequest, DeviceToken, Keys, + OAuth2Client, OfflineSession, Password, RefreshToken []ent.Interceptor + } +) diff --git a/storage/ent/db/config.go b/storage/ent/db/config.go deleted file mode 100644 index b26f166d29..0000000000 --- a/storage/ent/db/config.go +++ /dev/null @@ -1,68 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package db - -import ( - "entgo.io/ent" - "entgo.io/ent/dialect" -) - -// Option function to configure the client. -type Option func(*config) - -// Config is the configuration for the client and its builder. -type config struct { - // driver used for executing database requests. - driver dialect.Driver - // debug enable a debug logging. - debug bool - // log used for logging on debug mode. - log func(...interface{}) - // hooks to execute on mutations. - hooks *hooks -} - -// hooks per client, for fast access. -type hooks struct { - AuthCode []ent.Hook - AuthRequest []ent.Hook - Connector []ent.Hook - DeviceRequest []ent.Hook - DeviceToken []ent.Hook - Keys []ent.Hook - OAuth2Client []ent.Hook - OfflineSession []ent.Hook - Password []ent.Hook - RefreshToken []ent.Hook -} - -// Options applies the options on the config object. -func (c *config) options(opts ...Option) { - for _, opt := range opts { - opt(c) - } - if c.debug { - c.driver = dialect.Debug(c.driver, c.log) - } -} - -// Debug enables debug logging on the ent.Driver. -func Debug() Option { - return func(c *config) { - c.debug = true - } -} - -// Log sets the logging function for debug mode. -func Log(fn func(...interface{})) Option { - return func(c *config) { - c.log = fn - } -} - -// Driver configures the client driver. -func Driver(driver dialect.Driver) Option { - return func(c *config) { - c.driver = driver - } -} diff --git a/storage/ent/db/connector.go b/storage/ent/db/connector.go index 65cd4d25e8..2071d14ebb 100644 --- a/storage/ent/db/connector.go +++ b/storage/ent/db/connector.go @@ -6,6 +6,7 @@ import ( "fmt" "strings" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/dexidp/dex/storage/ent/db/connector" ) @@ -22,12 +23,13 @@ type Connector struct { // ResourceVersion holds the value of the "resource_version" field. ResourceVersion string `json:"resource_version,omitempty"` // Config holds the value of the "config" field. - Config []byte `json:"config,omitempty"` + Config []byte `json:"config,omitempty"` + selectValues sql.SelectValues } // scanValues returns the types for scanning values from sql.Rows. -func (*Connector) scanValues(columns []string) ([]interface{}, error) { - values := make([]interface{}, len(columns)) +func (*Connector) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) for i := range columns { switch columns[i] { case connector.FieldConfig: @@ -35,7 +37,7 @@ func (*Connector) scanValues(columns []string) ([]interface{}, error) { case connector.FieldID, connector.FieldType, connector.FieldName, connector.FieldResourceVersion: values[i] = new(sql.NullString) default: - return nil, fmt.Errorf("unexpected column %q for type Connector", columns[i]) + values[i] = new(sql.UnknownType) } } return values, nil @@ -43,7 +45,7 @@ func (*Connector) scanValues(columns []string) ([]interface{}, error) { // assignValues assigns the values that were returned from sql.Rows (after scanning) // to the Connector fields. -func (c *Connector) assignValues(columns []string, values []interface{}) error { +func (_m *Connector) assignValues(columns []string, values []any) error { if m, n := len(values), len(columns); m < n { return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) } @@ -53,80 +55,82 @@ func (c *Connector) assignValues(columns []string, values []interface{}) error { if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field id", values[i]) } else if value.Valid { - c.ID = value.String + _m.ID = value.String } case connector.FieldType: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field type", values[i]) } else if value.Valid { - c.Type = value.String + _m.Type = value.String } case connector.FieldName: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field name", values[i]) } else if value.Valid { - c.Name = value.String + _m.Name = value.String } case connector.FieldResourceVersion: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field resource_version", values[i]) } else if value.Valid { - c.ResourceVersion = value.String + _m.ResourceVersion = value.String } case connector.FieldConfig: if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field config", values[i]) } else if value != nil { - c.Config = *value + _m.Config = *value } + default: + _m.selectValues.Set(columns[i], values[i]) } } return nil } +// Value returns the ent.Value that was dynamically selected and assigned to the Connector. +// This includes values selected through modifiers, order, etc. +func (_m *Connector) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + // Update returns a builder for updating this Connector. // Note that you need to call Connector.Unwrap() before calling this method if this Connector // was returned from a transaction, and the transaction was committed or rolled back. -func (c *Connector) Update() *ConnectorUpdateOne { - return (&ConnectorClient{config: c.config}).UpdateOne(c) +func (_m *Connector) Update() *ConnectorUpdateOne { + return NewConnectorClient(_m.config).UpdateOne(_m) } // Unwrap unwraps the Connector entity that was returned from a transaction after it was closed, // so that all future queries will be executed through the driver which created the transaction. -func (c *Connector) Unwrap() *Connector { - _tx, ok := c.config.driver.(*txDriver) +func (_m *Connector) Unwrap() *Connector { + _tx, ok := _m.config.driver.(*txDriver) if !ok { panic("db: Connector is not a transactional entity") } - c.config.driver = _tx.drv - return c + _m.config.driver = _tx.drv + return _m } // String implements the fmt.Stringer. -func (c *Connector) String() string { +func (_m *Connector) String() string { var builder strings.Builder builder.WriteString("Connector(") - builder.WriteString(fmt.Sprintf("id=%v, ", c.ID)) + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) builder.WriteString("type=") - builder.WriteString(c.Type) + builder.WriteString(_m.Type) builder.WriteString(", ") builder.WriteString("name=") - builder.WriteString(c.Name) + builder.WriteString(_m.Name) builder.WriteString(", ") builder.WriteString("resource_version=") - builder.WriteString(c.ResourceVersion) + builder.WriteString(_m.ResourceVersion) builder.WriteString(", ") builder.WriteString("config=") - builder.WriteString(fmt.Sprintf("%v", c.Config)) + builder.WriteString(fmt.Sprintf("%v", _m.Config)) builder.WriteByte(')') return builder.String() } // Connectors is a parsable slice of Connector. type Connectors []*Connector - -func (c Connectors) config(cfg config) { - for _i := range c { - c[_i].config = cfg - } -} diff --git a/storage/ent/db/connector/connector.go b/storage/ent/db/connector/connector.go index 8f52a8f710..996328c12e 100644 --- a/storage/ent/db/connector/connector.go +++ b/storage/ent/db/connector/connector.go @@ -2,6 +2,10 @@ package connector +import ( + "entgo.io/ent/dialect/sql" +) + const ( // Label holds the string label denoting the connector type in the database. Label = "connector" @@ -46,3 +50,26 @@ var ( // IDValidator is a validator for the "id" field. It is called by the builders before save. IDValidator func(string) error ) + +// OrderOption defines the ordering options for the Connector queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByType orders the results by the type field. +func ByType(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldType, opts...).ToFunc() +} + +// ByName orders the results by the name field. +func ByName(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldName, opts...).ToFunc() +} + +// ByResourceVersion orders the results by the resource_version field. +func ByResourceVersion(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldResourceVersion, opts...).ToFunc() +} diff --git a/storage/ent/db/connector/where.go b/storage/ent/db/connector/where.go index e48576de93..39cc477fce 100644 --- a/storage/ent/db/connector/where.go +++ b/storage/ent/db/connector/where.go @@ -9,492 +9,325 @@ import ( // ID filters vertices based on their ID field. func ID(id string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.Connector(sql.FieldEQ(FieldID, id)) } // IDEQ applies the EQ predicate on the ID field. func IDEQ(id string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.Connector(sql.FieldEQ(FieldID, id)) } // IDNEQ applies the NEQ predicate on the ID field. func IDNEQ(id string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldID), id)) - }) + return predicate.Connector(sql.FieldNEQ(FieldID, id)) } // IDIn applies the In predicate on the ID field. func IDIn(ids ...string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.In(s.C(FieldID), v...)) - }) + return predicate.Connector(sql.FieldIn(FieldID, ids...)) } // IDNotIn applies the NotIn predicate on the ID field. func IDNotIn(ids ...string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.NotIn(s.C(FieldID), v...)) - }) + return predicate.Connector(sql.FieldNotIn(FieldID, ids...)) } // IDGT applies the GT predicate on the ID field. func IDGT(id string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldID), id)) - }) + return predicate.Connector(sql.FieldGT(FieldID, id)) } // IDGTE applies the GTE predicate on the ID field. func IDGTE(id string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldID), id)) - }) + return predicate.Connector(sql.FieldGTE(FieldID, id)) } // IDLT applies the LT predicate on the ID field. func IDLT(id string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldID), id)) - }) + return predicate.Connector(sql.FieldLT(FieldID, id)) } // IDLTE applies the LTE predicate on the ID field. func IDLTE(id string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldID), id)) - }) + return predicate.Connector(sql.FieldLTE(FieldID, id)) +} + +// IDEqualFold applies the EqualFold predicate on the ID field. +func IDEqualFold(id string) predicate.Connector { + return predicate.Connector(sql.FieldEqualFold(FieldID, id)) +} + +// IDContainsFold applies the ContainsFold predicate on the ID field. +func IDContainsFold(id string) predicate.Connector { + return predicate.Connector(sql.FieldContainsFold(FieldID, id)) } // Type applies equality check predicate on the "type" field. It's identical to TypeEQ. func Type(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldType), v)) - }) + return predicate.Connector(sql.FieldEQ(FieldType, v)) } // Name applies equality check predicate on the "name" field. It's identical to NameEQ. func Name(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldName), v)) - }) + return predicate.Connector(sql.FieldEQ(FieldName, v)) } // ResourceVersion applies equality check predicate on the "resource_version" field. It's identical to ResourceVersionEQ. func ResourceVersion(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldResourceVersion), v)) - }) + return predicate.Connector(sql.FieldEQ(FieldResourceVersion, v)) } // Config applies equality check predicate on the "config" field. It's identical to ConfigEQ. func Config(v []byte) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldConfig), v)) - }) + return predicate.Connector(sql.FieldEQ(FieldConfig, v)) } // TypeEQ applies the EQ predicate on the "type" field. func TypeEQ(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldType), v)) - }) + return predicate.Connector(sql.FieldEQ(FieldType, v)) } // TypeNEQ applies the NEQ predicate on the "type" field. func TypeNEQ(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldType), v)) - }) + return predicate.Connector(sql.FieldNEQ(FieldType, v)) } // TypeIn applies the In predicate on the "type" field. func TypeIn(vs ...string) predicate.Connector { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldType), v...)) - }) + return predicate.Connector(sql.FieldIn(FieldType, vs...)) } // TypeNotIn applies the NotIn predicate on the "type" field. func TypeNotIn(vs ...string) predicate.Connector { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldType), v...)) - }) + return predicate.Connector(sql.FieldNotIn(FieldType, vs...)) } // TypeGT applies the GT predicate on the "type" field. func TypeGT(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldType), v)) - }) + return predicate.Connector(sql.FieldGT(FieldType, v)) } // TypeGTE applies the GTE predicate on the "type" field. func TypeGTE(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldType), v)) - }) + return predicate.Connector(sql.FieldGTE(FieldType, v)) } // TypeLT applies the LT predicate on the "type" field. func TypeLT(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldType), v)) - }) + return predicate.Connector(sql.FieldLT(FieldType, v)) } // TypeLTE applies the LTE predicate on the "type" field. func TypeLTE(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldType), v)) - }) + return predicate.Connector(sql.FieldLTE(FieldType, v)) } // TypeContains applies the Contains predicate on the "type" field. func TypeContains(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldType), v)) - }) + return predicate.Connector(sql.FieldContains(FieldType, v)) } // TypeHasPrefix applies the HasPrefix predicate on the "type" field. func TypeHasPrefix(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldType), v)) - }) + return predicate.Connector(sql.FieldHasPrefix(FieldType, v)) } // TypeHasSuffix applies the HasSuffix predicate on the "type" field. func TypeHasSuffix(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldType), v)) - }) + return predicate.Connector(sql.FieldHasSuffix(FieldType, v)) } // TypeEqualFold applies the EqualFold predicate on the "type" field. func TypeEqualFold(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldType), v)) - }) + return predicate.Connector(sql.FieldEqualFold(FieldType, v)) } // TypeContainsFold applies the ContainsFold predicate on the "type" field. func TypeContainsFold(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldType), v)) - }) + return predicate.Connector(sql.FieldContainsFold(FieldType, v)) } // NameEQ applies the EQ predicate on the "name" field. func NameEQ(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldName), v)) - }) + return predicate.Connector(sql.FieldEQ(FieldName, v)) } // NameNEQ applies the NEQ predicate on the "name" field. func NameNEQ(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldName), v)) - }) + return predicate.Connector(sql.FieldNEQ(FieldName, v)) } // NameIn applies the In predicate on the "name" field. func NameIn(vs ...string) predicate.Connector { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldName), v...)) - }) + return predicate.Connector(sql.FieldIn(FieldName, vs...)) } // NameNotIn applies the NotIn predicate on the "name" field. func NameNotIn(vs ...string) predicate.Connector { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldName), v...)) - }) + return predicate.Connector(sql.FieldNotIn(FieldName, vs...)) } // NameGT applies the GT predicate on the "name" field. func NameGT(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldName), v)) - }) + return predicate.Connector(sql.FieldGT(FieldName, v)) } // NameGTE applies the GTE predicate on the "name" field. func NameGTE(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldName), v)) - }) + return predicate.Connector(sql.FieldGTE(FieldName, v)) } // NameLT applies the LT predicate on the "name" field. func NameLT(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldName), v)) - }) + return predicate.Connector(sql.FieldLT(FieldName, v)) } // NameLTE applies the LTE predicate on the "name" field. func NameLTE(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldName), v)) - }) + return predicate.Connector(sql.FieldLTE(FieldName, v)) } // NameContains applies the Contains predicate on the "name" field. func NameContains(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldName), v)) - }) + return predicate.Connector(sql.FieldContains(FieldName, v)) } // NameHasPrefix applies the HasPrefix predicate on the "name" field. func NameHasPrefix(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldName), v)) - }) + return predicate.Connector(sql.FieldHasPrefix(FieldName, v)) } // NameHasSuffix applies the HasSuffix predicate on the "name" field. func NameHasSuffix(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldName), v)) - }) + return predicate.Connector(sql.FieldHasSuffix(FieldName, v)) } // NameEqualFold applies the EqualFold predicate on the "name" field. func NameEqualFold(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldName), v)) - }) + return predicate.Connector(sql.FieldEqualFold(FieldName, v)) } // NameContainsFold applies the ContainsFold predicate on the "name" field. func NameContainsFold(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldName), v)) - }) + return predicate.Connector(sql.FieldContainsFold(FieldName, v)) } // ResourceVersionEQ applies the EQ predicate on the "resource_version" field. func ResourceVersionEQ(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldResourceVersion), v)) - }) + return predicate.Connector(sql.FieldEQ(FieldResourceVersion, v)) } // ResourceVersionNEQ applies the NEQ predicate on the "resource_version" field. func ResourceVersionNEQ(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldResourceVersion), v)) - }) + return predicate.Connector(sql.FieldNEQ(FieldResourceVersion, v)) } // ResourceVersionIn applies the In predicate on the "resource_version" field. func ResourceVersionIn(vs ...string) predicate.Connector { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldResourceVersion), v...)) - }) + return predicate.Connector(sql.FieldIn(FieldResourceVersion, vs...)) } // ResourceVersionNotIn applies the NotIn predicate on the "resource_version" field. func ResourceVersionNotIn(vs ...string) predicate.Connector { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldResourceVersion), v...)) - }) + return predicate.Connector(sql.FieldNotIn(FieldResourceVersion, vs...)) } // ResourceVersionGT applies the GT predicate on the "resource_version" field. func ResourceVersionGT(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldResourceVersion), v)) - }) + return predicate.Connector(sql.FieldGT(FieldResourceVersion, v)) } // ResourceVersionGTE applies the GTE predicate on the "resource_version" field. func ResourceVersionGTE(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldResourceVersion), v)) - }) + return predicate.Connector(sql.FieldGTE(FieldResourceVersion, v)) } // ResourceVersionLT applies the LT predicate on the "resource_version" field. func ResourceVersionLT(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldResourceVersion), v)) - }) + return predicate.Connector(sql.FieldLT(FieldResourceVersion, v)) } // ResourceVersionLTE applies the LTE predicate on the "resource_version" field. func ResourceVersionLTE(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldResourceVersion), v)) - }) + return predicate.Connector(sql.FieldLTE(FieldResourceVersion, v)) } // ResourceVersionContains applies the Contains predicate on the "resource_version" field. func ResourceVersionContains(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldResourceVersion), v)) - }) + return predicate.Connector(sql.FieldContains(FieldResourceVersion, v)) } // ResourceVersionHasPrefix applies the HasPrefix predicate on the "resource_version" field. func ResourceVersionHasPrefix(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldResourceVersion), v)) - }) + return predicate.Connector(sql.FieldHasPrefix(FieldResourceVersion, v)) } // ResourceVersionHasSuffix applies the HasSuffix predicate on the "resource_version" field. func ResourceVersionHasSuffix(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldResourceVersion), v)) - }) + return predicate.Connector(sql.FieldHasSuffix(FieldResourceVersion, v)) } // ResourceVersionEqualFold applies the EqualFold predicate on the "resource_version" field. func ResourceVersionEqualFold(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldResourceVersion), v)) - }) + return predicate.Connector(sql.FieldEqualFold(FieldResourceVersion, v)) } // ResourceVersionContainsFold applies the ContainsFold predicate on the "resource_version" field. func ResourceVersionContainsFold(v string) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldResourceVersion), v)) - }) + return predicate.Connector(sql.FieldContainsFold(FieldResourceVersion, v)) } // ConfigEQ applies the EQ predicate on the "config" field. func ConfigEQ(v []byte) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldConfig), v)) - }) + return predicate.Connector(sql.FieldEQ(FieldConfig, v)) } // ConfigNEQ applies the NEQ predicate on the "config" field. func ConfigNEQ(v []byte) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldConfig), v)) - }) + return predicate.Connector(sql.FieldNEQ(FieldConfig, v)) } // ConfigIn applies the In predicate on the "config" field. func ConfigIn(vs ...[]byte) predicate.Connector { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldConfig), v...)) - }) + return predicate.Connector(sql.FieldIn(FieldConfig, vs...)) } // ConfigNotIn applies the NotIn predicate on the "config" field. func ConfigNotIn(vs ...[]byte) predicate.Connector { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldConfig), v...)) - }) + return predicate.Connector(sql.FieldNotIn(FieldConfig, vs...)) } // ConfigGT applies the GT predicate on the "config" field. func ConfigGT(v []byte) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldConfig), v)) - }) + return predicate.Connector(sql.FieldGT(FieldConfig, v)) } // ConfigGTE applies the GTE predicate on the "config" field. func ConfigGTE(v []byte) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldConfig), v)) - }) + return predicate.Connector(sql.FieldGTE(FieldConfig, v)) } // ConfigLT applies the LT predicate on the "config" field. func ConfigLT(v []byte) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldConfig), v)) - }) + return predicate.Connector(sql.FieldLT(FieldConfig, v)) } // ConfigLTE applies the LTE predicate on the "config" field. func ConfigLTE(v []byte) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldConfig), v)) - }) + return predicate.Connector(sql.FieldLTE(FieldConfig, v)) } // And groups predicates with the AND operator between them. func And(predicates ...predicate.Connector) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for _, p := range predicates { - p(s1) - } - s.Where(s1.P()) - }) + return predicate.Connector(sql.AndPredicates(predicates...)) } // Or groups predicates with the OR operator between them. func Or(predicates ...predicate.Connector) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for i, p := range predicates { - if i > 0 { - s1.Or() - } - p(s1) - } - s.Where(s1.P()) - }) + return predicate.Connector(sql.OrPredicates(predicates...)) } // Not applies the not operator on the given predicate. func Not(p predicate.Connector) predicate.Connector { - return predicate.Connector(func(s *sql.Selector) { - p(s.Not()) - }) + return predicate.Connector(sql.NotPredicates(p)) } diff --git a/storage/ent/db/connector_create.go b/storage/ent/db/connector_create.go index ecff1c2f18..42da769e70 100644 --- a/storage/ent/db/connector_create.go +++ b/storage/ent/db/connector_create.go @@ -20,90 +20,48 @@ type ConnectorCreate struct { } // SetType sets the "type" field. -func (cc *ConnectorCreate) SetType(s string) *ConnectorCreate { - cc.mutation.SetType(s) - return cc +func (_c *ConnectorCreate) SetType(v string) *ConnectorCreate { + _c.mutation.SetType(v) + return _c } // SetName sets the "name" field. -func (cc *ConnectorCreate) SetName(s string) *ConnectorCreate { - cc.mutation.SetName(s) - return cc +func (_c *ConnectorCreate) SetName(v string) *ConnectorCreate { + _c.mutation.SetName(v) + return _c } // SetResourceVersion sets the "resource_version" field. -func (cc *ConnectorCreate) SetResourceVersion(s string) *ConnectorCreate { - cc.mutation.SetResourceVersion(s) - return cc +func (_c *ConnectorCreate) SetResourceVersion(v string) *ConnectorCreate { + _c.mutation.SetResourceVersion(v) + return _c } // SetConfig sets the "config" field. -func (cc *ConnectorCreate) SetConfig(b []byte) *ConnectorCreate { - cc.mutation.SetConfig(b) - return cc +func (_c *ConnectorCreate) SetConfig(v []byte) *ConnectorCreate { + _c.mutation.SetConfig(v) + return _c } // SetID sets the "id" field. -func (cc *ConnectorCreate) SetID(s string) *ConnectorCreate { - cc.mutation.SetID(s) - return cc +func (_c *ConnectorCreate) SetID(v string) *ConnectorCreate { + _c.mutation.SetID(v) + return _c } // Mutation returns the ConnectorMutation object of the builder. -func (cc *ConnectorCreate) Mutation() *ConnectorMutation { - return cc.mutation +func (_c *ConnectorCreate) Mutation() *ConnectorMutation { + return _c.mutation } // Save creates the Connector in the database. -func (cc *ConnectorCreate) Save(ctx context.Context) (*Connector, error) { - var ( - err error - node *Connector - ) - if len(cc.hooks) == 0 { - if err = cc.check(); err != nil { - return nil, err - } - node, err = cc.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*ConnectorMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = cc.check(); err != nil { - return nil, err - } - cc.mutation = mutation - if node, err = cc.sqlSave(ctx); err != nil { - return nil, err - } - mutation.id = &node.ID - mutation.done = true - return node, err - }) - for i := len(cc.hooks) - 1; i >= 0; i-- { - if cc.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = cc.hooks[i](mut) - } - v, err := mut.Mutate(ctx, cc.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*Connector) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from ConnectorMutation", v) - } - node = nv - } - return node, err +func (_c *ConnectorCreate) Save(ctx context.Context) (*Connector, error) { + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) } // SaveX calls Save and panics if Save returns an error. -func (cc *ConnectorCreate) SaveX(ctx context.Context) *Connector { - v, err := cc.Save(ctx) +func (_c *ConnectorCreate) SaveX(ctx context.Context) *Connector { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -111,43 +69,43 @@ func (cc *ConnectorCreate) SaveX(ctx context.Context) *Connector { } // Exec executes the query. -func (cc *ConnectorCreate) Exec(ctx context.Context) error { - _, err := cc.Save(ctx) +func (_c *ConnectorCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (cc *ConnectorCreate) ExecX(ctx context.Context) { - if err := cc.Exec(ctx); err != nil { +func (_c *ConnectorCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (cc *ConnectorCreate) check() error { - if _, ok := cc.mutation.GetType(); !ok { +func (_c *ConnectorCreate) check() error { + if _, ok := _c.mutation.GetType(); !ok { return &ValidationError{Name: "type", err: errors.New(`db: missing required field "Connector.type"`)} } - if v, ok := cc.mutation.GetType(); ok { + if v, ok := _c.mutation.GetType(); ok { if err := connector.TypeValidator(v); err != nil { return &ValidationError{Name: "type", err: fmt.Errorf(`db: validator failed for field "Connector.type": %w`, err)} } } - if _, ok := cc.mutation.Name(); !ok { + if _, ok := _c.mutation.Name(); !ok { return &ValidationError{Name: "name", err: errors.New(`db: missing required field "Connector.name"`)} } - if v, ok := cc.mutation.Name(); ok { + if v, ok := _c.mutation.Name(); ok { if err := connector.NameValidator(v); err != nil { return &ValidationError{Name: "name", err: fmt.Errorf(`db: validator failed for field "Connector.name": %w`, err)} } } - if _, ok := cc.mutation.ResourceVersion(); !ok { + if _, ok := _c.mutation.ResourceVersion(); !ok { return &ValidationError{Name: "resource_version", err: errors.New(`db: missing required field "Connector.resource_version"`)} } - if _, ok := cc.mutation.Config(); !ok { + if _, ok := _c.mutation.Config(); !ok { return &ValidationError{Name: "config", err: errors.New(`db: missing required field "Connector.config"`)} } - if v, ok := cc.mutation.ID(); ok { + if v, ok := _c.mutation.ID(); ok { if err := connector.IDValidator(v); err != nil { return &ValidationError{Name: "id", err: fmt.Errorf(`db: validator failed for field "Connector.id": %w`, err)} } @@ -155,9 +113,12 @@ func (cc *ConnectorCreate) check() error { return nil } -func (cc *ConnectorCreate) sqlSave(ctx context.Context) (*Connector, error) { - _node, _spec := cc.createSpec() - if err := sqlgraph.CreateNode(ctx, cc.driver, _spec); err != nil { +func (_c *ConnectorCreate) sqlSave(ctx context.Context) (*Connector, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -170,54 +131,34 @@ func (cc *ConnectorCreate) sqlSave(ctx context.Context) (*Connector, error) { return nil, fmt.Errorf("unexpected Connector.ID type: %T", _spec.ID.Value) } } + _c.mutation.id = &_node.ID + _c.mutation.done = true return _node, nil } -func (cc *ConnectorCreate) createSpec() (*Connector, *sqlgraph.CreateSpec) { +func (_c *ConnectorCreate) createSpec() (*Connector, *sqlgraph.CreateSpec) { var ( - _node = &Connector{config: cc.config} - _spec = &sqlgraph.CreateSpec{ - Table: connector.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: connector.FieldID, - }, - } + _node = &Connector{config: _c.config} + _spec = sqlgraph.NewCreateSpec(connector.Table, sqlgraph.NewFieldSpec(connector.FieldID, field.TypeString)) ) - if id, ok := cc.mutation.ID(); ok { + if id, ok := _c.mutation.ID(); ok { _node.ID = id _spec.ID.Value = id } - if value, ok := cc.mutation.GetType(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: connector.FieldType, - }) + if value, ok := _c.mutation.GetType(); ok { + _spec.SetField(connector.FieldType, field.TypeString, value) _node.Type = value } - if value, ok := cc.mutation.Name(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: connector.FieldName, - }) + if value, ok := _c.mutation.Name(); ok { + _spec.SetField(connector.FieldName, field.TypeString, value) _node.Name = value } - if value, ok := cc.mutation.ResourceVersion(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: connector.FieldResourceVersion, - }) + if value, ok := _c.mutation.ResourceVersion(); ok { + _spec.SetField(connector.FieldResourceVersion, field.TypeString, value) _node.ResourceVersion = value } - if value, ok := cc.mutation.Config(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: connector.FieldConfig, - }) + if value, ok := _c.mutation.Config(); ok { + _spec.SetField(connector.FieldConfig, field.TypeBytes, value) _node.Config = value } return _node, _spec @@ -226,17 +167,21 @@ func (cc *ConnectorCreate) createSpec() (*Connector, *sqlgraph.CreateSpec) { // ConnectorCreateBulk is the builder for creating many Connector entities in bulk. type ConnectorCreateBulk struct { config + err error builders []*ConnectorCreate } // Save creates the Connector entities in the database. -func (ccb *ConnectorCreateBulk) Save(ctx context.Context) ([]*Connector, error) { - specs := make([]*sqlgraph.CreateSpec, len(ccb.builders)) - nodes := make([]*Connector, len(ccb.builders)) - mutators := make([]Mutator, len(ccb.builders)) - for i := range ccb.builders { +func (_c *ConnectorCreateBulk) Save(ctx context.Context) ([]*Connector, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*Connector, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { func(i int, root context.Context) { - builder := ccb.builders[i] + builder := _c.builders[i] var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { mutation, ok := m.(*ConnectorMutation) if !ok { @@ -246,14 +191,14 @@ func (ccb *ConnectorCreateBulk) Save(ctx context.Context) ([]*Connector, error) return nil, err } builder.mutation = mutation - nodes[i], specs[i] = builder.createSpec() var err error + nodes[i], specs[i] = builder.createSpec() if i < len(mutators)-1 { - _, err = mutators[i+1].Mutate(root, ccb.builders[i+1].mutation) + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} // Invoke the actual operation on the latest mutation in the chain. - if err = sqlgraph.BatchCreate(ctx, ccb.driver, spec); err != nil { + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -273,7 +218,7 @@ func (ccb *ConnectorCreateBulk) Save(ctx context.Context) ([]*Connector, error) }(i, ctx) } if len(mutators) > 0 { - if _, err := mutators[0].Mutate(ctx, ccb.builders[0].mutation); err != nil { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { return nil, err } } @@ -281,8 +226,8 @@ func (ccb *ConnectorCreateBulk) Save(ctx context.Context) ([]*Connector, error) } // SaveX is like Save, but panics if an error occurs. -func (ccb *ConnectorCreateBulk) SaveX(ctx context.Context) []*Connector { - v, err := ccb.Save(ctx) +func (_c *ConnectorCreateBulk) SaveX(ctx context.Context) []*Connector { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -290,14 +235,14 @@ func (ccb *ConnectorCreateBulk) SaveX(ctx context.Context) []*Connector { } // Exec executes the query. -func (ccb *ConnectorCreateBulk) Exec(ctx context.Context) error { - _, err := ccb.Save(ctx) +func (_c *ConnectorCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (ccb *ConnectorCreateBulk) ExecX(ctx context.Context) { - if err := ccb.Exec(ctx); err != nil { +func (_c *ConnectorCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } diff --git a/storage/ent/db/connector_delete.go b/storage/ent/db/connector_delete.go index 0c5381eef5..4290b8db03 100644 --- a/storage/ent/db/connector_delete.go +++ b/storage/ent/db/connector_delete.go @@ -4,7 +4,6 @@ package db import ( "context" - "fmt" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" @@ -21,84 +20,56 @@ type ConnectorDelete struct { } // Where appends a list predicates to the ConnectorDelete builder. -func (cd *ConnectorDelete) Where(ps ...predicate.Connector) *ConnectorDelete { - cd.mutation.Where(ps...) - return cd +func (_d *ConnectorDelete) Where(ps ...predicate.Connector) *ConnectorDelete { + _d.mutation.Where(ps...) + return _d } // Exec executes the deletion query and returns how many vertices were deleted. -func (cd *ConnectorDelete) Exec(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(cd.hooks) == 0 { - affected, err = cd.sqlExec(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*ConnectorMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - cd.mutation = mutation - affected, err = cd.sqlExec(ctx) - mutation.done = true - return affected, err - }) - for i := len(cd.hooks) - 1; i >= 0; i-- { - if cd.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = cd.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, cd.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_d *ConnectorDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) } // ExecX is like Exec, but panics if an error occurs. -func (cd *ConnectorDelete) ExecX(ctx context.Context) int { - n, err := cd.Exec(ctx) +func (_d *ConnectorDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) if err != nil { panic(err) } return n } -func (cd *ConnectorDelete) sqlExec(ctx context.Context) (int, error) { - _spec := &sqlgraph.DeleteSpec{ - Node: &sqlgraph.NodeSpec{ - Table: connector.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: connector.FieldID, - }, - }, - } - if ps := cd.mutation.predicates; len(ps) > 0 { +func (_d *ConnectorDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(connector.Table, sqlgraph.NewFieldSpec(connector.FieldID, field.TypeString)) + if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - affected, err := sqlgraph.DeleteNodes(ctx, cd.driver, _spec) + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) if err != nil && sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } + _d.mutation.done = true return affected, err } // ConnectorDeleteOne is the builder for deleting a single Connector entity. type ConnectorDeleteOne struct { - cd *ConnectorDelete + _d *ConnectorDelete +} + +// Where appends a list predicates to the ConnectorDelete builder. +func (_d *ConnectorDeleteOne) Where(ps ...predicate.Connector) *ConnectorDeleteOne { + _d._d.mutation.Where(ps...) + return _d } // Exec executes the deletion query. -func (cdo *ConnectorDeleteOne) Exec(ctx context.Context) error { - n, err := cdo.cd.Exec(ctx) +func (_d *ConnectorDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) switch { case err != nil: return err @@ -110,6 +81,8 @@ func (cdo *ConnectorDeleteOne) Exec(ctx context.Context) error { } // ExecX is like Exec, but panics if an error occurs. -func (cdo *ConnectorDeleteOne) ExecX(ctx context.Context) { - cdo.cd.ExecX(ctx) +func (_d *ConnectorDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } } diff --git a/storage/ent/db/connector_query.go b/storage/ent/db/connector_query.go index 32d6020499..9f5e5dc2df 100644 --- a/storage/ent/db/connector_query.go +++ b/storage/ent/db/connector_query.go @@ -7,6 +7,7 @@ import ( "fmt" "math" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" @@ -17,11 +18,9 @@ import ( // ConnectorQuery is the builder for querying Connector entities. type ConnectorQuery struct { config - limit *int - offset *int - unique *bool - order []OrderFunc - fields []string + ctx *QueryContext + order []connector.OrderOption + inters []Interceptor predicates []predicate.Connector // intermediate query (i.e. traversal path). sql *sql.Selector @@ -29,40 +28,40 @@ type ConnectorQuery struct { } // Where adds a new predicate for the ConnectorQuery builder. -func (cq *ConnectorQuery) Where(ps ...predicate.Connector) *ConnectorQuery { - cq.predicates = append(cq.predicates, ps...) - return cq +func (_q *ConnectorQuery) Where(ps ...predicate.Connector) *ConnectorQuery { + _q.predicates = append(_q.predicates, ps...) + return _q } -// Limit adds a limit step to the query. -func (cq *ConnectorQuery) Limit(limit int) *ConnectorQuery { - cq.limit = &limit - return cq +// Limit the number of records to be returned by this query. +func (_q *ConnectorQuery) Limit(limit int) *ConnectorQuery { + _q.ctx.Limit = &limit + return _q } -// Offset adds an offset step to the query. -func (cq *ConnectorQuery) Offset(offset int) *ConnectorQuery { - cq.offset = &offset - return cq +// Offset to start from. +func (_q *ConnectorQuery) Offset(offset int) *ConnectorQuery { + _q.ctx.Offset = &offset + return _q } // Unique configures the query builder to filter duplicate records on query. // By default, unique is set to true, and can be disabled using this method. -func (cq *ConnectorQuery) Unique(unique bool) *ConnectorQuery { - cq.unique = &unique - return cq +func (_q *ConnectorQuery) Unique(unique bool) *ConnectorQuery { + _q.ctx.Unique = &unique + return _q } -// Order adds an order step to the query. -func (cq *ConnectorQuery) Order(o ...OrderFunc) *ConnectorQuery { - cq.order = append(cq.order, o...) - return cq +// Order specifies how the records should be ordered. +func (_q *ConnectorQuery) Order(o ...connector.OrderOption) *ConnectorQuery { + _q.order = append(_q.order, o...) + return _q } // First returns the first Connector entity from the query. // Returns a *NotFoundError when no Connector was found. -func (cq *ConnectorQuery) First(ctx context.Context) (*Connector, error) { - nodes, err := cq.Limit(1).All(ctx) +func (_q *ConnectorQuery) First(ctx context.Context) (*Connector, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) if err != nil { return nil, err } @@ -73,8 +72,8 @@ func (cq *ConnectorQuery) First(ctx context.Context) (*Connector, error) { } // FirstX is like First, but panics if an error occurs. -func (cq *ConnectorQuery) FirstX(ctx context.Context) *Connector { - node, err := cq.First(ctx) +func (_q *ConnectorQuery) FirstX(ctx context.Context) *Connector { + node, err := _q.First(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -83,9 +82,9 @@ func (cq *ConnectorQuery) FirstX(ctx context.Context) *Connector { // FirstID returns the first Connector ID from the query. // Returns a *NotFoundError when no Connector ID was found. -func (cq *ConnectorQuery) FirstID(ctx context.Context) (id string, err error) { +func (_q *ConnectorQuery) FirstID(ctx context.Context) (id string, err error) { var ids []string - if ids, err = cq.Limit(1).IDs(ctx); err != nil { + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { return } if len(ids) == 0 { @@ -96,8 +95,8 @@ func (cq *ConnectorQuery) FirstID(ctx context.Context) (id string, err error) { } // FirstIDX is like FirstID, but panics if an error occurs. -func (cq *ConnectorQuery) FirstIDX(ctx context.Context) string { - id, err := cq.FirstID(ctx) +func (_q *ConnectorQuery) FirstIDX(ctx context.Context) string { + id, err := _q.FirstID(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -107,8 +106,8 @@ func (cq *ConnectorQuery) FirstIDX(ctx context.Context) string { // Only returns a single Connector entity found by the query, ensuring it only returns one. // Returns a *NotSingularError when more than one Connector entity is found. // Returns a *NotFoundError when no Connector entities are found. -func (cq *ConnectorQuery) Only(ctx context.Context) (*Connector, error) { - nodes, err := cq.Limit(2).All(ctx) +func (_q *ConnectorQuery) Only(ctx context.Context) (*Connector, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) if err != nil { return nil, err } @@ -123,8 +122,8 @@ func (cq *ConnectorQuery) Only(ctx context.Context) (*Connector, error) { } // OnlyX is like Only, but panics if an error occurs. -func (cq *ConnectorQuery) OnlyX(ctx context.Context) *Connector { - node, err := cq.Only(ctx) +func (_q *ConnectorQuery) OnlyX(ctx context.Context) *Connector { + node, err := _q.Only(ctx) if err != nil { panic(err) } @@ -134,9 +133,9 @@ func (cq *ConnectorQuery) OnlyX(ctx context.Context) *Connector { // OnlyID is like Only, but returns the only Connector ID in the query. // Returns a *NotSingularError when more than one Connector ID is found. // Returns a *NotFoundError when no entities are found. -func (cq *ConnectorQuery) OnlyID(ctx context.Context) (id string, err error) { +func (_q *ConnectorQuery) OnlyID(ctx context.Context) (id string, err error) { var ids []string - if ids, err = cq.Limit(2).IDs(ctx); err != nil { + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { return } switch len(ids) { @@ -151,8 +150,8 @@ func (cq *ConnectorQuery) OnlyID(ctx context.Context) (id string, err error) { } // OnlyIDX is like OnlyID, but panics if an error occurs. -func (cq *ConnectorQuery) OnlyIDX(ctx context.Context) string { - id, err := cq.OnlyID(ctx) +func (_q *ConnectorQuery) OnlyIDX(ctx context.Context) string { + id, err := _q.OnlyID(ctx) if err != nil { panic(err) } @@ -160,16 +159,18 @@ func (cq *ConnectorQuery) OnlyIDX(ctx context.Context) string { } // All executes the query and returns a list of Connectors. -func (cq *ConnectorQuery) All(ctx context.Context) ([]*Connector, error) { - if err := cq.prepareQuery(ctx); err != nil { +func (_q *ConnectorQuery) All(ctx context.Context) ([]*Connector, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { return nil, err } - return cq.sqlAll(ctx) + qr := querierAll[[]*Connector, *ConnectorQuery]() + return withInterceptors[[]*Connector](ctx, _q, qr, _q.inters) } // AllX is like All, but panics if an error occurs. -func (cq *ConnectorQuery) AllX(ctx context.Context) []*Connector { - nodes, err := cq.All(ctx) +func (_q *ConnectorQuery) AllX(ctx context.Context) []*Connector { + nodes, err := _q.All(ctx) if err != nil { panic(err) } @@ -177,17 +178,20 @@ func (cq *ConnectorQuery) AllX(ctx context.Context) []*Connector { } // IDs executes the query and returns a list of Connector IDs. -func (cq *ConnectorQuery) IDs(ctx context.Context) ([]string, error) { - var ids []string - if err := cq.Select(connector.FieldID).Scan(ctx, &ids); err != nil { +func (_q *ConnectorQuery) IDs(ctx context.Context) (ids []string, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(connector.FieldID).Scan(ctx, &ids); err != nil { return nil, err } return ids, nil } // IDsX is like IDs, but panics if an error occurs. -func (cq *ConnectorQuery) IDsX(ctx context.Context) []string { - ids, err := cq.IDs(ctx) +func (_q *ConnectorQuery) IDsX(ctx context.Context) []string { + ids, err := _q.IDs(ctx) if err != nil { panic(err) } @@ -195,16 +199,17 @@ func (cq *ConnectorQuery) IDsX(ctx context.Context) []string { } // Count returns the count of the given query. -func (cq *ConnectorQuery) Count(ctx context.Context) (int, error) { - if err := cq.prepareQuery(ctx); err != nil { +func (_q *ConnectorQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { return 0, err } - return cq.sqlCount(ctx) + return withInterceptors[int](ctx, _q, querierCount[*ConnectorQuery](), _q.inters) } // CountX is like Count, but panics if an error occurs. -func (cq *ConnectorQuery) CountX(ctx context.Context) int { - count, err := cq.Count(ctx) +func (_q *ConnectorQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) if err != nil { panic(err) } @@ -212,16 +217,21 @@ func (cq *ConnectorQuery) CountX(ctx context.Context) int { } // Exist returns true if the query has elements in the graph. -func (cq *ConnectorQuery) Exist(ctx context.Context) (bool, error) { - if err := cq.prepareQuery(ctx); err != nil { - return false, err +func (_q *ConnectorQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("db: check existence: %w", err) + default: + return true, nil } - return cq.sqlExist(ctx) } // ExistX is like Exist, but panics if an error occurs. -func (cq *ConnectorQuery) ExistX(ctx context.Context) bool { - exist, err := cq.Exist(ctx) +func (_q *ConnectorQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) if err != nil { panic(err) } @@ -230,20 +240,19 @@ func (cq *ConnectorQuery) ExistX(ctx context.Context) bool { // Clone returns a duplicate of the ConnectorQuery builder, including all associated steps. It can be // used to prepare common query builders and use them differently after the clone is made. -func (cq *ConnectorQuery) Clone() *ConnectorQuery { - if cq == nil { +func (_q *ConnectorQuery) Clone() *ConnectorQuery { + if _q == nil { return nil } return &ConnectorQuery{ - config: cq.config, - limit: cq.limit, - offset: cq.offset, - order: append([]OrderFunc{}, cq.order...), - predicates: append([]predicate.Connector{}, cq.predicates...), + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]connector.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.Connector{}, _q.predicates...), // clone intermediate query. - sql: cq.sql.Clone(), - path: cq.path, - unique: cq.unique, + sql: _q.sql.Clone(), + path: _q.path, } } @@ -261,18 +270,12 @@ func (cq *ConnectorQuery) Clone() *ConnectorQuery { // GroupBy(connector.FieldType). // Aggregate(db.Count()). // Scan(ctx, &v) -// -func (cq *ConnectorQuery) GroupBy(field string, fields ...string) *ConnectorGroupBy { - grbuild := &ConnectorGroupBy{config: cq.config} - grbuild.fields = append([]string{field}, fields...) - grbuild.path = func(ctx context.Context) (prev *sql.Selector, err error) { - if err := cq.prepareQuery(ctx); err != nil { - return nil, err - } - return cq.sqlQuery(ctx), nil - } +func (_q *ConnectorQuery) GroupBy(field string, fields ...string) *ConnectorGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &ConnectorGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields grbuild.label = connector.Label - grbuild.flds, grbuild.scan = &grbuild.fields, grbuild.Scan + grbuild.scan = grbuild.Scan return grbuild } @@ -288,48 +291,62 @@ func (cq *ConnectorQuery) GroupBy(field string, fields ...string) *ConnectorGrou // client.Connector.Query(). // Select(connector.FieldType). // Scan(ctx, &v) -// -func (cq *ConnectorQuery) Select(fields ...string) *ConnectorSelect { - cq.fields = append(cq.fields, fields...) - selbuild := &ConnectorSelect{ConnectorQuery: cq} - selbuild.label = connector.Label - selbuild.flds, selbuild.scan = &cq.fields, selbuild.Scan - return selbuild +func (_q *ConnectorQuery) Select(fields ...string) *ConnectorSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &ConnectorSelect{ConnectorQuery: _q} + sbuild.label = connector.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a ConnectorSelect configured with the given aggregations. +func (_q *ConnectorQuery) Aggregate(fns ...AggregateFunc) *ConnectorSelect { + return _q.Select().Aggregate(fns...) } -func (cq *ConnectorQuery) prepareQuery(ctx context.Context) error { - for _, f := range cq.fields { +func (_q *ConnectorQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("db: uninitialized interceptor (forgotten import db/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { if !connector.ValidColumn(f) { return &ValidationError{Name: f, err: fmt.Errorf("db: invalid field %q for query", f)} } } - if cq.path != nil { - prev, err := cq.path(ctx) + if _q.path != nil { + prev, err := _q.path(ctx) if err != nil { return err } - cq.sql = prev + _q.sql = prev } return nil } -func (cq *ConnectorQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Connector, error) { +func (_q *ConnectorQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Connector, error) { var ( nodes = []*Connector{} - _spec = cq.querySpec() + _spec = _q.querySpec() ) - _spec.ScanValues = func(columns []string) ([]interface{}, error) { + _spec.ScanValues = func(columns []string) ([]any, error) { return (*Connector).scanValues(nil, columns) } - _spec.Assign = func(columns []string, values []interface{}) error { - node := &Connector{config: cq.config} + _spec.Assign = func(columns []string, values []any) error { + node := &Connector{config: _q.config} nodes = append(nodes, node) return node.assignValues(columns, values) } for i := range hooks { hooks[i](ctx, _spec) } - if err := sqlgraph.QueryNodes(ctx, cq.driver, _spec); err != nil { + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { return nil, err } if len(nodes) == 0 { @@ -338,40 +355,24 @@ func (cq *ConnectorQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Co return nodes, nil } -func (cq *ConnectorQuery) sqlCount(ctx context.Context) (int, error) { - _spec := cq.querySpec() - _spec.Node.Columns = cq.fields - if len(cq.fields) > 0 { - _spec.Unique = cq.unique != nil && *cq.unique - } - return sqlgraph.CountNodes(ctx, cq.driver, _spec) -} - -func (cq *ConnectorQuery) sqlExist(ctx context.Context) (bool, error) { - n, err := cq.sqlCount(ctx) - if err != nil { - return false, fmt.Errorf("db: check existence: %w", err) +func (_q *ConnectorQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique } - return n > 0, nil + return sqlgraph.CountNodes(ctx, _q.driver, _spec) } -func (cq *ConnectorQuery) querySpec() *sqlgraph.QuerySpec { - _spec := &sqlgraph.QuerySpec{ - Node: &sqlgraph.NodeSpec{ - Table: connector.Table, - Columns: connector.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: connector.FieldID, - }, - }, - From: cq.sql, - Unique: true, - } - if unique := cq.unique; unique != nil { +func (_q *ConnectorQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(connector.Table, connector.Columns, sqlgraph.NewFieldSpec(connector.FieldID, field.TypeString)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true } - if fields := cq.fields; len(fields) > 0 { + if fields := _q.ctx.Fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, connector.FieldID) for i := range fields { @@ -380,20 +381,20 @@ func (cq *ConnectorQuery) querySpec() *sqlgraph.QuerySpec { } } } - if ps := cq.predicates; len(ps) > 0 { + if ps := _q.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if limit := cq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { _spec.Limit = *limit } - if offset := cq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { _spec.Offset = *offset } - if ps := cq.order; len(ps) > 0 { + if ps := _q.order; len(ps) > 0 { _spec.Order = func(selector *sql.Selector) { for i := range ps { ps[i](selector) @@ -403,33 +404,33 @@ func (cq *ConnectorQuery) querySpec() *sqlgraph.QuerySpec { return _spec } -func (cq *ConnectorQuery) sqlQuery(ctx context.Context) *sql.Selector { - builder := sql.Dialect(cq.driver.Dialect()) +func (_q *ConnectorQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) t1 := builder.Table(connector.Table) - columns := cq.fields + columns := _q.ctx.Fields if len(columns) == 0 { columns = connector.Columns } selector := builder.Select(t1.Columns(columns...)...).From(t1) - if cq.sql != nil { - selector = cq.sql + if _q.sql != nil { + selector = _q.sql selector.Select(selector.Columns(columns...)...) } - if cq.unique != nil && *cq.unique { + if _q.ctx.Unique != nil && *_q.ctx.Unique { selector.Distinct() } - for _, p := range cq.predicates { + for _, p := range _q.predicates { p(selector) } - for _, p := range cq.order { + for _, p := range _q.order { p(selector) } - if offset := cq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { // limit is mandatory for offset clause. We start // with default value, and override it below if needed. selector.Offset(*offset).Limit(math.MaxInt32) } - if limit := cq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { selector.Limit(*limit) } return selector @@ -437,90 +438,88 @@ func (cq *ConnectorQuery) sqlQuery(ctx context.Context) *sql.Selector { // ConnectorGroupBy is the group-by builder for Connector entities. type ConnectorGroupBy struct { - config selector - fields []string - fns []AggregateFunc - // intermediate query (i.e. traversal path). - sql *sql.Selector - path func(context.Context) (*sql.Selector, error) + build *ConnectorQuery } // Aggregate adds the given aggregation functions to the group-by query. -func (cgb *ConnectorGroupBy) Aggregate(fns ...AggregateFunc) *ConnectorGroupBy { - cgb.fns = append(cgb.fns, fns...) - return cgb +func (_g *ConnectorGroupBy) Aggregate(fns ...AggregateFunc) *ConnectorGroupBy { + _g.fns = append(_g.fns, fns...) + return _g } -// Scan applies the group-by query and scans the result into the given value. -func (cgb *ConnectorGroupBy) Scan(ctx context.Context, v interface{}) error { - query, err := cgb.path(ctx) - if err != nil { +// Scan applies the selector query and scans the result into the given value. +func (_g *ConnectorGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { return err } - cgb.sql = query - return cgb.sqlScan(ctx, v) + return scanWithInterceptors[*ConnectorQuery, *ConnectorGroupBy](ctx, _g.build, _g, _g.build.inters, v) } -func (cgb *ConnectorGroupBy) sqlScan(ctx context.Context, v interface{}) error { - for _, f := range cgb.fields { - if !connector.ValidColumn(f) { - return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)} +func (_g *ConnectorGroupBy) sqlScan(ctx context.Context, root *ConnectorQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) } + columns = append(columns, aggregation...) + selector.Select(columns...) } - selector := cgb.sqlQuery() + selector.GroupBy(selector.Columns(*_g.flds...)...) if err := selector.Err(); err != nil { return err } rows := &sql.Rows{} query, args := selector.Query() - if err := cgb.driver.Query(ctx, query, args, rows); err != nil { + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() return sql.ScanSlice(rows, v) } -func (cgb *ConnectorGroupBy) sqlQuery() *sql.Selector { - selector := cgb.sql.Select() - aggregation := make([]string, 0, len(cgb.fns)) - for _, fn := range cgb.fns { - aggregation = append(aggregation, fn(selector)) - } - // If no columns were selected in a custom aggregation function, the default - // selection is the fields used for "group-by", and the aggregation functions. - if len(selector.SelectedColumns()) == 0 { - columns := make([]string, 0, len(cgb.fields)+len(cgb.fns)) - for _, f := range cgb.fields { - columns = append(columns, selector.C(f)) - } - columns = append(columns, aggregation...) - selector.Select(columns...) - } - return selector.GroupBy(selector.Columns(cgb.fields...)...) -} - // ConnectorSelect is the builder for selecting fields of Connector entities. type ConnectorSelect struct { *ConnectorQuery selector - // intermediate query (i.e. traversal path). - sql *sql.Selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *ConnectorSelect) Aggregate(fns ...AggregateFunc) *ConnectorSelect { + _s.fns = append(_s.fns, fns...) + return _s } // Scan applies the selector query and scans the result into the given value. -func (cs *ConnectorSelect) Scan(ctx context.Context, v interface{}) error { - if err := cs.prepareQuery(ctx); err != nil { +func (_s *ConnectorSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { return err } - cs.sql = cs.ConnectorQuery.sqlQuery(ctx) - return cs.sqlScan(ctx, v) + return scanWithInterceptors[*ConnectorQuery, *ConnectorSelect](ctx, _s.ConnectorQuery, _s, _s.inters, v) } -func (cs *ConnectorSelect) sqlScan(ctx context.Context, v interface{}) error { +func (_s *ConnectorSelect) sqlScan(ctx context.Context, root *ConnectorQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } rows := &sql.Rows{} - query, args := cs.sql.Query() - if err := cs.driver.Query(ctx, query, args, rows); err != nil { + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() diff --git a/storage/ent/db/connector_update.go b/storage/ent/db/connector_update.go index 736d0a62fb..bbcfd5654c 100644 --- a/storage/ent/db/connector_update.go +++ b/storage/ent/db/connector_update.go @@ -22,81 +22,72 @@ type ConnectorUpdate struct { } // Where appends a list predicates to the ConnectorUpdate builder. -func (cu *ConnectorUpdate) Where(ps ...predicate.Connector) *ConnectorUpdate { - cu.mutation.Where(ps...) - return cu +func (_u *ConnectorUpdate) Where(ps ...predicate.Connector) *ConnectorUpdate { + _u.mutation.Where(ps...) + return _u } // SetType sets the "type" field. -func (cu *ConnectorUpdate) SetType(s string) *ConnectorUpdate { - cu.mutation.SetType(s) - return cu +func (_u *ConnectorUpdate) SetType(v string) *ConnectorUpdate { + _u.mutation.SetType(v) + return _u +} + +// SetNillableType sets the "type" field if the given value is not nil. +func (_u *ConnectorUpdate) SetNillableType(v *string) *ConnectorUpdate { + if v != nil { + _u.SetType(*v) + } + return _u } // SetName sets the "name" field. -func (cu *ConnectorUpdate) SetName(s string) *ConnectorUpdate { - cu.mutation.SetName(s) - return cu +func (_u *ConnectorUpdate) SetName(v string) *ConnectorUpdate { + _u.mutation.SetName(v) + return _u +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (_u *ConnectorUpdate) SetNillableName(v *string) *ConnectorUpdate { + if v != nil { + _u.SetName(*v) + } + return _u } // SetResourceVersion sets the "resource_version" field. -func (cu *ConnectorUpdate) SetResourceVersion(s string) *ConnectorUpdate { - cu.mutation.SetResourceVersion(s) - return cu +func (_u *ConnectorUpdate) SetResourceVersion(v string) *ConnectorUpdate { + _u.mutation.SetResourceVersion(v) + return _u +} + +// SetNillableResourceVersion sets the "resource_version" field if the given value is not nil. +func (_u *ConnectorUpdate) SetNillableResourceVersion(v *string) *ConnectorUpdate { + if v != nil { + _u.SetResourceVersion(*v) + } + return _u } // SetConfig sets the "config" field. -func (cu *ConnectorUpdate) SetConfig(b []byte) *ConnectorUpdate { - cu.mutation.SetConfig(b) - return cu +func (_u *ConnectorUpdate) SetConfig(v []byte) *ConnectorUpdate { + _u.mutation.SetConfig(v) + return _u } // Mutation returns the ConnectorMutation object of the builder. -func (cu *ConnectorUpdate) Mutation() *ConnectorMutation { - return cu.mutation +func (_u *ConnectorUpdate) Mutation() *ConnectorMutation { + return _u.mutation } // Save executes the query and returns the number of nodes affected by the update operation. -func (cu *ConnectorUpdate) Save(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(cu.hooks) == 0 { - if err = cu.check(); err != nil { - return 0, err - } - affected, err = cu.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*ConnectorMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = cu.check(); err != nil { - return 0, err - } - cu.mutation = mutation - affected, err = cu.sqlSave(ctx) - mutation.done = true - return affected, err - }) - for i := len(cu.hooks) - 1; i >= 0; i-- { - if cu.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = cu.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, cu.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_u *ConnectorUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (cu *ConnectorUpdate) SaveX(ctx context.Context) int { - affected, err := cu.Save(ctx) +func (_u *ConnectorUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) if err != nil { panic(err) } @@ -104,26 +95,26 @@ func (cu *ConnectorUpdate) SaveX(ctx context.Context) int { } // Exec executes the query. -func (cu *ConnectorUpdate) Exec(ctx context.Context) error { - _, err := cu.Save(ctx) +func (_u *ConnectorUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (cu *ConnectorUpdate) ExecX(ctx context.Context) { - if err := cu.Exec(ctx); err != nil { +func (_u *ConnectorUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (cu *ConnectorUpdate) check() error { - if v, ok := cu.mutation.GetType(); ok { +func (_u *ConnectorUpdate) check() error { + if v, ok := _u.mutation.GetType(); ok { if err := connector.TypeValidator(v); err != nil { return &ValidationError{Name: "type", err: fmt.Errorf(`db: validator failed for field "Connector.type": %w`, err)} } } - if v, ok := cu.mutation.Name(); ok { + if v, ok := _u.mutation.Name(); ok { if err := connector.NameValidator(v); err != nil { return &ValidationError{Name: "name", err: fmt.Errorf(`db: validator failed for field "Connector.name": %w`, err)} } @@ -131,53 +122,31 @@ func (cu *ConnectorUpdate) check() error { return nil } -func (cu *ConnectorUpdate) sqlSave(ctx context.Context) (n int, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: connector.Table, - Columns: connector.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: connector.FieldID, - }, - }, +func (_u *ConnectorUpdate) sqlSave(ctx context.Context) (_node int, err error) { + if err := _u.check(); err != nil { + return _node, err } - if ps := cu.mutation.predicates; len(ps) > 0 { + _spec := sqlgraph.NewUpdateSpec(connector.Table, connector.Columns, sqlgraph.NewFieldSpec(connector.FieldID, field.TypeString)) + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := cu.mutation.GetType(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: connector.FieldType, - }) + if value, ok := _u.mutation.GetType(); ok { + _spec.SetField(connector.FieldType, field.TypeString, value) } - if value, ok := cu.mutation.Name(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: connector.FieldName, - }) + if value, ok := _u.mutation.Name(); ok { + _spec.SetField(connector.FieldName, field.TypeString, value) } - if value, ok := cu.mutation.ResourceVersion(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: connector.FieldResourceVersion, - }) + if value, ok := _u.mutation.ResourceVersion(); ok { + _spec.SetField(connector.FieldResourceVersion, field.TypeString, value) } - if value, ok := cu.mutation.Config(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: connector.FieldConfig, - }) + if value, ok := _u.mutation.Config(); ok { + _spec.SetField(connector.FieldConfig, field.TypeBytes, value) } - if n, err = sqlgraph.UpdateNodes(ctx, cu.driver, _spec); err != nil { + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{connector.Label} } else if sqlgraph.IsConstraintError(err) { @@ -185,7 +154,8 @@ func (cu *ConnectorUpdate) sqlSave(ctx context.Context) (n int, err error) { } return 0, err } - return n, nil + _u.mutation.done = true + return _node, nil } // ConnectorUpdateOne is the builder for updating a single Connector entity. @@ -197,88 +167,79 @@ type ConnectorUpdateOne struct { } // SetType sets the "type" field. -func (cuo *ConnectorUpdateOne) SetType(s string) *ConnectorUpdateOne { - cuo.mutation.SetType(s) - return cuo +func (_u *ConnectorUpdateOne) SetType(v string) *ConnectorUpdateOne { + _u.mutation.SetType(v) + return _u +} + +// SetNillableType sets the "type" field if the given value is not nil. +func (_u *ConnectorUpdateOne) SetNillableType(v *string) *ConnectorUpdateOne { + if v != nil { + _u.SetType(*v) + } + return _u } // SetName sets the "name" field. -func (cuo *ConnectorUpdateOne) SetName(s string) *ConnectorUpdateOne { - cuo.mutation.SetName(s) - return cuo +func (_u *ConnectorUpdateOne) SetName(v string) *ConnectorUpdateOne { + _u.mutation.SetName(v) + return _u +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (_u *ConnectorUpdateOne) SetNillableName(v *string) *ConnectorUpdateOne { + if v != nil { + _u.SetName(*v) + } + return _u } // SetResourceVersion sets the "resource_version" field. -func (cuo *ConnectorUpdateOne) SetResourceVersion(s string) *ConnectorUpdateOne { - cuo.mutation.SetResourceVersion(s) - return cuo +func (_u *ConnectorUpdateOne) SetResourceVersion(v string) *ConnectorUpdateOne { + _u.mutation.SetResourceVersion(v) + return _u +} + +// SetNillableResourceVersion sets the "resource_version" field if the given value is not nil. +func (_u *ConnectorUpdateOne) SetNillableResourceVersion(v *string) *ConnectorUpdateOne { + if v != nil { + _u.SetResourceVersion(*v) + } + return _u } // SetConfig sets the "config" field. -func (cuo *ConnectorUpdateOne) SetConfig(b []byte) *ConnectorUpdateOne { - cuo.mutation.SetConfig(b) - return cuo +func (_u *ConnectorUpdateOne) SetConfig(v []byte) *ConnectorUpdateOne { + _u.mutation.SetConfig(v) + return _u } // Mutation returns the ConnectorMutation object of the builder. -func (cuo *ConnectorUpdateOne) Mutation() *ConnectorMutation { - return cuo.mutation +func (_u *ConnectorUpdateOne) Mutation() *ConnectorMutation { + return _u.mutation +} + +// Where appends a list predicates to the ConnectorUpdate builder. +func (_u *ConnectorUpdateOne) Where(ps ...predicate.Connector) *ConnectorUpdateOne { + _u.mutation.Where(ps...) + return _u } // Select allows selecting one or more fields (columns) of the returned entity. // The default is selecting all fields defined in the entity schema. -func (cuo *ConnectorUpdateOne) Select(field string, fields ...string) *ConnectorUpdateOne { - cuo.fields = append([]string{field}, fields...) - return cuo +func (_u *ConnectorUpdateOne) Select(field string, fields ...string) *ConnectorUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u } // Save executes the query and returns the updated Connector entity. -func (cuo *ConnectorUpdateOne) Save(ctx context.Context) (*Connector, error) { - var ( - err error - node *Connector - ) - if len(cuo.hooks) == 0 { - if err = cuo.check(); err != nil { - return nil, err - } - node, err = cuo.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*ConnectorMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = cuo.check(); err != nil { - return nil, err - } - cuo.mutation = mutation - node, err = cuo.sqlSave(ctx) - mutation.done = true - return node, err - }) - for i := len(cuo.hooks) - 1; i >= 0; i-- { - if cuo.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = cuo.hooks[i](mut) - } - v, err := mut.Mutate(ctx, cuo.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*Connector) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from ConnectorMutation", v) - } - node = nv - } - return node, err +func (_u *ConnectorUpdateOne) Save(ctx context.Context) (*Connector, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (cuo *ConnectorUpdateOne) SaveX(ctx context.Context) *Connector { - node, err := cuo.Save(ctx) +func (_u *ConnectorUpdateOne) SaveX(ctx context.Context) *Connector { + node, err := _u.Save(ctx) if err != nil { panic(err) } @@ -286,26 +247,26 @@ func (cuo *ConnectorUpdateOne) SaveX(ctx context.Context) *Connector { } // Exec executes the query on the entity. -func (cuo *ConnectorUpdateOne) Exec(ctx context.Context) error { - _, err := cuo.Save(ctx) +func (_u *ConnectorUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (cuo *ConnectorUpdateOne) ExecX(ctx context.Context) { - if err := cuo.Exec(ctx); err != nil { +func (_u *ConnectorUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (cuo *ConnectorUpdateOne) check() error { - if v, ok := cuo.mutation.GetType(); ok { +func (_u *ConnectorUpdateOne) check() error { + if v, ok := _u.mutation.GetType(); ok { if err := connector.TypeValidator(v); err != nil { return &ValidationError{Name: "type", err: fmt.Errorf(`db: validator failed for field "Connector.type": %w`, err)} } } - if v, ok := cuo.mutation.Name(); ok { + if v, ok := _u.mutation.Name(); ok { if err := connector.NameValidator(v); err != nil { return &ValidationError{Name: "name", err: fmt.Errorf(`db: validator failed for field "Connector.name": %w`, err)} } @@ -313,23 +274,17 @@ func (cuo *ConnectorUpdateOne) check() error { return nil } -func (cuo *ConnectorUpdateOne) sqlSave(ctx context.Context) (_node *Connector, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: connector.Table, - Columns: connector.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: connector.FieldID, - }, - }, +func (_u *ConnectorUpdateOne) sqlSave(ctx context.Context) (_node *Connector, err error) { + if err := _u.check(); err != nil { + return _node, err } - id, ok := cuo.mutation.ID() + _spec := sqlgraph.NewUpdateSpec(connector.Table, connector.Columns, sqlgraph.NewFieldSpec(connector.FieldID, field.TypeString)) + id, ok := _u.mutation.ID() if !ok { return nil, &ValidationError{Name: "id", err: errors.New(`db: missing "Connector.id" for update`)} } _spec.Node.ID.Value = id - if fields := cuo.fields; len(fields) > 0 { + if fields := _u.fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, connector.FieldID) for _, f := range fields { @@ -341,45 +296,29 @@ func (cuo *ConnectorUpdateOne) sqlSave(ctx context.Context) (_node *Connector, e } } } - if ps := cuo.mutation.predicates; len(ps) > 0 { + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := cuo.mutation.GetType(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: connector.FieldType, - }) + if value, ok := _u.mutation.GetType(); ok { + _spec.SetField(connector.FieldType, field.TypeString, value) } - if value, ok := cuo.mutation.Name(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: connector.FieldName, - }) + if value, ok := _u.mutation.Name(); ok { + _spec.SetField(connector.FieldName, field.TypeString, value) } - if value, ok := cuo.mutation.ResourceVersion(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: connector.FieldResourceVersion, - }) + if value, ok := _u.mutation.ResourceVersion(); ok { + _spec.SetField(connector.FieldResourceVersion, field.TypeString, value) } - if value, ok := cuo.mutation.Config(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: connector.FieldConfig, - }) + if value, ok := _u.mutation.Config(); ok { + _spec.SetField(connector.FieldConfig, field.TypeBytes, value) } - _node = &Connector{config: cuo.config} + _node = &Connector{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues - if err = sqlgraph.UpdateNode(ctx, cuo.driver, _spec); err != nil { + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{connector.Label} } else if sqlgraph.IsConstraintError(err) { @@ -387,5 +326,6 @@ func (cuo *ConnectorUpdateOne) sqlSave(ctx context.Context) (_node *Connector, e } return nil, err } + _u.mutation.done = true return _node, nil } diff --git a/storage/ent/db/context.go b/storage/ent/db/context.go deleted file mode 100644 index 95e1ad8b09..0000000000 --- a/storage/ent/db/context.go +++ /dev/null @@ -1,33 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package db - -import ( - "context" -) - -type clientCtxKey struct{} - -// FromContext returns a Client stored inside a context, or nil if there isn't one. -func FromContext(ctx context.Context) *Client { - c, _ := ctx.Value(clientCtxKey{}).(*Client) - return c -} - -// NewContext returns a new context with the given Client attached. -func NewContext(parent context.Context, c *Client) context.Context { - return context.WithValue(parent, clientCtxKey{}, c) -} - -type txCtxKey struct{} - -// TxFromContext returns a Tx stored inside a context, or nil if there isn't one. -func TxFromContext(ctx context.Context) *Tx { - tx, _ := ctx.Value(txCtxKey{}).(*Tx) - return tx -} - -// NewTxContext returns a new context with the given Tx attached. -func NewTxContext(parent context.Context, tx *Tx) context.Context { - return context.WithValue(parent, txCtxKey{}, tx) -} diff --git a/storage/ent/db/devicerequest.go b/storage/ent/db/devicerequest.go index d358f1741f..ca502a2cd5 100644 --- a/storage/ent/db/devicerequest.go +++ b/storage/ent/db/devicerequest.go @@ -8,6 +8,7 @@ import ( "strings" "time" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/dexidp/dex/storage/ent/db/devicerequest" ) @@ -28,12 +29,13 @@ type DeviceRequest struct { // Scopes holds the value of the "scopes" field. Scopes []string `json:"scopes,omitempty"` // Expiry holds the value of the "expiry" field. - Expiry time.Time `json:"expiry,omitempty"` + Expiry time.Time `json:"expiry,omitempty"` + selectValues sql.SelectValues } // scanValues returns the types for scanning values from sql.Rows. -func (*DeviceRequest) scanValues(columns []string) ([]interface{}, error) { - values := make([]interface{}, len(columns)) +func (*DeviceRequest) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) for i := range columns { switch columns[i] { case devicerequest.FieldScopes: @@ -45,7 +47,7 @@ func (*DeviceRequest) scanValues(columns []string) ([]interface{}, error) { case devicerequest.FieldExpiry: values[i] = new(sql.NullTime) default: - return nil, fmt.Errorf("unexpected column %q for type DeviceRequest", columns[i]) + values[i] = new(sql.UnknownType) } } return values, nil @@ -53,7 +55,7 @@ func (*DeviceRequest) scanValues(columns []string) ([]interface{}, error) { // assignValues assigns the values that were returned from sql.Rows (after scanning) // to the DeviceRequest fields. -func (dr *DeviceRequest) assignValues(columns []string, values []interface{}) error { +func (_m *DeviceRequest) assignValues(columns []string, values []any) error { if m, n := len(values), len(columns); m < n { return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) } @@ -64,36 +66,36 @@ func (dr *DeviceRequest) assignValues(columns []string, values []interface{}) er if !ok { return fmt.Errorf("unexpected type %T for field id", value) } - dr.ID = int(value.Int64) + _m.ID = int(value.Int64) case devicerequest.FieldUserCode: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field user_code", values[i]) } else if value.Valid { - dr.UserCode = value.String + _m.UserCode = value.String } case devicerequest.FieldDeviceCode: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field device_code", values[i]) } else if value.Valid { - dr.DeviceCode = value.String + _m.DeviceCode = value.String } case devicerequest.FieldClientID: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field client_id", values[i]) } else if value.Valid { - dr.ClientID = value.String + _m.ClientID = value.String } case devicerequest.FieldClientSecret: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field client_secret", values[i]) } else if value.Valid { - dr.ClientSecret = value.String + _m.ClientSecret = value.String } case devicerequest.FieldScopes: if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field scopes", values[i]) } else if value != nil && len(*value) > 0 { - if err := json.Unmarshal(*value, &dr.Scopes); err != nil { + if err := json.Unmarshal(*value, &_m.Scopes); err != nil { return fmt.Errorf("unmarshal field scopes: %w", err) } } @@ -101,62 +103,64 @@ func (dr *DeviceRequest) assignValues(columns []string, values []interface{}) er if value, ok := values[i].(*sql.NullTime); !ok { return fmt.Errorf("unexpected type %T for field expiry", values[i]) } else if value.Valid { - dr.Expiry = value.Time + _m.Expiry = value.Time } + default: + _m.selectValues.Set(columns[i], values[i]) } } return nil } +// Value returns the ent.Value that was dynamically selected and assigned to the DeviceRequest. +// This includes values selected through modifiers, order, etc. +func (_m *DeviceRequest) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + // Update returns a builder for updating this DeviceRequest. // Note that you need to call DeviceRequest.Unwrap() before calling this method if this DeviceRequest // was returned from a transaction, and the transaction was committed or rolled back. -func (dr *DeviceRequest) Update() *DeviceRequestUpdateOne { - return (&DeviceRequestClient{config: dr.config}).UpdateOne(dr) +func (_m *DeviceRequest) Update() *DeviceRequestUpdateOne { + return NewDeviceRequestClient(_m.config).UpdateOne(_m) } // Unwrap unwraps the DeviceRequest entity that was returned from a transaction after it was closed, // so that all future queries will be executed through the driver which created the transaction. -func (dr *DeviceRequest) Unwrap() *DeviceRequest { - _tx, ok := dr.config.driver.(*txDriver) +func (_m *DeviceRequest) Unwrap() *DeviceRequest { + _tx, ok := _m.config.driver.(*txDriver) if !ok { panic("db: DeviceRequest is not a transactional entity") } - dr.config.driver = _tx.drv - return dr + _m.config.driver = _tx.drv + return _m } // String implements the fmt.Stringer. -func (dr *DeviceRequest) String() string { +func (_m *DeviceRequest) String() string { var builder strings.Builder builder.WriteString("DeviceRequest(") - builder.WriteString(fmt.Sprintf("id=%v, ", dr.ID)) + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) builder.WriteString("user_code=") - builder.WriteString(dr.UserCode) + builder.WriteString(_m.UserCode) builder.WriteString(", ") builder.WriteString("device_code=") - builder.WriteString(dr.DeviceCode) + builder.WriteString(_m.DeviceCode) builder.WriteString(", ") builder.WriteString("client_id=") - builder.WriteString(dr.ClientID) + builder.WriteString(_m.ClientID) builder.WriteString(", ") builder.WriteString("client_secret=") - builder.WriteString(dr.ClientSecret) + builder.WriteString(_m.ClientSecret) builder.WriteString(", ") builder.WriteString("scopes=") - builder.WriteString(fmt.Sprintf("%v", dr.Scopes)) + builder.WriteString(fmt.Sprintf("%v", _m.Scopes)) builder.WriteString(", ") builder.WriteString("expiry=") - builder.WriteString(dr.Expiry.Format(time.ANSIC)) + builder.WriteString(_m.Expiry.Format(time.ANSIC)) builder.WriteByte(')') return builder.String() } // DeviceRequests is a parsable slice of DeviceRequest. type DeviceRequests []*DeviceRequest - -func (dr DeviceRequests) config(cfg config) { - for _i := range dr { - dr[_i].config = cfg - } -} diff --git a/storage/ent/db/devicerequest/devicerequest.go b/storage/ent/db/devicerequest/devicerequest.go index 5dd032d613..d27f3971ca 100644 --- a/storage/ent/db/devicerequest/devicerequest.go +++ b/storage/ent/db/devicerequest/devicerequest.go @@ -2,6 +2,10 @@ package devicerequest +import ( + "entgo.io/ent/dialect/sql" +) + const ( // Label holds the string label denoting the devicerequest type in the database. Label = "device_request" @@ -54,3 +58,36 @@ var ( // ClientSecretValidator is a validator for the "client_secret" field. It is called by the builders before save. ClientSecretValidator func(string) error ) + +// OrderOption defines the ordering options for the DeviceRequest queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByUserCode orders the results by the user_code field. +func ByUserCode(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUserCode, opts...).ToFunc() +} + +// ByDeviceCode orders the results by the device_code field. +func ByDeviceCode(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldDeviceCode, opts...).ToFunc() +} + +// ByClientID orders the results by the client_id field. +func ByClientID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClientID, opts...).ToFunc() +} + +// ByClientSecret orders the results by the client_secret field. +func ByClientSecret(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClientSecret, opts...).ToFunc() +} + +// ByExpiry orders the results by the expiry field. +func ByExpiry(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldExpiry, opts...).ToFunc() +} diff --git a/storage/ent/db/devicerequest/where.go b/storage/ent/db/devicerequest/where.go index 5cb5ce4489..47a578fc3c 100644 --- a/storage/ent/db/devicerequest/where.go +++ b/storage/ent/db/devicerequest/where.go @@ -11,612 +11,395 @@ import ( // ID filters vertices based on their ID field. func ID(id int) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.DeviceRequest(sql.FieldEQ(FieldID, id)) } // IDEQ applies the EQ predicate on the ID field. func IDEQ(id int) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.DeviceRequest(sql.FieldEQ(FieldID, id)) } // IDNEQ applies the NEQ predicate on the ID field. func IDNEQ(id int) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldID), id)) - }) + return predicate.DeviceRequest(sql.FieldNEQ(FieldID, id)) } // IDIn applies the In predicate on the ID field. func IDIn(ids ...int) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.In(s.C(FieldID), v...)) - }) + return predicate.DeviceRequest(sql.FieldIn(FieldID, ids...)) } // IDNotIn applies the NotIn predicate on the ID field. func IDNotIn(ids ...int) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.NotIn(s.C(FieldID), v...)) - }) + return predicate.DeviceRequest(sql.FieldNotIn(FieldID, ids...)) } // IDGT applies the GT predicate on the ID field. func IDGT(id int) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldID), id)) - }) + return predicate.DeviceRequest(sql.FieldGT(FieldID, id)) } // IDGTE applies the GTE predicate on the ID field. func IDGTE(id int) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldID), id)) - }) + return predicate.DeviceRequest(sql.FieldGTE(FieldID, id)) } // IDLT applies the LT predicate on the ID field. func IDLT(id int) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldID), id)) - }) + return predicate.DeviceRequest(sql.FieldLT(FieldID, id)) } // IDLTE applies the LTE predicate on the ID field. func IDLTE(id int) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldID), id)) - }) + return predicate.DeviceRequest(sql.FieldLTE(FieldID, id)) } // UserCode applies equality check predicate on the "user_code" field. It's identical to UserCodeEQ. func UserCode(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldUserCode), v)) - }) + return predicate.DeviceRequest(sql.FieldEQ(FieldUserCode, v)) } // DeviceCode applies equality check predicate on the "device_code" field. It's identical to DeviceCodeEQ. func DeviceCode(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceRequest(sql.FieldEQ(FieldDeviceCode, v)) } // ClientID applies equality check predicate on the "client_id" field. It's identical to ClientIDEQ. func ClientID(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClientID), v)) - }) + return predicate.DeviceRequest(sql.FieldEQ(FieldClientID, v)) } // ClientSecret applies equality check predicate on the "client_secret" field. It's identical to ClientSecretEQ. func ClientSecret(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClientSecret), v)) - }) + return predicate.DeviceRequest(sql.FieldEQ(FieldClientSecret, v)) } // Expiry applies equality check predicate on the "expiry" field. It's identical to ExpiryEQ. func Expiry(v time.Time) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldExpiry), v)) - }) + return predicate.DeviceRequest(sql.FieldEQ(FieldExpiry, v)) } // UserCodeEQ applies the EQ predicate on the "user_code" field. func UserCodeEQ(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldUserCode), v)) - }) + return predicate.DeviceRequest(sql.FieldEQ(FieldUserCode, v)) } // UserCodeNEQ applies the NEQ predicate on the "user_code" field. func UserCodeNEQ(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldUserCode), v)) - }) + return predicate.DeviceRequest(sql.FieldNEQ(FieldUserCode, v)) } // UserCodeIn applies the In predicate on the "user_code" field. func UserCodeIn(vs ...string) predicate.DeviceRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldUserCode), v...)) - }) + return predicate.DeviceRequest(sql.FieldIn(FieldUserCode, vs...)) } // UserCodeNotIn applies the NotIn predicate on the "user_code" field. func UserCodeNotIn(vs ...string) predicate.DeviceRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldUserCode), v...)) - }) + return predicate.DeviceRequest(sql.FieldNotIn(FieldUserCode, vs...)) } // UserCodeGT applies the GT predicate on the "user_code" field. func UserCodeGT(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldUserCode), v)) - }) + return predicate.DeviceRequest(sql.FieldGT(FieldUserCode, v)) } // UserCodeGTE applies the GTE predicate on the "user_code" field. func UserCodeGTE(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldUserCode), v)) - }) + return predicate.DeviceRequest(sql.FieldGTE(FieldUserCode, v)) } // UserCodeLT applies the LT predicate on the "user_code" field. func UserCodeLT(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldUserCode), v)) - }) + return predicate.DeviceRequest(sql.FieldLT(FieldUserCode, v)) } // UserCodeLTE applies the LTE predicate on the "user_code" field. func UserCodeLTE(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldUserCode), v)) - }) + return predicate.DeviceRequest(sql.FieldLTE(FieldUserCode, v)) } // UserCodeContains applies the Contains predicate on the "user_code" field. func UserCodeContains(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldUserCode), v)) - }) + return predicate.DeviceRequest(sql.FieldContains(FieldUserCode, v)) } // UserCodeHasPrefix applies the HasPrefix predicate on the "user_code" field. func UserCodeHasPrefix(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldUserCode), v)) - }) + return predicate.DeviceRequest(sql.FieldHasPrefix(FieldUserCode, v)) } // UserCodeHasSuffix applies the HasSuffix predicate on the "user_code" field. func UserCodeHasSuffix(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldUserCode), v)) - }) + return predicate.DeviceRequest(sql.FieldHasSuffix(FieldUserCode, v)) } // UserCodeEqualFold applies the EqualFold predicate on the "user_code" field. func UserCodeEqualFold(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldUserCode), v)) - }) + return predicate.DeviceRequest(sql.FieldEqualFold(FieldUserCode, v)) } // UserCodeContainsFold applies the ContainsFold predicate on the "user_code" field. func UserCodeContainsFold(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldUserCode), v)) - }) + return predicate.DeviceRequest(sql.FieldContainsFold(FieldUserCode, v)) } // DeviceCodeEQ applies the EQ predicate on the "device_code" field. func DeviceCodeEQ(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceRequest(sql.FieldEQ(FieldDeviceCode, v)) } // DeviceCodeNEQ applies the NEQ predicate on the "device_code" field. func DeviceCodeNEQ(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceRequest(sql.FieldNEQ(FieldDeviceCode, v)) } // DeviceCodeIn applies the In predicate on the "device_code" field. func DeviceCodeIn(vs ...string) predicate.DeviceRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldDeviceCode), v...)) - }) + return predicate.DeviceRequest(sql.FieldIn(FieldDeviceCode, vs...)) } // DeviceCodeNotIn applies the NotIn predicate on the "device_code" field. func DeviceCodeNotIn(vs ...string) predicate.DeviceRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldDeviceCode), v...)) - }) + return predicate.DeviceRequest(sql.FieldNotIn(FieldDeviceCode, vs...)) } // DeviceCodeGT applies the GT predicate on the "device_code" field. func DeviceCodeGT(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceRequest(sql.FieldGT(FieldDeviceCode, v)) } // DeviceCodeGTE applies the GTE predicate on the "device_code" field. func DeviceCodeGTE(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceRequest(sql.FieldGTE(FieldDeviceCode, v)) } // DeviceCodeLT applies the LT predicate on the "device_code" field. func DeviceCodeLT(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceRequest(sql.FieldLT(FieldDeviceCode, v)) } // DeviceCodeLTE applies the LTE predicate on the "device_code" field. func DeviceCodeLTE(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceRequest(sql.FieldLTE(FieldDeviceCode, v)) } // DeviceCodeContains applies the Contains predicate on the "device_code" field. func DeviceCodeContains(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceRequest(sql.FieldContains(FieldDeviceCode, v)) } // DeviceCodeHasPrefix applies the HasPrefix predicate on the "device_code" field. func DeviceCodeHasPrefix(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceRequest(sql.FieldHasPrefix(FieldDeviceCode, v)) } // DeviceCodeHasSuffix applies the HasSuffix predicate on the "device_code" field. func DeviceCodeHasSuffix(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceRequest(sql.FieldHasSuffix(FieldDeviceCode, v)) } // DeviceCodeEqualFold applies the EqualFold predicate on the "device_code" field. func DeviceCodeEqualFold(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceRequest(sql.FieldEqualFold(FieldDeviceCode, v)) } // DeviceCodeContainsFold applies the ContainsFold predicate on the "device_code" field. func DeviceCodeContainsFold(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceRequest(sql.FieldContainsFold(FieldDeviceCode, v)) } // ClientIDEQ applies the EQ predicate on the "client_id" field. func ClientIDEQ(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClientID), v)) - }) + return predicate.DeviceRequest(sql.FieldEQ(FieldClientID, v)) } // ClientIDNEQ applies the NEQ predicate on the "client_id" field. func ClientIDNEQ(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClientID), v)) - }) + return predicate.DeviceRequest(sql.FieldNEQ(FieldClientID, v)) } // ClientIDIn applies the In predicate on the "client_id" field. func ClientIDIn(vs ...string) predicate.DeviceRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldClientID), v...)) - }) + return predicate.DeviceRequest(sql.FieldIn(FieldClientID, vs...)) } // ClientIDNotIn applies the NotIn predicate on the "client_id" field. func ClientIDNotIn(vs ...string) predicate.DeviceRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldClientID), v...)) - }) + return predicate.DeviceRequest(sql.FieldNotIn(FieldClientID, vs...)) } // ClientIDGT applies the GT predicate on the "client_id" field. func ClientIDGT(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldClientID), v)) - }) + return predicate.DeviceRequest(sql.FieldGT(FieldClientID, v)) } // ClientIDGTE applies the GTE predicate on the "client_id" field. func ClientIDGTE(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldClientID), v)) - }) + return predicate.DeviceRequest(sql.FieldGTE(FieldClientID, v)) } // ClientIDLT applies the LT predicate on the "client_id" field. func ClientIDLT(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldClientID), v)) - }) + return predicate.DeviceRequest(sql.FieldLT(FieldClientID, v)) } // ClientIDLTE applies the LTE predicate on the "client_id" field. func ClientIDLTE(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldClientID), v)) - }) + return predicate.DeviceRequest(sql.FieldLTE(FieldClientID, v)) } // ClientIDContains applies the Contains predicate on the "client_id" field. func ClientIDContains(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldClientID), v)) - }) + return predicate.DeviceRequest(sql.FieldContains(FieldClientID, v)) } // ClientIDHasPrefix applies the HasPrefix predicate on the "client_id" field. func ClientIDHasPrefix(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldClientID), v)) - }) + return predicate.DeviceRequest(sql.FieldHasPrefix(FieldClientID, v)) } // ClientIDHasSuffix applies the HasSuffix predicate on the "client_id" field. func ClientIDHasSuffix(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldClientID), v)) - }) + return predicate.DeviceRequest(sql.FieldHasSuffix(FieldClientID, v)) } // ClientIDEqualFold applies the EqualFold predicate on the "client_id" field. func ClientIDEqualFold(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldClientID), v)) - }) + return predicate.DeviceRequest(sql.FieldEqualFold(FieldClientID, v)) } // ClientIDContainsFold applies the ContainsFold predicate on the "client_id" field. func ClientIDContainsFold(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldClientID), v)) - }) + return predicate.DeviceRequest(sql.FieldContainsFold(FieldClientID, v)) } // ClientSecretEQ applies the EQ predicate on the "client_secret" field. func ClientSecretEQ(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClientSecret), v)) - }) + return predicate.DeviceRequest(sql.FieldEQ(FieldClientSecret, v)) } // ClientSecretNEQ applies the NEQ predicate on the "client_secret" field. func ClientSecretNEQ(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClientSecret), v)) - }) + return predicate.DeviceRequest(sql.FieldNEQ(FieldClientSecret, v)) } // ClientSecretIn applies the In predicate on the "client_secret" field. func ClientSecretIn(vs ...string) predicate.DeviceRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldClientSecret), v...)) - }) + return predicate.DeviceRequest(sql.FieldIn(FieldClientSecret, vs...)) } // ClientSecretNotIn applies the NotIn predicate on the "client_secret" field. func ClientSecretNotIn(vs ...string) predicate.DeviceRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldClientSecret), v...)) - }) + return predicate.DeviceRequest(sql.FieldNotIn(FieldClientSecret, vs...)) } // ClientSecretGT applies the GT predicate on the "client_secret" field. func ClientSecretGT(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldClientSecret), v)) - }) + return predicate.DeviceRequest(sql.FieldGT(FieldClientSecret, v)) } // ClientSecretGTE applies the GTE predicate on the "client_secret" field. func ClientSecretGTE(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldClientSecret), v)) - }) + return predicate.DeviceRequest(sql.FieldGTE(FieldClientSecret, v)) } // ClientSecretLT applies the LT predicate on the "client_secret" field. func ClientSecretLT(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldClientSecret), v)) - }) + return predicate.DeviceRequest(sql.FieldLT(FieldClientSecret, v)) } // ClientSecretLTE applies the LTE predicate on the "client_secret" field. func ClientSecretLTE(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldClientSecret), v)) - }) + return predicate.DeviceRequest(sql.FieldLTE(FieldClientSecret, v)) } // ClientSecretContains applies the Contains predicate on the "client_secret" field. func ClientSecretContains(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldClientSecret), v)) - }) + return predicate.DeviceRequest(sql.FieldContains(FieldClientSecret, v)) } // ClientSecretHasPrefix applies the HasPrefix predicate on the "client_secret" field. func ClientSecretHasPrefix(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldClientSecret), v)) - }) + return predicate.DeviceRequest(sql.FieldHasPrefix(FieldClientSecret, v)) } // ClientSecretHasSuffix applies the HasSuffix predicate on the "client_secret" field. func ClientSecretHasSuffix(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldClientSecret), v)) - }) + return predicate.DeviceRequest(sql.FieldHasSuffix(FieldClientSecret, v)) } // ClientSecretEqualFold applies the EqualFold predicate on the "client_secret" field. func ClientSecretEqualFold(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldClientSecret), v)) - }) + return predicate.DeviceRequest(sql.FieldEqualFold(FieldClientSecret, v)) } // ClientSecretContainsFold applies the ContainsFold predicate on the "client_secret" field. func ClientSecretContainsFold(v string) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldClientSecret), v)) - }) + return predicate.DeviceRequest(sql.FieldContainsFold(FieldClientSecret, v)) } // ScopesIsNil applies the IsNil predicate on the "scopes" field. func ScopesIsNil() predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.IsNull(s.C(FieldScopes))) - }) + return predicate.DeviceRequest(sql.FieldIsNull(FieldScopes)) } // ScopesNotNil applies the NotNil predicate on the "scopes" field. func ScopesNotNil() predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.NotNull(s.C(FieldScopes))) - }) + return predicate.DeviceRequest(sql.FieldNotNull(FieldScopes)) } // ExpiryEQ applies the EQ predicate on the "expiry" field. func ExpiryEQ(v time.Time) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldExpiry), v)) - }) + return predicate.DeviceRequest(sql.FieldEQ(FieldExpiry, v)) } // ExpiryNEQ applies the NEQ predicate on the "expiry" field. func ExpiryNEQ(v time.Time) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldExpiry), v)) - }) + return predicate.DeviceRequest(sql.FieldNEQ(FieldExpiry, v)) } // ExpiryIn applies the In predicate on the "expiry" field. func ExpiryIn(vs ...time.Time) predicate.DeviceRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldExpiry), v...)) - }) + return predicate.DeviceRequest(sql.FieldIn(FieldExpiry, vs...)) } // ExpiryNotIn applies the NotIn predicate on the "expiry" field. func ExpiryNotIn(vs ...time.Time) predicate.DeviceRequest { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldExpiry), v...)) - }) + return predicate.DeviceRequest(sql.FieldNotIn(FieldExpiry, vs...)) } // ExpiryGT applies the GT predicate on the "expiry" field. func ExpiryGT(v time.Time) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldExpiry), v)) - }) + return predicate.DeviceRequest(sql.FieldGT(FieldExpiry, v)) } // ExpiryGTE applies the GTE predicate on the "expiry" field. func ExpiryGTE(v time.Time) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldExpiry), v)) - }) + return predicate.DeviceRequest(sql.FieldGTE(FieldExpiry, v)) } // ExpiryLT applies the LT predicate on the "expiry" field. func ExpiryLT(v time.Time) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldExpiry), v)) - }) + return predicate.DeviceRequest(sql.FieldLT(FieldExpiry, v)) } // ExpiryLTE applies the LTE predicate on the "expiry" field. func ExpiryLTE(v time.Time) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldExpiry), v)) - }) + return predicate.DeviceRequest(sql.FieldLTE(FieldExpiry, v)) } // And groups predicates with the AND operator between them. func And(predicates ...predicate.DeviceRequest) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for _, p := range predicates { - p(s1) - } - s.Where(s1.P()) - }) + return predicate.DeviceRequest(sql.AndPredicates(predicates...)) } // Or groups predicates with the OR operator between them. func Or(predicates ...predicate.DeviceRequest) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for i, p := range predicates { - if i > 0 { - s1.Or() - } - p(s1) - } - s.Where(s1.P()) - }) + return predicate.DeviceRequest(sql.OrPredicates(predicates...)) } // Not applies the not operator on the given predicate. func Not(p predicate.DeviceRequest) predicate.DeviceRequest { - return predicate.DeviceRequest(func(s *sql.Selector) { - p(s.Not()) - }) + return predicate.DeviceRequest(sql.NotPredicates(p)) } diff --git a/storage/ent/db/devicerequest_create.go b/storage/ent/db/devicerequest_create.go index ae7644ca0c..75a94c1781 100644 --- a/storage/ent/db/devicerequest_create.go +++ b/storage/ent/db/devicerequest_create.go @@ -21,96 +21,54 @@ type DeviceRequestCreate struct { } // SetUserCode sets the "user_code" field. -func (drc *DeviceRequestCreate) SetUserCode(s string) *DeviceRequestCreate { - drc.mutation.SetUserCode(s) - return drc +func (_c *DeviceRequestCreate) SetUserCode(v string) *DeviceRequestCreate { + _c.mutation.SetUserCode(v) + return _c } // SetDeviceCode sets the "device_code" field. -func (drc *DeviceRequestCreate) SetDeviceCode(s string) *DeviceRequestCreate { - drc.mutation.SetDeviceCode(s) - return drc +func (_c *DeviceRequestCreate) SetDeviceCode(v string) *DeviceRequestCreate { + _c.mutation.SetDeviceCode(v) + return _c } // SetClientID sets the "client_id" field. -func (drc *DeviceRequestCreate) SetClientID(s string) *DeviceRequestCreate { - drc.mutation.SetClientID(s) - return drc +func (_c *DeviceRequestCreate) SetClientID(v string) *DeviceRequestCreate { + _c.mutation.SetClientID(v) + return _c } // SetClientSecret sets the "client_secret" field. -func (drc *DeviceRequestCreate) SetClientSecret(s string) *DeviceRequestCreate { - drc.mutation.SetClientSecret(s) - return drc +func (_c *DeviceRequestCreate) SetClientSecret(v string) *DeviceRequestCreate { + _c.mutation.SetClientSecret(v) + return _c } // SetScopes sets the "scopes" field. -func (drc *DeviceRequestCreate) SetScopes(s []string) *DeviceRequestCreate { - drc.mutation.SetScopes(s) - return drc +func (_c *DeviceRequestCreate) SetScopes(v []string) *DeviceRequestCreate { + _c.mutation.SetScopes(v) + return _c } // SetExpiry sets the "expiry" field. -func (drc *DeviceRequestCreate) SetExpiry(t time.Time) *DeviceRequestCreate { - drc.mutation.SetExpiry(t) - return drc +func (_c *DeviceRequestCreate) SetExpiry(v time.Time) *DeviceRequestCreate { + _c.mutation.SetExpiry(v) + return _c } // Mutation returns the DeviceRequestMutation object of the builder. -func (drc *DeviceRequestCreate) Mutation() *DeviceRequestMutation { - return drc.mutation +func (_c *DeviceRequestCreate) Mutation() *DeviceRequestMutation { + return _c.mutation } // Save creates the DeviceRequest in the database. -func (drc *DeviceRequestCreate) Save(ctx context.Context) (*DeviceRequest, error) { - var ( - err error - node *DeviceRequest - ) - if len(drc.hooks) == 0 { - if err = drc.check(); err != nil { - return nil, err - } - node, err = drc.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*DeviceRequestMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = drc.check(); err != nil { - return nil, err - } - drc.mutation = mutation - if node, err = drc.sqlSave(ctx); err != nil { - return nil, err - } - mutation.id = &node.ID - mutation.done = true - return node, err - }) - for i := len(drc.hooks) - 1; i >= 0; i-- { - if drc.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = drc.hooks[i](mut) - } - v, err := mut.Mutate(ctx, drc.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*DeviceRequest) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from DeviceRequestMutation", v) - } - node = nv - } - return node, err +func (_c *DeviceRequestCreate) Save(ctx context.Context) (*DeviceRequest, error) { + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) } // SaveX calls Save and panics if Save returns an error. -func (drc *DeviceRequestCreate) SaveX(ctx context.Context) *DeviceRequest { - v, err := drc.Save(ctx) +func (_c *DeviceRequestCreate) SaveX(ctx context.Context) *DeviceRequest { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -118,61 +76,64 @@ func (drc *DeviceRequestCreate) SaveX(ctx context.Context) *DeviceRequest { } // Exec executes the query. -func (drc *DeviceRequestCreate) Exec(ctx context.Context) error { - _, err := drc.Save(ctx) +func (_c *DeviceRequestCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (drc *DeviceRequestCreate) ExecX(ctx context.Context) { - if err := drc.Exec(ctx); err != nil { +func (_c *DeviceRequestCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (drc *DeviceRequestCreate) check() error { - if _, ok := drc.mutation.UserCode(); !ok { +func (_c *DeviceRequestCreate) check() error { + if _, ok := _c.mutation.UserCode(); !ok { return &ValidationError{Name: "user_code", err: errors.New(`db: missing required field "DeviceRequest.user_code"`)} } - if v, ok := drc.mutation.UserCode(); ok { + if v, ok := _c.mutation.UserCode(); ok { if err := devicerequest.UserCodeValidator(v); err != nil { return &ValidationError{Name: "user_code", err: fmt.Errorf(`db: validator failed for field "DeviceRequest.user_code": %w`, err)} } } - if _, ok := drc.mutation.DeviceCode(); !ok { + if _, ok := _c.mutation.DeviceCode(); !ok { return &ValidationError{Name: "device_code", err: errors.New(`db: missing required field "DeviceRequest.device_code"`)} } - if v, ok := drc.mutation.DeviceCode(); ok { + if v, ok := _c.mutation.DeviceCode(); ok { if err := devicerequest.DeviceCodeValidator(v); err != nil { return &ValidationError{Name: "device_code", err: fmt.Errorf(`db: validator failed for field "DeviceRequest.device_code": %w`, err)} } } - if _, ok := drc.mutation.ClientID(); !ok { + if _, ok := _c.mutation.ClientID(); !ok { return &ValidationError{Name: "client_id", err: errors.New(`db: missing required field "DeviceRequest.client_id"`)} } - if v, ok := drc.mutation.ClientID(); ok { + if v, ok := _c.mutation.ClientID(); ok { if err := devicerequest.ClientIDValidator(v); err != nil { return &ValidationError{Name: "client_id", err: fmt.Errorf(`db: validator failed for field "DeviceRequest.client_id": %w`, err)} } } - if _, ok := drc.mutation.ClientSecret(); !ok { + if _, ok := _c.mutation.ClientSecret(); !ok { return &ValidationError{Name: "client_secret", err: errors.New(`db: missing required field "DeviceRequest.client_secret"`)} } - if v, ok := drc.mutation.ClientSecret(); ok { + if v, ok := _c.mutation.ClientSecret(); ok { if err := devicerequest.ClientSecretValidator(v); err != nil { return &ValidationError{Name: "client_secret", err: fmt.Errorf(`db: validator failed for field "DeviceRequest.client_secret": %w`, err)} } } - if _, ok := drc.mutation.Expiry(); !ok { + if _, ok := _c.mutation.Expiry(); !ok { return &ValidationError{Name: "expiry", err: errors.New(`db: missing required field "DeviceRequest.expiry"`)} } return nil } -func (drc *DeviceRequestCreate) sqlSave(ctx context.Context) (*DeviceRequest, error) { - _node, _spec := drc.createSpec() - if err := sqlgraph.CreateNode(ctx, drc.driver, _spec); err != nil { +func (_c *DeviceRequestCreate) sqlSave(ctx context.Context) (*DeviceRequest, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -180,66 +141,38 @@ func (drc *DeviceRequestCreate) sqlSave(ctx context.Context) (*DeviceRequest, er } id := _spec.ID.Value.(int64) _node.ID = int(id) + _c.mutation.id = &_node.ID + _c.mutation.done = true return _node, nil } -func (drc *DeviceRequestCreate) createSpec() (*DeviceRequest, *sqlgraph.CreateSpec) { +func (_c *DeviceRequestCreate) createSpec() (*DeviceRequest, *sqlgraph.CreateSpec) { var ( - _node = &DeviceRequest{config: drc.config} - _spec = &sqlgraph.CreateSpec{ - Table: devicerequest.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: devicerequest.FieldID, - }, - } + _node = &DeviceRequest{config: _c.config} + _spec = sqlgraph.NewCreateSpec(devicerequest.Table, sqlgraph.NewFieldSpec(devicerequest.FieldID, field.TypeInt)) ) - if value, ok := drc.mutation.UserCode(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicerequest.FieldUserCode, - }) + if value, ok := _c.mutation.UserCode(); ok { + _spec.SetField(devicerequest.FieldUserCode, field.TypeString, value) _node.UserCode = value } - if value, ok := drc.mutation.DeviceCode(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicerequest.FieldDeviceCode, - }) + if value, ok := _c.mutation.DeviceCode(); ok { + _spec.SetField(devicerequest.FieldDeviceCode, field.TypeString, value) _node.DeviceCode = value } - if value, ok := drc.mutation.ClientID(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicerequest.FieldClientID, - }) + if value, ok := _c.mutation.ClientID(); ok { + _spec.SetField(devicerequest.FieldClientID, field.TypeString, value) _node.ClientID = value } - if value, ok := drc.mutation.ClientSecret(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicerequest.FieldClientSecret, - }) + if value, ok := _c.mutation.ClientSecret(); ok { + _spec.SetField(devicerequest.FieldClientSecret, field.TypeString, value) _node.ClientSecret = value } - if value, ok := drc.mutation.Scopes(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: devicerequest.FieldScopes, - }) + if value, ok := _c.mutation.Scopes(); ok { + _spec.SetField(devicerequest.FieldScopes, field.TypeJSON, value) _node.Scopes = value } - if value, ok := drc.mutation.Expiry(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: devicerequest.FieldExpiry, - }) + if value, ok := _c.mutation.Expiry(); ok { + _spec.SetField(devicerequest.FieldExpiry, field.TypeTime, value) _node.Expiry = value } return _node, _spec @@ -248,17 +181,21 @@ func (drc *DeviceRequestCreate) createSpec() (*DeviceRequest, *sqlgraph.CreateSp // DeviceRequestCreateBulk is the builder for creating many DeviceRequest entities in bulk. type DeviceRequestCreateBulk struct { config + err error builders []*DeviceRequestCreate } // Save creates the DeviceRequest entities in the database. -func (drcb *DeviceRequestCreateBulk) Save(ctx context.Context) ([]*DeviceRequest, error) { - specs := make([]*sqlgraph.CreateSpec, len(drcb.builders)) - nodes := make([]*DeviceRequest, len(drcb.builders)) - mutators := make([]Mutator, len(drcb.builders)) - for i := range drcb.builders { +func (_c *DeviceRequestCreateBulk) Save(ctx context.Context) ([]*DeviceRequest, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*DeviceRequest, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { func(i int, root context.Context) { - builder := drcb.builders[i] + builder := _c.builders[i] var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { mutation, ok := m.(*DeviceRequestMutation) if !ok { @@ -268,14 +205,14 @@ func (drcb *DeviceRequestCreateBulk) Save(ctx context.Context) ([]*DeviceRequest return nil, err } builder.mutation = mutation - nodes[i], specs[i] = builder.createSpec() var err error + nodes[i], specs[i] = builder.createSpec() if i < len(mutators)-1 { - _, err = mutators[i+1].Mutate(root, drcb.builders[i+1].mutation) + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} // Invoke the actual operation on the latest mutation in the chain. - if err = sqlgraph.BatchCreate(ctx, drcb.driver, spec); err != nil { + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -299,7 +236,7 @@ func (drcb *DeviceRequestCreateBulk) Save(ctx context.Context) ([]*DeviceRequest }(i, ctx) } if len(mutators) > 0 { - if _, err := mutators[0].Mutate(ctx, drcb.builders[0].mutation); err != nil { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { return nil, err } } @@ -307,8 +244,8 @@ func (drcb *DeviceRequestCreateBulk) Save(ctx context.Context) ([]*DeviceRequest } // SaveX is like Save, but panics if an error occurs. -func (drcb *DeviceRequestCreateBulk) SaveX(ctx context.Context) []*DeviceRequest { - v, err := drcb.Save(ctx) +func (_c *DeviceRequestCreateBulk) SaveX(ctx context.Context) []*DeviceRequest { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -316,14 +253,14 @@ func (drcb *DeviceRequestCreateBulk) SaveX(ctx context.Context) []*DeviceRequest } // Exec executes the query. -func (drcb *DeviceRequestCreateBulk) Exec(ctx context.Context) error { - _, err := drcb.Save(ctx) +func (_c *DeviceRequestCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (drcb *DeviceRequestCreateBulk) ExecX(ctx context.Context) { - if err := drcb.Exec(ctx); err != nil { +func (_c *DeviceRequestCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } diff --git a/storage/ent/db/devicerequest_delete.go b/storage/ent/db/devicerequest_delete.go index 635a8a498d..97ddacf72e 100644 --- a/storage/ent/db/devicerequest_delete.go +++ b/storage/ent/db/devicerequest_delete.go @@ -4,7 +4,6 @@ package db import ( "context" - "fmt" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" @@ -21,84 +20,56 @@ type DeviceRequestDelete struct { } // Where appends a list predicates to the DeviceRequestDelete builder. -func (drd *DeviceRequestDelete) Where(ps ...predicate.DeviceRequest) *DeviceRequestDelete { - drd.mutation.Where(ps...) - return drd +func (_d *DeviceRequestDelete) Where(ps ...predicate.DeviceRequest) *DeviceRequestDelete { + _d.mutation.Where(ps...) + return _d } // Exec executes the deletion query and returns how many vertices were deleted. -func (drd *DeviceRequestDelete) Exec(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(drd.hooks) == 0 { - affected, err = drd.sqlExec(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*DeviceRequestMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - drd.mutation = mutation - affected, err = drd.sqlExec(ctx) - mutation.done = true - return affected, err - }) - for i := len(drd.hooks) - 1; i >= 0; i-- { - if drd.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = drd.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, drd.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_d *DeviceRequestDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) } // ExecX is like Exec, but panics if an error occurs. -func (drd *DeviceRequestDelete) ExecX(ctx context.Context) int { - n, err := drd.Exec(ctx) +func (_d *DeviceRequestDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) if err != nil { panic(err) } return n } -func (drd *DeviceRequestDelete) sqlExec(ctx context.Context) (int, error) { - _spec := &sqlgraph.DeleteSpec{ - Node: &sqlgraph.NodeSpec{ - Table: devicerequest.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: devicerequest.FieldID, - }, - }, - } - if ps := drd.mutation.predicates; len(ps) > 0 { +func (_d *DeviceRequestDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(devicerequest.Table, sqlgraph.NewFieldSpec(devicerequest.FieldID, field.TypeInt)) + if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - affected, err := sqlgraph.DeleteNodes(ctx, drd.driver, _spec) + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) if err != nil && sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } + _d.mutation.done = true return affected, err } // DeviceRequestDeleteOne is the builder for deleting a single DeviceRequest entity. type DeviceRequestDeleteOne struct { - drd *DeviceRequestDelete + _d *DeviceRequestDelete +} + +// Where appends a list predicates to the DeviceRequestDelete builder. +func (_d *DeviceRequestDeleteOne) Where(ps ...predicate.DeviceRequest) *DeviceRequestDeleteOne { + _d._d.mutation.Where(ps...) + return _d } // Exec executes the deletion query. -func (drdo *DeviceRequestDeleteOne) Exec(ctx context.Context) error { - n, err := drdo.drd.Exec(ctx) +func (_d *DeviceRequestDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) switch { case err != nil: return err @@ -110,6 +81,8 @@ func (drdo *DeviceRequestDeleteOne) Exec(ctx context.Context) error { } // ExecX is like Exec, but panics if an error occurs. -func (drdo *DeviceRequestDeleteOne) ExecX(ctx context.Context) { - drdo.drd.ExecX(ctx) +func (_d *DeviceRequestDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } } diff --git a/storage/ent/db/devicerequest_query.go b/storage/ent/db/devicerequest_query.go index 3fd43dd89d..93093d2a1c 100644 --- a/storage/ent/db/devicerequest_query.go +++ b/storage/ent/db/devicerequest_query.go @@ -7,6 +7,7 @@ import ( "fmt" "math" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" @@ -17,11 +18,9 @@ import ( // DeviceRequestQuery is the builder for querying DeviceRequest entities. type DeviceRequestQuery struct { config - limit *int - offset *int - unique *bool - order []OrderFunc - fields []string + ctx *QueryContext + order []devicerequest.OrderOption + inters []Interceptor predicates []predicate.DeviceRequest // intermediate query (i.e. traversal path). sql *sql.Selector @@ -29,40 +28,40 @@ type DeviceRequestQuery struct { } // Where adds a new predicate for the DeviceRequestQuery builder. -func (drq *DeviceRequestQuery) Where(ps ...predicate.DeviceRequest) *DeviceRequestQuery { - drq.predicates = append(drq.predicates, ps...) - return drq +func (_q *DeviceRequestQuery) Where(ps ...predicate.DeviceRequest) *DeviceRequestQuery { + _q.predicates = append(_q.predicates, ps...) + return _q } -// Limit adds a limit step to the query. -func (drq *DeviceRequestQuery) Limit(limit int) *DeviceRequestQuery { - drq.limit = &limit - return drq +// Limit the number of records to be returned by this query. +func (_q *DeviceRequestQuery) Limit(limit int) *DeviceRequestQuery { + _q.ctx.Limit = &limit + return _q } -// Offset adds an offset step to the query. -func (drq *DeviceRequestQuery) Offset(offset int) *DeviceRequestQuery { - drq.offset = &offset - return drq +// Offset to start from. +func (_q *DeviceRequestQuery) Offset(offset int) *DeviceRequestQuery { + _q.ctx.Offset = &offset + return _q } // Unique configures the query builder to filter duplicate records on query. // By default, unique is set to true, and can be disabled using this method. -func (drq *DeviceRequestQuery) Unique(unique bool) *DeviceRequestQuery { - drq.unique = &unique - return drq +func (_q *DeviceRequestQuery) Unique(unique bool) *DeviceRequestQuery { + _q.ctx.Unique = &unique + return _q } -// Order adds an order step to the query. -func (drq *DeviceRequestQuery) Order(o ...OrderFunc) *DeviceRequestQuery { - drq.order = append(drq.order, o...) - return drq +// Order specifies how the records should be ordered. +func (_q *DeviceRequestQuery) Order(o ...devicerequest.OrderOption) *DeviceRequestQuery { + _q.order = append(_q.order, o...) + return _q } // First returns the first DeviceRequest entity from the query. // Returns a *NotFoundError when no DeviceRequest was found. -func (drq *DeviceRequestQuery) First(ctx context.Context) (*DeviceRequest, error) { - nodes, err := drq.Limit(1).All(ctx) +func (_q *DeviceRequestQuery) First(ctx context.Context) (*DeviceRequest, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) if err != nil { return nil, err } @@ -73,8 +72,8 @@ func (drq *DeviceRequestQuery) First(ctx context.Context) (*DeviceRequest, error } // FirstX is like First, but panics if an error occurs. -func (drq *DeviceRequestQuery) FirstX(ctx context.Context) *DeviceRequest { - node, err := drq.First(ctx) +func (_q *DeviceRequestQuery) FirstX(ctx context.Context) *DeviceRequest { + node, err := _q.First(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -83,9 +82,9 @@ func (drq *DeviceRequestQuery) FirstX(ctx context.Context) *DeviceRequest { // FirstID returns the first DeviceRequest ID from the query. // Returns a *NotFoundError when no DeviceRequest ID was found. -func (drq *DeviceRequestQuery) FirstID(ctx context.Context) (id int, err error) { +func (_q *DeviceRequestQuery) FirstID(ctx context.Context) (id int, err error) { var ids []int - if ids, err = drq.Limit(1).IDs(ctx); err != nil { + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { return } if len(ids) == 0 { @@ -96,8 +95,8 @@ func (drq *DeviceRequestQuery) FirstID(ctx context.Context) (id int, err error) } // FirstIDX is like FirstID, but panics if an error occurs. -func (drq *DeviceRequestQuery) FirstIDX(ctx context.Context) int { - id, err := drq.FirstID(ctx) +func (_q *DeviceRequestQuery) FirstIDX(ctx context.Context) int { + id, err := _q.FirstID(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -107,8 +106,8 @@ func (drq *DeviceRequestQuery) FirstIDX(ctx context.Context) int { // Only returns a single DeviceRequest entity found by the query, ensuring it only returns one. // Returns a *NotSingularError when more than one DeviceRequest entity is found. // Returns a *NotFoundError when no DeviceRequest entities are found. -func (drq *DeviceRequestQuery) Only(ctx context.Context) (*DeviceRequest, error) { - nodes, err := drq.Limit(2).All(ctx) +func (_q *DeviceRequestQuery) Only(ctx context.Context) (*DeviceRequest, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) if err != nil { return nil, err } @@ -123,8 +122,8 @@ func (drq *DeviceRequestQuery) Only(ctx context.Context) (*DeviceRequest, error) } // OnlyX is like Only, but panics if an error occurs. -func (drq *DeviceRequestQuery) OnlyX(ctx context.Context) *DeviceRequest { - node, err := drq.Only(ctx) +func (_q *DeviceRequestQuery) OnlyX(ctx context.Context) *DeviceRequest { + node, err := _q.Only(ctx) if err != nil { panic(err) } @@ -134,9 +133,9 @@ func (drq *DeviceRequestQuery) OnlyX(ctx context.Context) *DeviceRequest { // OnlyID is like Only, but returns the only DeviceRequest ID in the query. // Returns a *NotSingularError when more than one DeviceRequest ID is found. // Returns a *NotFoundError when no entities are found. -func (drq *DeviceRequestQuery) OnlyID(ctx context.Context) (id int, err error) { +func (_q *DeviceRequestQuery) OnlyID(ctx context.Context) (id int, err error) { var ids []int - if ids, err = drq.Limit(2).IDs(ctx); err != nil { + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { return } switch len(ids) { @@ -151,8 +150,8 @@ func (drq *DeviceRequestQuery) OnlyID(ctx context.Context) (id int, err error) { } // OnlyIDX is like OnlyID, but panics if an error occurs. -func (drq *DeviceRequestQuery) OnlyIDX(ctx context.Context) int { - id, err := drq.OnlyID(ctx) +func (_q *DeviceRequestQuery) OnlyIDX(ctx context.Context) int { + id, err := _q.OnlyID(ctx) if err != nil { panic(err) } @@ -160,16 +159,18 @@ func (drq *DeviceRequestQuery) OnlyIDX(ctx context.Context) int { } // All executes the query and returns a list of DeviceRequests. -func (drq *DeviceRequestQuery) All(ctx context.Context) ([]*DeviceRequest, error) { - if err := drq.prepareQuery(ctx); err != nil { +func (_q *DeviceRequestQuery) All(ctx context.Context) ([]*DeviceRequest, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { return nil, err } - return drq.sqlAll(ctx) + qr := querierAll[[]*DeviceRequest, *DeviceRequestQuery]() + return withInterceptors[[]*DeviceRequest](ctx, _q, qr, _q.inters) } // AllX is like All, but panics if an error occurs. -func (drq *DeviceRequestQuery) AllX(ctx context.Context) []*DeviceRequest { - nodes, err := drq.All(ctx) +func (_q *DeviceRequestQuery) AllX(ctx context.Context) []*DeviceRequest { + nodes, err := _q.All(ctx) if err != nil { panic(err) } @@ -177,17 +178,20 @@ func (drq *DeviceRequestQuery) AllX(ctx context.Context) []*DeviceRequest { } // IDs executes the query and returns a list of DeviceRequest IDs. -func (drq *DeviceRequestQuery) IDs(ctx context.Context) ([]int, error) { - var ids []int - if err := drq.Select(devicerequest.FieldID).Scan(ctx, &ids); err != nil { +func (_q *DeviceRequestQuery) IDs(ctx context.Context) (ids []int, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(devicerequest.FieldID).Scan(ctx, &ids); err != nil { return nil, err } return ids, nil } // IDsX is like IDs, but panics if an error occurs. -func (drq *DeviceRequestQuery) IDsX(ctx context.Context) []int { - ids, err := drq.IDs(ctx) +func (_q *DeviceRequestQuery) IDsX(ctx context.Context) []int { + ids, err := _q.IDs(ctx) if err != nil { panic(err) } @@ -195,16 +199,17 @@ func (drq *DeviceRequestQuery) IDsX(ctx context.Context) []int { } // Count returns the count of the given query. -func (drq *DeviceRequestQuery) Count(ctx context.Context) (int, error) { - if err := drq.prepareQuery(ctx); err != nil { +func (_q *DeviceRequestQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { return 0, err } - return drq.sqlCount(ctx) + return withInterceptors[int](ctx, _q, querierCount[*DeviceRequestQuery](), _q.inters) } // CountX is like Count, but panics if an error occurs. -func (drq *DeviceRequestQuery) CountX(ctx context.Context) int { - count, err := drq.Count(ctx) +func (_q *DeviceRequestQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) if err != nil { panic(err) } @@ -212,16 +217,21 @@ func (drq *DeviceRequestQuery) CountX(ctx context.Context) int { } // Exist returns true if the query has elements in the graph. -func (drq *DeviceRequestQuery) Exist(ctx context.Context) (bool, error) { - if err := drq.prepareQuery(ctx); err != nil { - return false, err +func (_q *DeviceRequestQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("db: check existence: %w", err) + default: + return true, nil } - return drq.sqlExist(ctx) } // ExistX is like Exist, but panics if an error occurs. -func (drq *DeviceRequestQuery) ExistX(ctx context.Context) bool { - exist, err := drq.Exist(ctx) +func (_q *DeviceRequestQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) if err != nil { panic(err) } @@ -230,20 +240,19 @@ func (drq *DeviceRequestQuery) ExistX(ctx context.Context) bool { // Clone returns a duplicate of the DeviceRequestQuery builder, including all associated steps. It can be // used to prepare common query builders and use them differently after the clone is made. -func (drq *DeviceRequestQuery) Clone() *DeviceRequestQuery { - if drq == nil { +func (_q *DeviceRequestQuery) Clone() *DeviceRequestQuery { + if _q == nil { return nil } return &DeviceRequestQuery{ - config: drq.config, - limit: drq.limit, - offset: drq.offset, - order: append([]OrderFunc{}, drq.order...), - predicates: append([]predicate.DeviceRequest{}, drq.predicates...), + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]devicerequest.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.DeviceRequest{}, _q.predicates...), // clone intermediate query. - sql: drq.sql.Clone(), - path: drq.path, - unique: drq.unique, + sql: _q.sql.Clone(), + path: _q.path, } } @@ -261,18 +270,12 @@ func (drq *DeviceRequestQuery) Clone() *DeviceRequestQuery { // GroupBy(devicerequest.FieldUserCode). // Aggregate(db.Count()). // Scan(ctx, &v) -// -func (drq *DeviceRequestQuery) GroupBy(field string, fields ...string) *DeviceRequestGroupBy { - grbuild := &DeviceRequestGroupBy{config: drq.config} - grbuild.fields = append([]string{field}, fields...) - grbuild.path = func(ctx context.Context) (prev *sql.Selector, err error) { - if err := drq.prepareQuery(ctx); err != nil { - return nil, err - } - return drq.sqlQuery(ctx), nil - } +func (_q *DeviceRequestQuery) GroupBy(field string, fields ...string) *DeviceRequestGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &DeviceRequestGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields grbuild.label = devicerequest.Label - grbuild.flds, grbuild.scan = &grbuild.fields, grbuild.Scan + grbuild.scan = grbuild.Scan return grbuild } @@ -288,48 +291,62 @@ func (drq *DeviceRequestQuery) GroupBy(field string, fields ...string) *DeviceRe // client.DeviceRequest.Query(). // Select(devicerequest.FieldUserCode). // Scan(ctx, &v) -// -func (drq *DeviceRequestQuery) Select(fields ...string) *DeviceRequestSelect { - drq.fields = append(drq.fields, fields...) - selbuild := &DeviceRequestSelect{DeviceRequestQuery: drq} - selbuild.label = devicerequest.Label - selbuild.flds, selbuild.scan = &drq.fields, selbuild.Scan - return selbuild +func (_q *DeviceRequestQuery) Select(fields ...string) *DeviceRequestSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &DeviceRequestSelect{DeviceRequestQuery: _q} + sbuild.label = devicerequest.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a DeviceRequestSelect configured with the given aggregations. +func (_q *DeviceRequestQuery) Aggregate(fns ...AggregateFunc) *DeviceRequestSelect { + return _q.Select().Aggregate(fns...) } -func (drq *DeviceRequestQuery) prepareQuery(ctx context.Context) error { - for _, f := range drq.fields { +func (_q *DeviceRequestQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("db: uninitialized interceptor (forgotten import db/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { if !devicerequest.ValidColumn(f) { return &ValidationError{Name: f, err: fmt.Errorf("db: invalid field %q for query", f)} } } - if drq.path != nil { - prev, err := drq.path(ctx) + if _q.path != nil { + prev, err := _q.path(ctx) if err != nil { return err } - drq.sql = prev + _q.sql = prev } return nil } -func (drq *DeviceRequestQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*DeviceRequest, error) { +func (_q *DeviceRequestQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*DeviceRequest, error) { var ( nodes = []*DeviceRequest{} - _spec = drq.querySpec() + _spec = _q.querySpec() ) - _spec.ScanValues = func(columns []string) ([]interface{}, error) { + _spec.ScanValues = func(columns []string) ([]any, error) { return (*DeviceRequest).scanValues(nil, columns) } - _spec.Assign = func(columns []string, values []interface{}) error { - node := &DeviceRequest{config: drq.config} + _spec.Assign = func(columns []string, values []any) error { + node := &DeviceRequest{config: _q.config} nodes = append(nodes, node) return node.assignValues(columns, values) } for i := range hooks { hooks[i](ctx, _spec) } - if err := sqlgraph.QueryNodes(ctx, drq.driver, _spec); err != nil { + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { return nil, err } if len(nodes) == 0 { @@ -338,40 +355,24 @@ func (drq *DeviceRequestQuery) sqlAll(ctx context.Context, hooks ...queryHook) ( return nodes, nil } -func (drq *DeviceRequestQuery) sqlCount(ctx context.Context) (int, error) { - _spec := drq.querySpec() - _spec.Node.Columns = drq.fields - if len(drq.fields) > 0 { - _spec.Unique = drq.unique != nil && *drq.unique - } - return sqlgraph.CountNodes(ctx, drq.driver, _spec) -} - -func (drq *DeviceRequestQuery) sqlExist(ctx context.Context) (bool, error) { - n, err := drq.sqlCount(ctx) - if err != nil { - return false, fmt.Errorf("db: check existence: %w", err) +func (_q *DeviceRequestQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique } - return n > 0, nil + return sqlgraph.CountNodes(ctx, _q.driver, _spec) } -func (drq *DeviceRequestQuery) querySpec() *sqlgraph.QuerySpec { - _spec := &sqlgraph.QuerySpec{ - Node: &sqlgraph.NodeSpec{ - Table: devicerequest.Table, - Columns: devicerequest.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: devicerequest.FieldID, - }, - }, - From: drq.sql, - Unique: true, - } - if unique := drq.unique; unique != nil { +func (_q *DeviceRequestQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(devicerequest.Table, devicerequest.Columns, sqlgraph.NewFieldSpec(devicerequest.FieldID, field.TypeInt)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true } - if fields := drq.fields; len(fields) > 0 { + if fields := _q.ctx.Fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, devicerequest.FieldID) for i := range fields { @@ -380,20 +381,20 @@ func (drq *DeviceRequestQuery) querySpec() *sqlgraph.QuerySpec { } } } - if ps := drq.predicates; len(ps) > 0 { + if ps := _q.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if limit := drq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { _spec.Limit = *limit } - if offset := drq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { _spec.Offset = *offset } - if ps := drq.order; len(ps) > 0 { + if ps := _q.order; len(ps) > 0 { _spec.Order = func(selector *sql.Selector) { for i := range ps { ps[i](selector) @@ -403,33 +404,33 @@ func (drq *DeviceRequestQuery) querySpec() *sqlgraph.QuerySpec { return _spec } -func (drq *DeviceRequestQuery) sqlQuery(ctx context.Context) *sql.Selector { - builder := sql.Dialect(drq.driver.Dialect()) +func (_q *DeviceRequestQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) t1 := builder.Table(devicerequest.Table) - columns := drq.fields + columns := _q.ctx.Fields if len(columns) == 0 { columns = devicerequest.Columns } selector := builder.Select(t1.Columns(columns...)...).From(t1) - if drq.sql != nil { - selector = drq.sql + if _q.sql != nil { + selector = _q.sql selector.Select(selector.Columns(columns...)...) } - if drq.unique != nil && *drq.unique { + if _q.ctx.Unique != nil && *_q.ctx.Unique { selector.Distinct() } - for _, p := range drq.predicates { + for _, p := range _q.predicates { p(selector) } - for _, p := range drq.order { + for _, p := range _q.order { p(selector) } - if offset := drq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { // limit is mandatory for offset clause. We start // with default value, and override it below if needed. selector.Offset(*offset).Limit(math.MaxInt32) } - if limit := drq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { selector.Limit(*limit) } return selector @@ -437,90 +438,88 @@ func (drq *DeviceRequestQuery) sqlQuery(ctx context.Context) *sql.Selector { // DeviceRequestGroupBy is the group-by builder for DeviceRequest entities. type DeviceRequestGroupBy struct { - config selector - fields []string - fns []AggregateFunc - // intermediate query (i.e. traversal path). - sql *sql.Selector - path func(context.Context) (*sql.Selector, error) + build *DeviceRequestQuery } // Aggregate adds the given aggregation functions to the group-by query. -func (drgb *DeviceRequestGroupBy) Aggregate(fns ...AggregateFunc) *DeviceRequestGroupBy { - drgb.fns = append(drgb.fns, fns...) - return drgb +func (_g *DeviceRequestGroupBy) Aggregate(fns ...AggregateFunc) *DeviceRequestGroupBy { + _g.fns = append(_g.fns, fns...) + return _g } -// Scan applies the group-by query and scans the result into the given value. -func (drgb *DeviceRequestGroupBy) Scan(ctx context.Context, v interface{}) error { - query, err := drgb.path(ctx) - if err != nil { +// Scan applies the selector query and scans the result into the given value. +func (_g *DeviceRequestGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { return err } - drgb.sql = query - return drgb.sqlScan(ctx, v) + return scanWithInterceptors[*DeviceRequestQuery, *DeviceRequestGroupBy](ctx, _g.build, _g, _g.build.inters, v) } -func (drgb *DeviceRequestGroupBy) sqlScan(ctx context.Context, v interface{}) error { - for _, f := range drgb.fields { - if !devicerequest.ValidColumn(f) { - return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)} +func (_g *DeviceRequestGroupBy) sqlScan(ctx context.Context, root *DeviceRequestQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) } + columns = append(columns, aggregation...) + selector.Select(columns...) } - selector := drgb.sqlQuery() + selector.GroupBy(selector.Columns(*_g.flds...)...) if err := selector.Err(); err != nil { return err } rows := &sql.Rows{} query, args := selector.Query() - if err := drgb.driver.Query(ctx, query, args, rows); err != nil { + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() return sql.ScanSlice(rows, v) } -func (drgb *DeviceRequestGroupBy) sqlQuery() *sql.Selector { - selector := drgb.sql.Select() - aggregation := make([]string, 0, len(drgb.fns)) - for _, fn := range drgb.fns { - aggregation = append(aggregation, fn(selector)) - } - // If no columns were selected in a custom aggregation function, the default - // selection is the fields used for "group-by", and the aggregation functions. - if len(selector.SelectedColumns()) == 0 { - columns := make([]string, 0, len(drgb.fields)+len(drgb.fns)) - for _, f := range drgb.fields { - columns = append(columns, selector.C(f)) - } - columns = append(columns, aggregation...) - selector.Select(columns...) - } - return selector.GroupBy(selector.Columns(drgb.fields...)...) -} - // DeviceRequestSelect is the builder for selecting fields of DeviceRequest entities. type DeviceRequestSelect struct { *DeviceRequestQuery selector - // intermediate query (i.e. traversal path). - sql *sql.Selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *DeviceRequestSelect) Aggregate(fns ...AggregateFunc) *DeviceRequestSelect { + _s.fns = append(_s.fns, fns...) + return _s } // Scan applies the selector query and scans the result into the given value. -func (drs *DeviceRequestSelect) Scan(ctx context.Context, v interface{}) error { - if err := drs.prepareQuery(ctx); err != nil { +func (_s *DeviceRequestSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { return err } - drs.sql = drs.DeviceRequestQuery.sqlQuery(ctx) - return drs.sqlScan(ctx, v) + return scanWithInterceptors[*DeviceRequestQuery, *DeviceRequestSelect](ctx, _s.DeviceRequestQuery, _s, _s.inters, v) } -func (drs *DeviceRequestSelect) sqlScan(ctx context.Context, v interface{}) error { +func (_s *DeviceRequestSelect) sqlScan(ctx context.Context, root *DeviceRequestQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } rows := &sql.Rows{} - query, args := drs.sql.Query() - if err := drs.driver.Query(ctx, query, args, rows); err != nil { + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() diff --git a/storage/ent/db/devicerequest_update.go b/storage/ent/db/devicerequest_update.go index 2bf38af697..9447f4e532 100644 --- a/storage/ent/db/devicerequest_update.go +++ b/storage/ent/db/devicerequest_update.go @@ -10,6 +10,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/dialect/sql/sqljson" "entgo.io/ent/schema/field" "github.com/dexidp/dex/storage/ent/db/devicerequest" "github.com/dexidp/dex/storage/ent/db/predicate" @@ -23,99 +24,112 @@ type DeviceRequestUpdate struct { } // Where appends a list predicates to the DeviceRequestUpdate builder. -func (dru *DeviceRequestUpdate) Where(ps ...predicate.DeviceRequest) *DeviceRequestUpdate { - dru.mutation.Where(ps...) - return dru +func (_u *DeviceRequestUpdate) Where(ps ...predicate.DeviceRequest) *DeviceRequestUpdate { + _u.mutation.Where(ps...) + return _u } // SetUserCode sets the "user_code" field. -func (dru *DeviceRequestUpdate) SetUserCode(s string) *DeviceRequestUpdate { - dru.mutation.SetUserCode(s) - return dru +func (_u *DeviceRequestUpdate) SetUserCode(v string) *DeviceRequestUpdate { + _u.mutation.SetUserCode(v) + return _u +} + +// SetNillableUserCode sets the "user_code" field if the given value is not nil. +func (_u *DeviceRequestUpdate) SetNillableUserCode(v *string) *DeviceRequestUpdate { + if v != nil { + _u.SetUserCode(*v) + } + return _u } // SetDeviceCode sets the "device_code" field. -func (dru *DeviceRequestUpdate) SetDeviceCode(s string) *DeviceRequestUpdate { - dru.mutation.SetDeviceCode(s) - return dru +func (_u *DeviceRequestUpdate) SetDeviceCode(v string) *DeviceRequestUpdate { + _u.mutation.SetDeviceCode(v) + return _u +} + +// SetNillableDeviceCode sets the "device_code" field if the given value is not nil. +func (_u *DeviceRequestUpdate) SetNillableDeviceCode(v *string) *DeviceRequestUpdate { + if v != nil { + _u.SetDeviceCode(*v) + } + return _u } // SetClientID sets the "client_id" field. -func (dru *DeviceRequestUpdate) SetClientID(s string) *DeviceRequestUpdate { - dru.mutation.SetClientID(s) - return dru +func (_u *DeviceRequestUpdate) SetClientID(v string) *DeviceRequestUpdate { + _u.mutation.SetClientID(v) + return _u +} + +// SetNillableClientID sets the "client_id" field if the given value is not nil. +func (_u *DeviceRequestUpdate) SetNillableClientID(v *string) *DeviceRequestUpdate { + if v != nil { + _u.SetClientID(*v) + } + return _u } // SetClientSecret sets the "client_secret" field. -func (dru *DeviceRequestUpdate) SetClientSecret(s string) *DeviceRequestUpdate { - dru.mutation.SetClientSecret(s) - return dru +func (_u *DeviceRequestUpdate) SetClientSecret(v string) *DeviceRequestUpdate { + _u.mutation.SetClientSecret(v) + return _u +} + +// SetNillableClientSecret sets the "client_secret" field if the given value is not nil. +func (_u *DeviceRequestUpdate) SetNillableClientSecret(v *string) *DeviceRequestUpdate { + if v != nil { + _u.SetClientSecret(*v) + } + return _u } // SetScopes sets the "scopes" field. -func (dru *DeviceRequestUpdate) SetScopes(s []string) *DeviceRequestUpdate { - dru.mutation.SetScopes(s) - return dru +func (_u *DeviceRequestUpdate) SetScopes(v []string) *DeviceRequestUpdate { + _u.mutation.SetScopes(v) + return _u +} + +// AppendScopes appends value to the "scopes" field. +func (_u *DeviceRequestUpdate) AppendScopes(v []string) *DeviceRequestUpdate { + _u.mutation.AppendScopes(v) + return _u } // ClearScopes clears the value of the "scopes" field. -func (dru *DeviceRequestUpdate) ClearScopes() *DeviceRequestUpdate { - dru.mutation.ClearScopes() - return dru +func (_u *DeviceRequestUpdate) ClearScopes() *DeviceRequestUpdate { + _u.mutation.ClearScopes() + return _u } // SetExpiry sets the "expiry" field. -func (dru *DeviceRequestUpdate) SetExpiry(t time.Time) *DeviceRequestUpdate { - dru.mutation.SetExpiry(t) - return dru +func (_u *DeviceRequestUpdate) SetExpiry(v time.Time) *DeviceRequestUpdate { + _u.mutation.SetExpiry(v) + return _u +} + +// SetNillableExpiry sets the "expiry" field if the given value is not nil. +func (_u *DeviceRequestUpdate) SetNillableExpiry(v *time.Time) *DeviceRequestUpdate { + if v != nil { + _u.SetExpiry(*v) + } + return _u } // Mutation returns the DeviceRequestMutation object of the builder. -func (dru *DeviceRequestUpdate) Mutation() *DeviceRequestMutation { - return dru.mutation +func (_u *DeviceRequestUpdate) Mutation() *DeviceRequestMutation { + return _u.mutation } // Save executes the query and returns the number of nodes affected by the update operation. -func (dru *DeviceRequestUpdate) Save(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(dru.hooks) == 0 { - if err = dru.check(); err != nil { - return 0, err - } - affected, err = dru.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*DeviceRequestMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = dru.check(); err != nil { - return 0, err - } - dru.mutation = mutation - affected, err = dru.sqlSave(ctx) - mutation.done = true - return affected, err - }) - for i := len(dru.hooks) - 1; i >= 0; i-- { - if dru.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = dru.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, dru.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_u *DeviceRequestUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (dru *DeviceRequestUpdate) SaveX(ctx context.Context) int { - affected, err := dru.Save(ctx) +func (_u *DeviceRequestUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) if err != nil { panic(err) } @@ -123,36 +137,36 @@ func (dru *DeviceRequestUpdate) SaveX(ctx context.Context) int { } // Exec executes the query. -func (dru *DeviceRequestUpdate) Exec(ctx context.Context) error { - _, err := dru.Save(ctx) +func (_u *DeviceRequestUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (dru *DeviceRequestUpdate) ExecX(ctx context.Context) { - if err := dru.Exec(ctx); err != nil { +func (_u *DeviceRequestUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (dru *DeviceRequestUpdate) check() error { - if v, ok := dru.mutation.UserCode(); ok { +func (_u *DeviceRequestUpdate) check() error { + if v, ok := _u.mutation.UserCode(); ok { if err := devicerequest.UserCodeValidator(v); err != nil { return &ValidationError{Name: "user_code", err: fmt.Errorf(`db: validator failed for field "DeviceRequest.user_code": %w`, err)} } } - if v, ok := dru.mutation.DeviceCode(); ok { + if v, ok := _u.mutation.DeviceCode(); ok { if err := devicerequest.DeviceCodeValidator(v); err != nil { return &ValidationError{Name: "device_code", err: fmt.Errorf(`db: validator failed for field "DeviceRequest.device_code": %w`, err)} } } - if v, ok := dru.mutation.ClientID(); ok { + if v, ok := _u.mutation.ClientID(); ok { if err := devicerequest.ClientIDValidator(v); err != nil { return &ValidationError{Name: "client_id", err: fmt.Errorf(`db: validator failed for field "DeviceRequest.client_id": %w`, err)} } } - if v, ok := dru.mutation.ClientSecret(); ok { + if v, ok := _u.mutation.ClientSecret(); ok { if err := devicerequest.ClientSecretValidator(v); err != nil { return &ValidationError{Name: "client_secret", err: fmt.Errorf(`db: validator failed for field "DeviceRequest.client_secret": %w`, err)} } @@ -160,73 +174,45 @@ func (dru *DeviceRequestUpdate) check() error { return nil } -func (dru *DeviceRequestUpdate) sqlSave(ctx context.Context) (n int, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: devicerequest.Table, - Columns: devicerequest.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: devicerequest.FieldID, - }, - }, +func (_u *DeviceRequestUpdate) sqlSave(ctx context.Context) (_node int, err error) { + if err := _u.check(); err != nil { + return _node, err } - if ps := dru.mutation.predicates; len(ps) > 0 { + _spec := sqlgraph.NewUpdateSpec(devicerequest.Table, devicerequest.Columns, sqlgraph.NewFieldSpec(devicerequest.FieldID, field.TypeInt)) + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := dru.mutation.UserCode(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicerequest.FieldUserCode, - }) + if value, ok := _u.mutation.UserCode(); ok { + _spec.SetField(devicerequest.FieldUserCode, field.TypeString, value) } - if value, ok := dru.mutation.DeviceCode(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicerequest.FieldDeviceCode, - }) + if value, ok := _u.mutation.DeviceCode(); ok { + _spec.SetField(devicerequest.FieldDeviceCode, field.TypeString, value) } - if value, ok := dru.mutation.ClientID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicerequest.FieldClientID, - }) + if value, ok := _u.mutation.ClientID(); ok { + _spec.SetField(devicerequest.FieldClientID, field.TypeString, value) } - if value, ok := dru.mutation.ClientSecret(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicerequest.FieldClientSecret, - }) + if value, ok := _u.mutation.ClientSecret(); ok { + _spec.SetField(devicerequest.FieldClientSecret, field.TypeString, value) } - if value, ok := dru.mutation.Scopes(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: devicerequest.FieldScopes, - }) + if value, ok := _u.mutation.Scopes(); ok { + _spec.SetField(devicerequest.FieldScopes, field.TypeJSON, value) } - if dru.mutation.ScopesCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: devicerequest.FieldScopes, + if value, ok := _u.mutation.AppendedScopes(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, devicerequest.FieldScopes, value) }) } - if value, ok := dru.mutation.Expiry(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: devicerequest.FieldExpiry, - }) + if _u.mutation.ScopesCleared() { + _spec.ClearField(devicerequest.FieldScopes, field.TypeJSON) } - if n, err = sqlgraph.UpdateNodes(ctx, dru.driver, _spec); err != nil { + if value, ok := _u.mutation.Expiry(); ok { + _spec.SetField(devicerequest.FieldExpiry, field.TypeTime, value) + } + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{devicerequest.Label} } else if sqlgraph.IsConstraintError(err) { @@ -234,7 +220,8 @@ func (dru *DeviceRequestUpdate) sqlSave(ctx context.Context) (n int, err error) } return 0, err } - return n, nil + _u.mutation.done = true + return _node, nil } // DeviceRequestUpdateOne is the builder for updating a single DeviceRequest entity. @@ -246,106 +233,119 @@ type DeviceRequestUpdateOne struct { } // SetUserCode sets the "user_code" field. -func (druo *DeviceRequestUpdateOne) SetUserCode(s string) *DeviceRequestUpdateOne { - druo.mutation.SetUserCode(s) - return druo +func (_u *DeviceRequestUpdateOne) SetUserCode(v string) *DeviceRequestUpdateOne { + _u.mutation.SetUserCode(v) + return _u +} + +// SetNillableUserCode sets the "user_code" field if the given value is not nil. +func (_u *DeviceRequestUpdateOne) SetNillableUserCode(v *string) *DeviceRequestUpdateOne { + if v != nil { + _u.SetUserCode(*v) + } + return _u } // SetDeviceCode sets the "device_code" field. -func (druo *DeviceRequestUpdateOne) SetDeviceCode(s string) *DeviceRequestUpdateOne { - druo.mutation.SetDeviceCode(s) - return druo +func (_u *DeviceRequestUpdateOne) SetDeviceCode(v string) *DeviceRequestUpdateOne { + _u.mutation.SetDeviceCode(v) + return _u +} + +// SetNillableDeviceCode sets the "device_code" field if the given value is not nil. +func (_u *DeviceRequestUpdateOne) SetNillableDeviceCode(v *string) *DeviceRequestUpdateOne { + if v != nil { + _u.SetDeviceCode(*v) + } + return _u } // SetClientID sets the "client_id" field. -func (druo *DeviceRequestUpdateOne) SetClientID(s string) *DeviceRequestUpdateOne { - druo.mutation.SetClientID(s) - return druo +func (_u *DeviceRequestUpdateOne) SetClientID(v string) *DeviceRequestUpdateOne { + _u.mutation.SetClientID(v) + return _u +} + +// SetNillableClientID sets the "client_id" field if the given value is not nil. +func (_u *DeviceRequestUpdateOne) SetNillableClientID(v *string) *DeviceRequestUpdateOne { + if v != nil { + _u.SetClientID(*v) + } + return _u } // SetClientSecret sets the "client_secret" field. -func (druo *DeviceRequestUpdateOne) SetClientSecret(s string) *DeviceRequestUpdateOne { - druo.mutation.SetClientSecret(s) - return druo +func (_u *DeviceRequestUpdateOne) SetClientSecret(v string) *DeviceRequestUpdateOne { + _u.mutation.SetClientSecret(v) + return _u +} + +// SetNillableClientSecret sets the "client_secret" field if the given value is not nil. +func (_u *DeviceRequestUpdateOne) SetNillableClientSecret(v *string) *DeviceRequestUpdateOne { + if v != nil { + _u.SetClientSecret(*v) + } + return _u } // SetScopes sets the "scopes" field. -func (druo *DeviceRequestUpdateOne) SetScopes(s []string) *DeviceRequestUpdateOne { - druo.mutation.SetScopes(s) - return druo +func (_u *DeviceRequestUpdateOne) SetScopes(v []string) *DeviceRequestUpdateOne { + _u.mutation.SetScopes(v) + return _u +} + +// AppendScopes appends value to the "scopes" field. +func (_u *DeviceRequestUpdateOne) AppendScopes(v []string) *DeviceRequestUpdateOne { + _u.mutation.AppendScopes(v) + return _u } // ClearScopes clears the value of the "scopes" field. -func (druo *DeviceRequestUpdateOne) ClearScopes() *DeviceRequestUpdateOne { - druo.mutation.ClearScopes() - return druo +func (_u *DeviceRequestUpdateOne) ClearScopes() *DeviceRequestUpdateOne { + _u.mutation.ClearScopes() + return _u } // SetExpiry sets the "expiry" field. -func (druo *DeviceRequestUpdateOne) SetExpiry(t time.Time) *DeviceRequestUpdateOne { - druo.mutation.SetExpiry(t) - return druo +func (_u *DeviceRequestUpdateOne) SetExpiry(v time.Time) *DeviceRequestUpdateOne { + _u.mutation.SetExpiry(v) + return _u +} + +// SetNillableExpiry sets the "expiry" field if the given value is not nil. +func (_u *DeviceRequestUpdateOne) SetNillableExpiry(v *time.Time) *DeviceRequestUpdateOne { + if v != nil { + _u.SetExpiry(*v) + } + return _u } // Mutation returns the DeviceRequestMutation object of the builder. -func (druo *DeviceRequestUpdateOne) Mutation() *DeviceRequestMutation { - return druo.mutation +func (_u *DeviceRequestUpdateOne) Mutation() *DeviceRequestMutation { + return _u.mutation +} + +// Where appends a list predicates to the DeviceRequestUpdate builder. +func (_u *DeviceRequestUpdateOne) Where(ps ...predicate.DeviceRequest) *DeviceRequestUpdateOne { + _u.mutation.Where(ps...) + return _u } // Select allows selecting one or more fields (columns) of the returned entity. // The default is selecting all fields defined in the entity schema. -func (druo *DeviceRequestUpdateOne) Select(field string, fields ...string) *DeviceRequestUpdateOne { - druo.fields = append([]string{field}, fields...) - return druo +func (_u *DeviceRequestUpdateOne) Select(field string, fields ...string) *DeviceRequestUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u } // Save executes the query and returns the updated DeviceRequest entity. -func (druo *DeviceRequestUpdateOne) Save(ctx context.Context) (*DeviceRequest, error) { - var ( - err error - node *DeviceRequest - ) - if len(druo.hooks) == 0 { - if err = druo.check(); err != nil { - return nil, err - } - node, err = druo.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*DeviceRequestMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = druo.check(); err != nil { - return nil, err - } - druo.mutation = mutation - node, err = druo.sqlSave(ctx) - mutation.done = true - return node, err - }) - for i := len(druo.hooks) - 1; i >= 0; i-- { - if druo.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = druo.hooks[i](mut) - } - v, err := mut.Mutate(ctx, druo.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*DeviceRequest) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from DeviceRequestMutation", v) - } - node = nv - } - return node, err +func (_u *DeviceRequestUpdateOne) Save(ctx context.Context) (*DeviceRequest, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (druo *DeviceRequestUpdateOne) SaveX(ctx context.Context) *DeviceRequest { - node, err := druo.Save(ctx) +func (_u *DeviceRequestUpdateOne) SaveX(ctx context.Context) *DeviceRequest { + node, err := _u.Save(ctx) if err != nil { panic(err) } @@ -353,36 +353,36 @@ func (druo *DeviceRequestUpdateOne) SaveX(ctx context.Context) *DeviceRequest { } // Exec executes the query on the entity. -func (druo *DeviceRequestUpdateOne) Exec(ctx context.Context) error { - _, err := druo.Save(ctx) +func (_u *DeviceRequestUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (druo *DeviceRequestUpdateOne) ExecX(ctx context.Context) { - if err := druo.Exec(ctx); err != nil { +func (_u *DeviceRequestUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (druo *DeviceRequestUpdateOne) check() error { - if v, ok := druo.mutation.UserCode(); ok { +func (_u *DeviceRequestUpdateOne) check() error { + if v, ok := _u.mutation.UserCode(); ok { if err := devicerequest.UserCodeValidator(v); err != nil { return &ValidationError{Name: "user_code", err: fmt.Errorf(`db: validator failed for field "DeviceRequest.user_code": %w`, err)} } } - if v, ok := druo.mutation.DeviceCode(); ok { + if v, ok := _u.mutation.DeviceCode(); ok { if err := devicerequest.DeviceCodeValidator(v); err != nil { return &ValidationError{Name: "device_code", err: fmt.Errorf(`db: validator failed for field "DeviceRequest.device_code": %w`, err)} } } - if v, ok := druo.mutation.ClientID(); ok { + if v, ok := _u.mutation.ClientID(); ok { if err := devicerequest.ClientIDValidator(v); err != nil { return &ValidationError{Name: "client_id", err: fmt.Errorf(`db: validator failed for field "DeviceRequest.client_id": %w`, err)} } } - if v, ok := druo.mutation.ClientSecret(); ok { + if v, ok := _u.mutation.ClientSecret(); ok { if err := devicerequest.ClientSecretValidator(v); err != nil { return &ValidationError{Name: "client_secret", err: fmt.Errorf(`db: validator failed for field "DeviceRequest.client_secret": %w`, err)} } @@ -390,23 +390,17 @@ func (druo *DeviceRequestUpdateOne) check() error { return nil } -func (druo *DeviceRequestUpdateOne) sqlSave(ctx context.Context) (_node *DeviceRequest, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: devicerequest.Table, - Columns: devicerequest.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: devicerequest.FieldID, - }, - }, +func (_u *DeviceRequestUpdateOne) sqlSave(ctx context.Context) (_node *DeviceRequest, err error) { + if err := _u.check(); err != nil { + return _node, err } - id, ok := druo.mutation.ID() + _spec := sqlgraph.NewUpdateSpec(devicerequest.Table, devicerequest.Columns, sqlgraph.NewFieldSpec(devicerequest.FieldID, field.TypeInt)) + id, ok := _u.mutation.ID() if !ok { return nil, &ValidationError{Name: "id", err: errors.New(`db: missing "DeviceRequest.id" for update`)} } _spec.Node.ID.Value = id - if fields := druo.fields; len(fields) > 0 { + if fields := _u.fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, devicerequest.FieldID) for _, f := range fields { @@ -418,65 +412,43 @@ func (druo *DeviceRequestUpdateOne) sqlSave(ctx context.Context) (_node *DeviceR } } } - if ps := druo.mutation.predicates; len(ps) > 0 { + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := druo.mutation.UserCode(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicerequest.FieldUserCode, - }) + if value, ok := _u.mutation.UserCode(); ok { + _spec.SetField(devicerequest.FieldUserCode, field.TypeString, value) } - if value, ok := druo.mutation.DeviceCode(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicerequest.FieldDeviceCode, - }) + if value, ok := _u.mutation.DeviceCode(); ok { + _spec.SetField(devicerequest.FieldDeviceCode, field.TypeString, value) } - if value, ok := druo.mutation.ClientID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicerequest.FieldClientID, - }) + if value, ok := _u.mutation.ClientID(); ok { + _spec.SetField(devicerequest.FieldClientID, field.TypeString, value) } - if value, ok := druo.mutation.ClientSecret(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicerequest.FieldClientSecret, - }) + if value, ok := _u.mutation.ClientSecret(); ok { + _spec.SetField(devicerequest.FieldClientSecret, field.TypeString, value) } - if value, ok := druo.mutation.Scopes(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: devicerequest.FieldScopes, - }) + if value, ok := _u.mutation.Scopes(); ok { + _spec.SetField(devicerequest.FieldScopes, field.TypeJSON, value) } - if druo.mutation.ScopesCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: devicerequest.FieldScopes, + if value, ok := _u.mutation.AppendedScopes(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, devicerequest.FieldScopes, value) }) } - if value, ok := druo.mutation.Expiry(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: devicerequest.FieldExpiry, - }) + if _u.mutation.ScopesCleared() { + _spec.ClearField(devicerequest.FieldScopes, field.TypeJSON) + } + if value, ok := _u.mutation.Expiry(); ok { + _spec.SetField(devicerequest.FieldExpiry, field.TypeTime, value) } - _node = &DeviceRequest{config: druo.config} + _node = &DeviceRequest{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues - if err = sqlgraph.UpdateNode(ctx, druo.driver, _spec); err != nil { + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{devicerequest.Label} } else if sqlgraph.IsConstraintError(err) { @@ -484,5 +456,6 @@ func (druo *DeviceRequestUpdateOne) sqlSave(ctx context.Context) (_node *DeviceR } return nil, err } + _u.mutation.done = true return _node, nil } diff --git a/storage/ent/db/devicetoken.go b/storage/ent/db/devicetoken.go index 0daa128064..30b69d0307 100644 --- a/storage/ent/db/devicetoken.go +++ b/storage/ent/db/devicetoken.go @@ -7,6 +7,7 @@ import ( "strings" "time" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/dexidp/dex/storage/ent/db/devicetoken" ) @@ -32,11 +33,12 @@ type DeviceToken struct { CodeChallenge string `json:"code_challenge,omitempty"` // CodeChallengeMethod holds the value of the "code_challenge_method" field. CodeChallengeMethod string `json:"code_challenge_method,omitempty"` + selectValues sql.SelectValues } // scanValues returns the types for scanning values from sql.Rows. -func (*DeviceToken) scanValues(columns []string) ([]interface{}, error) { - values := make([]interface{}, len(columns)) +func (*DeviceToken) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) for i := range columns { switch columns[i] { case devicetoken.FieldToken: @@ -48,7 +50,7 @@ func (*DeviceToken) scanValues(columns []string) ([]interface{}, error) { case devicetoken.FieldExpiry, devicetoken.FieldLastRequest: values[i] = new(sql.NullTime) default: - return nil, fmt.Errorf("unexpected column %q for type DeviceToken", columns[i]) + values[i] = new(sql.UnknownType) } } return values, nil @@ -56,7 +58,7 @@ func (*DeviceToken) scanValues(columns []string) ([]interface{}, error) { // assignValues assigns the values that were returned from sql.Rows (after scanning) // to the DeviceToken fields. -func (dt *DeviceToken) assignValues(columns []string, values []interface{}) error { +func (_m *DeviceToken) assignValues(columns []string, values []any) error { if m, n := len(values), len(columns); m < n { return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) } @@ -67,117 +69,119 @@ func (dt *DeviceToken) assignValues(columns []string, values []interface{}) erro if !ok { return fmt.Errorf("unexpected type %T for field id", value) } - dt.ID = int(value.Int64) + _m.ID = int(value.Int64) case devicetoken.FieldDeviceCode: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field device_code", values[i]) } else if value.Valid { - dt.DeviceCode = value.String + _m.DeviceCode = value.String } case devicetoken.FieldStatus: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field status", values[i]) } else if value.Valid { - dt.Status = value.String + _m.Status = value.String } case devicetoken.FieldToken: if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field token", values[i]) } else if value != nil { - dt.Token = value + _m.Token = value } case devicetoken.FieldExpiry: if value, ok := values[i].(*sql.NullTime); !ok { return fmt.Errorf("unexpected type %T for field expiry", values[i]) } else if value.Valid { - dt.Expiry = value.Time + _m.Expiry = value.Time } case devicetoken.FieldLastRequest: if value, ok := values[i].(*sql.NullTime); !ok { return fmt.Errorf("unexpected type %T for field last_request", values[i]) } else if value.Valid { - dt.LastRequest = value.Time + _m.LastRequest = value.Time } case devicetoken.FieldPollInterval: if value, ok := values[i].(*sql.NullInt64); !ok { return fmt.Errorf("unexpected type %T for field poll_interval", values[i]) } else if value.Valid { - dt.PollInterval = int(value.Int64) + _m.PollInterval = int(value.Int64) } case devicetoken.FieldCodeChallenge: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field code_challenge", values[i]) } else if value.Valid { - dt.CodeChallenge = value.String + _m.CodeChallenge = value.String } case devicetoken.FieldCodeChallengeMethod: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field code_challenge_method", values[i]) } else if value.Valid { - dt.CodeChallengeMethod = value.String + _m.CodeChallengeMethod = value.String } + default: + _m.selectValues.Set(columns[i], values[i]) } } return nil } +// Value returns the ent.Value that was dynamically selected and assigned to the DeviceToken. +// This includes values selected through modifiers, order, etc. +func (_m *DeviceToken) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + // Update returns a builder for updating this DeviceToken. // Note that you need to call DeviceToken.Unwrap() before calling this method if this DeviceToken // was returned from a transaction, and the transaction was committed or rolled back. -func (dt *DeviceToken) Update() *DeviceTokenUpdateOne { - return (&DeviceTokenClient{config: dt.config}).UpdateOne(dt) +func (_m *DeviceToken) Update() *DeviceTokenUpdateOne { + return NewDeviceTokenClient(_m.config).UpdateOne(_m) } // Unwrap unwraps the DeviceToken entity that was returned from a transaction after it was closed, // so that all future queries will be executed through the driver which created the transaction. -func (dt *DeviceToken) Unwrap() *DeviceToken { - _tx, ok := dt.config.driver.(*txDriver) +func (_m *DeviceToken) Unwrap() *DeviceToken { + _tx, ok := _m.config.driver.(*txDriver) if !ok { panic("db: DeviceToken is not a transactional entity") } - dt.config.driver = _tx.drv - return dt + _m.config.driver = _tx.drv + return _m } // String implements the fmt.Stringer. -func (dt *DeviceToken) String() string { +func (_m *DeviceToken) String() string { var builder strings.Builder builder.WriteString("DeviceToken(") - builder.WriteString(fmt.Sprintf("id=%v, ", dt.ID)) + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) builder.WriteString("device_code=") - builder.WriteString(dt.DeviceCode) + builder.WriteString(_m.DeviceCode) builder.WriteString(", ") builder.WriteString("status=") - builder.WriteString(dt.Status) + builder.WriteString(_m.Status) builder.WriteString(", ") - if v := dt.Token; v != nil { + if v := _m.Token; v != nil { builder.WriteString("token=") builder.WriteString(fmt.Sprintf("%v", *v)) } builder.WriteString(", ") builder.WriteString("expiry=") - builder.WriteString(dt.Expiry.Format(time.ANSIC)) + builder.WriteString(_m.Expiry.Format(time.ANSIC)) builder.WriteString(", ") builder.WriteString("last_request=") - builder.WriteString(dt.LastRequest.Format(time.ANSIC)) + builder.WriteString(_m.LastRequest.Format(time.ANSIC)) builder.WriteString(", ") builder.WriteString("poll_interval=") - builder.WriteString(fmt.Sprintf("%v", dt.PollInterval)) + builder.WriteString(fmt.Sprintf("%v", _m.PollInterval)) builder.WriteString(", ") builder.WriteString("code_challenge=") - builder.WriteString(dt.CodeChallenge) + builder.WriteString(_m.CodeChallenge) builder.WriteString(", ") builder.WriteString("code_challenge_method=") - builder.WriteString(dt.CodeChallengeMethod) + builder.WriteString(_m.CodeChallengeMethod) builder.WriteByte(')') return builder.String() } // DeviceTokens is a parsable slice of DeviceToken. type DeviceTokens []*DeviceToken - -func (dt DeviceTokens) config(cfg config) { - for _i := range dt { - dt[_i].config = cfg - } -} diff --git a/storage/ent/db/devicetoken/devicetoken.go b/storage/ent/db/devicetoken/devicetoken.go index f40b1b048a..7297244035 100644 --- a/storage/ent/db/devicetoken/devicetoken.go +++ b/storage/ent/db/devicetoken/devicetoken.go @@ -2,6 +2,10 @@ package devicetoken +import ( + "entgo.io/ent/dialect/sql" +) + const ( // Label holds the string label denoting the devicetoken type in the database. Label = "device_token" @@ -60,3 +64,46 @@ var ( // DefaultCodeChallengeMethod holds the default value on creation for the "code_challenge_method" field. DefaultCodeChallengeMethod string ) + +// OrderOption defines the ordering options for the DeviceToken queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByDeviceCode orders the results by the device_code field. +func ByDeviceCode(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldDeviceCode, opts...).ToFunc() +} + +// ByStatus orders the results by the status field. +func ByStatus(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldStatus, opts...).ToFunc() +} + +// ByExpiry orders the results by the expiry field. +func ByExpiry(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldExpiry, opts...).ToFunc() +} + +// ByLastRequest orders the results by the last_request field. +func ByLastRequest(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldLastRequest, opts...).ToFunc() +} + +// ByPollInterval orders the results by the poll_interval field. +func ByPollInterval(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldPollInterval, opts...).ToFunc() +} + +// ByCodeChallenge orders the results by the code_challenge field. +func ByCodeChallenge(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldCodeChallenge, opts...).ToFunc() +} + +// ByCodeChallengeMethod orders the results by the code_challenge_method field. +func ByCodeChallengeMethod(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldCodeChallengeMethod, opts...).ToFunc() +} diff --git a/storage/ent/db/devicetoken/where.go b/storage/ent/db/devicetoken/where.go index a8e33f1e00..59fa65cb1e 100644 --- a/storage/ent/db/devicetoken/where.go +++ b/storage/ent/db/devicetoken/where.go @@ -11,825 +11,530 @@ import ( // ID filters vertices based on their ID field. func ID(id int) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.DeviceToken(sql.FieldEQ(FieldID, id)) } // IDEQ applies the EQ predicate on the ID field. func IDEQ(id int) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.DeviceToken(sql.FieldEQ(FieldID, id)) } // IDNEQ applies the NEQ predicate on the ID field. func IDNEQ(id int) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldID), id)) - }) + return predicate.DeviceToken(sql.FieldNEQ(FieldID, id)) } // IDIn applies the In predicate on the ID field. func IDIn(ids ...int) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.In(s.C(FieldID), v...)) - }) + return predicate.DeviceToken(sql.FieldIn(FieldID, ids...)) } // IDNotIn applies the NotIn predicate on the ID field. func IDNotIn(ids ...int) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.NotIn(s.C(FieldID), v...)) - }) + return predicate.DeviceToken(sql.FieldNotIn(FieldID, ids...)) } // IDGT applies the GT predicate on the ID field. func IDGT(id int) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldID), id)) - }) + return predicate.DeviceToken(sql.FieldGT(FieldID, id)) } // IDGTE applies the GTE predicate on the ID field. func IDGTE(id int) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldID), id)) - }) + return predicate.DeviceToken(sql.FieldGTE(FieldID, id)) } // IDLT applies the LT predicate on the ID field. func IDLT(id int) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldID), id)) - }) + return predicate.DeviceToken(sql.FieldLT(FieldID, id)) } // IDLTE applies the LTE predicate on the ID field. func IDLTE(id int) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldID), id)) - }) + return predicate.DeviceToken(sql.FieldLTE(FieldID, id)) } // DeviceCode applies equality check predicate on the "device_code" field. It's identical to DeviceCodeEQ. func DeviceCode(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceToken(sql.FieldEQ(FieldDeviceCode, v)) } // Status applies equality check predicate on the "status" field. It's identical to StatusEQ. func Status(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldStatus), v)) - }) + return predicate.DeviceToken(sql.FieldEQ(FieldStatus, v)) } // Token applies equality check predicate on the "token" field. It's identical to TokenEQ. func Token(v []byte) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldToken), v)) - }) + return predicate.DeviceToken(sql.FieldEQ(FieldToken, v)) } // Expiry applies equality check predicate on the "expiry" field. It's identical to ExpiryEQ. func Expiry(v time.Time) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldExpiry), v)) - }) + return predicate.DeviceToken(sql.FieldEQ(FieldExpiry, v)) } // LastRequest applies equality check predicate on the "last_request" field. It's identical to LastRequestEQ. func LastRequest(v time.Time) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldLastRequest), v)) - }) + return predicate.DeviceToken(sql.FieldEQ(FieldLastRequest, v)) } // PollInterval applies equality check predicate on the "poll_interval" field. It's identical to PollIntervalEQ. func PollInterval(v int) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldPollInterval), v)) - }) + return predicate.DeviceToken(sql.FieldEQ(FieldPollInterval, v)) } // CodeChallenge applies equality check predicate on the "code_challenge" field. It's identical to CodeChallengeEQ. func CodeChallenge(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldCodeChallenge), v)) - }) + return predicate.DeviceToken(sql.FieldEQ(FieldCodeChallenge, v)) } // CodeChallengeMethod applies equality check predicate on the "code_challenge_method" field. It's identical to CodeChallengeMethodEQ. func CodeChallengeMethod(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.DeviceToken(sql.FieldEQ(FieldCodeChallengeMethod, v)) } // DeviceCodeEQ applies the EQ predicate on the "device_code" field. func DeviceCodeEQ(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceToken(sql.FieldEQ(FieldDeviceCode, v)) } // DeviceCodeNEQ applies the NEQ predicate on the "device_code" field. func DeviceCodeNEQ(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceToken(sql.FieldNEQ(FieldDeviceCode, v)) } // DeviceCodeIn applies the In predicate on the "device_code" field. func DeviceCodeIn(vs ...string) predicate.DeviceToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldDeviceCode), v...)) - }) + return predicate.DeviceToken(sql.FieldIn(FieldDeviceCode, vs...)) } // DeviceCodeNotIn applies the NotIn predicate on the "device_code" field. func DeviceCodeNotIn(vs ...string) predicate.DeviceToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldDeviceCode), v...)) - }) + return predicate.DeviceToken(sql.FieldNotIn(FieldDeviceCode, vs...)) } // DeviceCodeGT applies the GT predicate on the "device_code" field. func DeviceCodeGT(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceToken(sql.FieldGT(FieldDeviceCode, v)) } // DeviceCodeGTE applies the GTE predicate on the "device_code" field. func DeviceCodeGTE(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceToken(sql.FieldGTE(FieldDeviceCode, v)) } // DeviceCodeLT applies the LT predicate on the "device_code" field. func DeviceCodeLT(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceToken(sql.FieldLT(FieldDeviceCode, v)) } // DeviceCodeLTE applies the LTE predicate on the "device_code" field. func DeviceCodeLTE(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceToken(sql.FieldLTE(FieldDeviceCode, v)) } // DeviceCodeContains applies the Contains predicate on the "device_code" field. func DeviceCodeContains(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceToken(sql.FieldContains(FieldDeviceCode, v)) } // DeviceCodeHasPrefix applies the HasPrefix predicate on the "device_code" field. func DeviceCodeHasPrefix(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceToken(sql.FieldHasPrefix(FieldDeviceCode, v)) } // DeviceCodeHasSuffix applies the HasSuffix predicate on the "device_code" field. func DeviceCodeHasSuffix(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceToken(sql.FieldHasSuffix(FieldDeviceCode, v)) } // DeviceCodeEqualFold applies the EqualFold predicate on the "device_code" field. func DeviceCodeEqualFold(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceToken(sql.FieldEqualFold(FieldDeviceCode, v)) } // DeviceCodeContainsFold applies the ContainsFold predicate on the "device_code" field. func DeviceCodeContainsFold(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldDeviceCode), v)) - }) + return predicate.DeviceToken(sql.FieldContainsFold(FieldDeviceCode, v)) } // StatusEQ applies the EQ predicate on the "status" field. func StatusEQ(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldStatus), v)) - }) + return predicate.DeviceToken(sql.FieldEQ(FieldStatus, v)) } // StatusNEQ applies the NEQ predicate on the "status" field. func StatusNEQ(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldStatus), v)) - }) + return predicate.DeviceToken(sql.FieldNEQ(FieldStatus, v)) } // StatusIn applies the In predicate on the "status" field. func StatusIn(vs ...string) predicate.DeviceToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldStatus), v...)) - }) + return predicate.DeviceToken(sql.FieldIn(FieldStatus, vs...)) } // StatusNotIn applies the NotIn predicate on the "status" field. func StatusNotIn(vs ...string) predicate.DeviceToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldStatus), v...)) - }) + return predicate.DeviceToken(sql.FieldNotIn(FieldStatus, vs...)) } // StatusGT applies the GT predicate on the "status" field. func StatusGT(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldStatus), v)) - }) + return predicate.DeviceToken(sql.FieldGT(FieldStatus, v)) } // StatusGTE applies the GTE predicate on the "status" field. func StatusGTE(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldStatus), v)) - }) + return predicate.DeviceToken(sql.FieldGTE(FieldStatus, v)) } // StatusLT applies the LT predicate on the "status" field. func StatusLT(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldStatus), v)) - }) + return predicate.DeviceToken(sql.FieldLT(FieldStatus, v)) } // StatusLTE applies the LTE predicate on the "status" field. func StatusLTE(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldStatus), v)) - }) + return predicate.DeviceToken(sql.FieldLTE(FieldStatus, v)) } // StatusContains applies the Contains predicate on the "status" field. func StatusContains(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldStatus), v)) - }) + return predicate.DeviceToken(sql.FieldContains(FieldStatus, v)) } // StatusHasPrefix applies the HasPrefix predicate on the "status" field. func StatusHasPrefix(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldStatus), v)) - }) + return predicate.DeviceToken(sql.FieldHasPrefix(FieldStatus, v)) } // StatusHasSuffix applies the HasSuffix predicate on the "status" field. func StatusHasSuffix(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldStatus), v)) - }) + return predicate.DeviceToken(sql.FieldHasSuffix(FieldStatus, v)) } // StatusEqualFold applies the EqualFold predicate on the "status" field. func StatusEqualFold(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldStatus), v)) - }) + return predicate.DeviceToken(sql.FieldEqualFold(FieldStatus, v)) } // StatusContainsFold applies the ContainsFold predicate on the "status" field. func StatusContainsFold(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldStatus), v)) - }) + return predicate.DeviceToken(sql.FieldContainsFold(FieldStatus, v)) } // TokenEQ applies the EQ predicate on the "token" field. func TokenEQ(v []byte) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldToken), v)) - }) + return predicate.DeviceToken(sql.FieldEQ(FieldToken, v)) } // TokenNEQ applies the NEQ predicate on the "token" field. func TokenNEQ(v []byte) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldToken), v)) - }) + return predicate.DeviceToken(sql.FieldNEQ(FieldToken, v)) } // TokenIn applies the In predicate on the "token" field. func TokenIn(vs ...[]byte) predicate.DeviceToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldToken), v...)) - }) + return predicate.DeviceToken(sql.FieldIn(FieldToken, vs...)) } // TokenNotIn applies the NotIn predicate on the "token" field. func TokenNotIn(vs ...[]byte) predicate.DeviceToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldToken), v...)) - }) + return predicate.DeviceToken(sql.FieldNotIn(FieldToken, vs...)) } // TokenGT applies the GT predicate on the "token" field. func TokenGT(v []byte) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldToken), v)) - }) + return predicate.DeviceToken(sql.FieldGT(FieldToken, v)) } // TokenGTE applies the GTE predicate on the "token" field. func TokenGTE(v []byte) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldToken), v)) - }) + return predicate.DeviceToken(sql.FieldGTE(FieldToken, v)) } // TokenLT applies the LT predicate on the "token" field. func TokenLT(v []byte) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldToken), v)) - }) + return predicate.DeviceToken(sql.FieldLT(FieldToken, v)) } // TokenLTE applies the LTE predicate on the "token" field. func TokenLTE(v []byte) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldToken), v)) - }) + return predicate.DeviceToken(sql.FieldLTE(FieldToken, v)) } // TokenIsNil applies the IsNil predicate on the "token" field. func TokenIsNil() predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.IsNull(s.C(FieldToken))) - }) + return predicate.DeviceToken(sql.FieldIsNull(FieldToken)) } // TokenNotNil applies the NotNil predicate on the "token" field. func TokenNotNil() predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.NotNull(s.C(FieldToken))) - }) + return predicate.DeviceToken(sql.FieldNotNull(FieldToken)) } // ExpiryEQ applies the EQ predicate on the "expiry" field. func ExpiryEQ(v time.Time) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldExpiry), v)) - }) + return predicate.DeviceToken(sql.FieldEQ(FieldExpiry, v)) } // ExpiryNEQ applies the NEQ predicate on the "expiry" field. func ExpiryNEQ(v time.Time) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldExpiry), v)) - }) + return predicate.DeviceToken(sql.FieldNEQ(FieldExpiry, v)) } // ExpiryIn applies the In predicate on the "expiry" field. func ExpiryIn(vs ...time.Time) predicate.DeviceToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldExpiry), v...)) - }) + return predicate.DeviceToken(sql.FieldIn(FieldExpiry, vs...)) } // ExpiryNotIn applies the NotIn predicate on the "expiry" field. func ExpiryNotIn(vs ...time.Time) predicate.DeviceToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldExpiry), v...)) - }) + return predicate.DeviceToken(sql.FieldNotIn(FieldExpiry, vs...)) } // ExpiryGT applies the GT predicate on the "expiry" field. func ExpiryGT(v time.Time) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldExpiry), v)) - }) + return predicate.DeviceToken(sql.FieldGT(FieldExpiry, v)) } // ExpiryGTE applies the GTE predicate on the "expiry" field. func ExpiryGTE(v time.Time) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldExpiry), v)) - }) + return predicate.DeviceToken(sql.FieldGTE(FieldExpiry, v)) } // ExpiryLT applies the LT predicate on the "expiry" field. func ExpiryLT(v time.Time) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldExpiry), v)) - }) + return predicate.DeviceToken(sql.FieldLT(FieldExpiry, v)) } // ExpiryLTE applies the LTE predicate on the "expiry" field. func ExpiryLTE(v time.Time) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldExpiry), v)) - }) + return predicate.DeviceToken(sql.FieldLTE(FieldExpiry, v)) } // LastRequestEQ applies the EQ predicate on the "last_request" field. func LastRequestEQ(v time.Time) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldLastRequest), v)) - }) + return predicate.DeviceToken(sql.FieldEQ(FieldLastRequest, v)) } // LastRequestNEQ applies the NEQ predicate on the "last_request" field. func LastRequestNEQ(v time.Time) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldLastRequest), v)) - }) + return predicate.DeviceToken(sql.FieldNEQ(FieldLastRequest, v)) } // LastRequestIn applies the In predicate on the "last_request" field. func LastRequestIn(vs ...time.Time) predicate.DeviceToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldLastRequest), v...)) - }) + return predicate.DeviceToken(sql.FieldIn(FieldLastRequest, vs...)) } // LastRequestNotIn applies the NotIn predicate on the "last_request" field. func LastRequestNotIn(vs ...time.Time) predicate.DeviceToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldLastRequest), v...)) - }) + return predicate.DeviceToken(sql.FieldNotIn(FieldLastRequest, vs...)) } // LastRequestGT applies the GT predicate on the "last_request" field. func LastRequestGT(v time.Time) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldLastRequest), v)) - }) + return predicate.DeviceToken(sql.FieldGT(FieldLastRequest, v)) } // LastRequestGTE applies the GTE predicate on the "last_request" field. func LastRequestGTE(v time.Time) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldLastRequest), v)) - }) + return predicate.DeviceToken(sql.FieldGTE(FieldLastRequest, v)) } // LastRequestLT applies the LT predicate on the "last_request" field. func LastRequestLT(v time.Time) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldLastRequest), v)) - }) + return predicate.DeviceToken(sql.FieldLT(FieldLastRequest, v)) } // LastRequestLTE applies the LTE predicate on the "last_request" field. func LastRequestLTE(v time.Time) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldLastRequest), v)) - }) + return predicate.DeviceToken(sql.FieldLTE(FieldLastRequest, v)) } // PollIntervalEQ applies the EQ predicate on the "poll_interval" field. func PollIntervalEQ(v int) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldPollInterval), v)) - }) + return predicate.DeviceToken(sql.FieldEQ(FieldPollInterval, v)) } // PollIntervalNEQ applies the NEQ predicate on the "poll_interval" field. func PollIntervalNEQ(v int) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldPollInterval), v)) - }) + return predicate.DeviceToken(sql.FieldNEQ(FieldPollInterval, v)) } // PollIntervalIn applies the In predicate on the "poll_interval" field. func PollIntervalIn(vs ...int) predicate.DeviceToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldPollInterval), v...)) - }) + return predicate.DeviceToken(sql.FieldIn(FieldPollInterval, vs...)) } // PollIntervalNotIn applies the NotIn predicate on the "poll_interval" field. func PollIntervalNotIn(vs ...int) predicate.DeviceToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldPollInterval), v...)) - }) + return predicate.DeviceToken(sql.FieldNotIn(FieldPollInterval, vs...)) } // PollIntervalGT applies the GT predicate on the "poll_interval" field. func PollIntervalGT(v int) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldPollInterval), v)) - }) + return predicate.DeviceToken(sql.FieldGT(FieldPollInterval, v)) } // PollIntervalGTE applies the GTE predicate on the "poll_interval" field. func PollIntervalGTE(v int) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldPollInterval), v)) - }) + return predicate.DeviceToken(sql.FieldGTE(FieldPollInterval, v)) } // PollIntervalLT applies the LT predicate on the "poll_interval" field. func PollIntervalLT(v int) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldPollInterval), v)) - }) + return predicate.DeviceToken(sql.FieldLT(FieldPollInterval, v)) } // PollIntervalLTE applies the LTE predicate on the "poll_interval" field. func PollIntervalLTE(v int) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldPollInterval), v)) - }) + return predicate.DeviceToken(sql.FieldLTE(FieldPollInterval, v)) } // CodeChallengeEQ applies the EQ predicate on the "code_challenge" field. func CodeChallengeEQ(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldCodeChallenge), v)) - }) + return predicate.DeviceToken(sql.FieldEQ(FieldCodeChallenge, v)) } // CodeChallengeNEQ applies the NEQ predicate on the "code_challenge" field. func CodeChallengeNEQ(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldCodeChallenge), v)) - }) + return predicate.DeviceToken(sql.FieldNEQ(FieldCodeChallenge, v)) } // CodeChallengeIn applies the In predicate on the "code_challenge" field. func CodeChallengeIn(vs ...string) predicate.DeviceToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldCodeChallenge), v...)) - }) + return predicate.DeviceToken(sql.FieldIn(FieldCodeChallenge, vs...)) } // CodeChallengeNotIn applies the NotIn predicate on the "code_challenge" field. func CodeChallengeNotIn(vs ...string) predicate.DeviceToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldCodeChallenge), v...)) - }) + return predicate.DeviceToken(sql.FieldNotIn(FieldCodeChallenge, vs...)) } // CodeChallengeGT applies the GT predicate on the "code_challenge" field. func CodeChallengeGT(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldCodeChallenge), v)) - }) + return predicate.DeviceToken(sql.FieldGT(FieldCodeChallenge, v)) } // CodeChallengeGTE applies the GTE predicate on the "code_challenge" field. func CodeChallengeGTE(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldCodeChallenge), v)) - }) + return predicate.DeviceToken(sql.FieldGTE(FieldCodeChallenge, v)) } // CodeChallengeLT applies the LT predicate on the "code_challenge" field. func CodeChallengeLT(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldCodeChallenge), v)) - }) + return predicate.DeviceToken(sql.FieldLT(FieldCodeChallenge, v)) } // CodeChallengeLTE applies the LTE predicate on the "code_challenge" field. func CodeChallengeLTE(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldCodeChallenge), v)) - }) + return predicate.DeviceToken(sql.FieldLTE(FieldCodeChallenge, v)) } // CodeChallengeContains applies the Contains predicate on the "code_challenge" field. func CodeChallengeContains(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldCodeChallenge), v)) - }) + return predicate.DeviceToken(sql.FieldContains(FieldCodeChallenge, v)) } // CodeChallengeHasPrefix applies the HasPrefix predicate on the "code_challenge" field. func CodeChallengeHasPrefix(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldCodeChallenge), v)) - }) + return predicate.DeviceToken(sql.FieldHasPrefix(FieldCodeChallenge, v)) } // CodeChallengeHasSuffix applies the HasSuffix predicate on the "code_challenge" field. func CodeChallengeHasSuffix(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldCodeChallenge), v)) - }) + return predicate.DeviceToken(sql.FieldHasSuffix(FieldCodeChallenge, v)) } // CodeChallengeEqualFold applies the EqualFold predicate on the "code_challenge" field. func CodeChallengeEqualFold(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldCodeChallenge), v)) - }) + return predicate.DeviceToken(sql.FieldEqualFold(FieldCodeChallenge, v)) } // CodeChallengeContainsFold applies the ContainsFold predicate on the "code_challenge" field. func CodeChallengeContainsFold(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldCodeChallenge), v)) - }) + return predicate.DeviceToken(sql.FieldContainsFold(FieldCodeChallenge, v)) } // CodeChallengeMethodEQ applies the EQ predicate on the "code_challenge_method" field. func CodeChallengeMethodEQ(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.DeviceToken(sql.FieldEQ(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodNEQ applies the NEQ predicate on the "code_challenge_method" field. func CodeChallengeMethodNEQ(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.DeviceToken(sql.FieldNEQ(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodIn applies the In predicate on the "code_challenge_method" field. func CodeChallengeMethodIn(vs ...string) predicate.DeviceToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldCodeChallengeMethod), v...)) - }) + return predicate.DeviceToken(sql.FieldIn(FieldCodeChallengeMethod, vs...)) } // CodeChallengeMethodNotIn applies the NotIn predicate on the "code_challenge_method" field. func CodeChallengeMethodNotIn(vs ...string) predicate.DeviceToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldCodeChallengeMethod), v...)) - }) + return predicate.DeviceToken(sql.FieldNotIn(FieldCodeChallengeMethod, vs...)) } // CodeChallengeMethodGT applies the GT predicate on the "code_challenge_method" field. func CodeChallengeMethodGT(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.DeviceToken(sql.FieldGT(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodGTE applies the GTE predicate on the "code_challenge_method" field. func CodeChallengeMethodGTE(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.DeviceToken(sql.FieldGTE(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodLT applies the LT predicate on the "code_challenge_method" field. func CodeChallengeMethodLT(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.DeviceToken(sql.FieldLT(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodLTE applies the LTE predicate on the "code_challenge_method" field. func CodeChallengeMethodLTE(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.DeviceToken(sql.FieldLTE(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodContains applies the Contains predicate on the "code_challenge_method" field. func CodeChallengeMethodContains(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.DeviceToken(sql.FieldContains(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodHasPrefix applies the HasPrefix predicate on the "code_challenge_method" field. func CodeChallengeMethodHasPrefix(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.DeviceToken(sql.FieldHasPrefix(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodHasSuffix applies the HasSuffix predicate on the "code_challenge_method" field. func CodeChallengeMethodHasSuffix(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.DeviceToken(sql.FieldHasSuffix(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodEqualFold applies the EqualFold predicate on the "code_challenge_method" field. func CodeChallengeMethodEqualFold(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.DeviceToken(sql.FieldEqualFold(FieldCodeChallengeMethod, v)) } // CodeChallengeMethodContainsFold applies the ContainsFold predicate on the "code_challenge_method" field. func CodeChallengeMethodContainsFold(v string) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldCodeChallengeMethod), v)) - }) + return predicate.DeviceToken(sql.FieldContainsFold(FieldCodeChallengeMethod, v)) } // And groups predicates with the AND operator between them. func And(predicates ...predicate.DeviceToken) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for _, p := range predicates { - p(s1) - } - s.Where(s1.P()) - }) + return predicate.DeviceToken(sql.AndPredicates(predicates...)) } // Or groups predicates with the OR operator between them. func Or(predicates ...predicate.DeviceToken) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for i, p := range predicates { - if i > 0 { - s1.Or() - } - p(s1) - } - s.Where(s1.P()) - }) + return predicate.DeviceToken(sql.OrPredicates(predicates...)) } // Not applies the not operator on the given predicate. func Not(p predicate.DeviceToken) predicate.DeviceToken { - return predicate.DeviceToken(func(s *sql.Selector) { - p(s.Not()) - }) + return predicate.DeviceToken(sql.NotPredicates(p)) } diff --git a/storage/ent/db/devicetoken_create.go b/storage/ent/db/devicetoken_create.go index bbf67e5a29..577d475103 100644 --- a/storage/ent/db/devicetoken_create.go +++ b/storage/ent/db/devicetoken_create.go @@ -21,125 +21,83 @@ type DeviceTokenCreate struct { } // SetDeviceCode sets the "device_code" field. -func (dtc *DeviceTokenCreate) SetDeviceCode(s string) *DeviceTokenCreate { - dtc.mutation.SetDeviceCode(s) - return dtc +func (_c *DeviceTokenCreate) SetDeviceCode(v string) *DeviceTokenCreate { + _c.mutation.SetDeviceCode(v) + return _c } // SetStatus sets the "status" field. -func (dtc *DeviceTokenCreate) SetStatus(s string) *DeviceTokenCreate { - dtc.mutation.SetStatus(s) - return dtc +func (_c *DeviceTokenCreate) SetStatus(v string) *DeviceTokenCreate { + _c.mutation.SetStatus(v) + return _c } // SetToken sets the "token" field. -func (dtc *DeviceTokenCreate) SetToken(b []byte) *DeviceTokenCreate { - dtc.mutation.SetToken(b) - return dtc +func (_c *DeviceTokenCreate) SetToken(v []byte) *DeviceTokenCreate { + _c.mutation.SetToken(v) + return _c } // SetExpiry sets the "expiry" field. -func (dtc *DeviceTokenCreate) SetExpiry(t time.Time) *DeviceTokenCreate { - dtc.mutation.SetExpiry(t) - return dtc +func (_c *DeviceTokenCreate) SetExpiry(v time.Time) *DeviceTokenCreate { + _c.mutation.SetExpiry(v) + return _c } // SetLastRequest sets the "last_request" field. -func (dtc *DeviceTokenCreate) SetLastRequest(t time.Time) *DeviceTokenCreate { - dtc.mutation.SetLastRequest(t) - return dtc +func (_c *DeviceTokenCreate) SetLastRequest(v time.Time) *DeviceTokenCreate { + _c.mutation.SetLastRequest(v) + return _c } // SetPollInterval sets the "poll_interval" field. -func (dtc *DeviceTokenCreate) SetPollInterval(i int) *DeviceTokenCreate { - dtc.mutation.SetPollInterval(i) - return dtc +func (_c *DeviceTokenCreate) SetPollInterval(v int) *DeviceTokenCreate { + _c.mutation.SetPollInterval(v) + return _c } // SetCodeChallenge sets the "code_challenge" field. -func (dtc *DeviceTokenCreate) SetCodeChallenge(s string) *DeviceTokenCreate { - dtc.mutation.SetCodeChallenge(s) - return dtc +func (_c *DeviceTokenCreate) SetCodeChallenge(v string) *DeviceTokenCreate { + _c.mutation.SetCodeChallenge(v) + return _c } // SetNillableCodeChallenge sets the "code_challenge" field if the given value is not nil. -func (dtc *DeviceTokenCreate) SetNillableCodeChallenge(s *string) *DeviceTokenCreate { - if s != nil { - dtc.SetCodeChallenge(*s) +func (_c *DeviceTokenCreate) SetNillableCodeChallenge(v *string) *DeviceTokenCreate { + if v != nil { + _c.SetCodeChallenge(*v) } - return dtc + return _c } // SetCodeChallengeMethod sets the "code_challenge_method" field. -func (dtc *DeviceTokenCreate) SetCodeChallengeMethod(s string) *DeviceTokenCreate { - dtc.mutation.SetCodeChallengeMethod(s) - return dtc +func (_c *DeviceTokenCreate) SetCodeChallengeMethod(v string) *DeviceTokenCreate { + _c.mutation.SetCodeChallengeMethod(v) + return _c } // SetNillableCodeChallengeMethod sets the "code_challenge_method" field if the given value is not nil. -func (dtc *DeviceTokenCreate) SetNillableCodeChallengeMethod(s *string) *DeviceTokenCreate { - if s != nil { - dtc.SetCodeChallengeMethod(*s) +func (_c *DeviceTokenCreate) SetNillableCodeChallengeMethod(v *string) *DeviceTokenCreate { + if v != nil { + _c.SetCodeChallengeMethod(*v) } - return dtc + return _c } // Mutation returns the DeviceTokenMutation object of the builder. -func (dtc *DeviceTokenCreate) Mutation() *DeviceTokenMutation { - return dtc.mutation +func (_c *DeviceTokenCreate) Mutation() *DeviceTokenMutation { + return _c.mutation } // Save creates the DeviceToken in the database. -func (dtc *DeviceTokenCreate) Save(ctx context.Context) (*DeviceToken, error) { - var ( - err error - node *DeviceToken - ) - dtc.defaults() - if len(dtc.hooks) == 0 { - if err = dtc.check(); err != nil { - return nil, err - } - node, err = dtc.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*DeviceTokenMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = dtc.check(); err != nil { - return nil, err - } - dtc.mutation = mutation - if node, err = dtc.sqlSave(ctx); err != nil { - return nil, err - } - mutation.id = &node.ID - mutation.done = true - return node, err - }) - for i := len(dtc.hooks) - 1; i >= 0; i-- { - if dtc.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = dtc.hooks[i](mut) - } - v, err := mut.Mutate(ctx, dtc.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*DeviceToken) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from DeviceTokenMutation", v) - } - node = nv - } - return node, err +func (_c *DeviceTokenCreate) Save(ctx context.Context) (*DeviceToken, error) { + _c.defaults() + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) } // SaveX calls Save and panics if Save returns an error. -func (dtc *DeviceTokenCreate) SaveX(ctx context.Context) *DeviceToken { - v, err := dtc.Save(ctx) +func (_c *DeviceTokenCreate) SaveX(ctx context.Context) *DeviceToken { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -147,69 +105,72 @@ func (dtc *DeviceTokenCreate) SaveX(ctx context.Context) *DeviceToken { } // Exec executes the query. -func (dtc *DeviceTokenCreate) Exec(ctx context.Context) error { - _, err := dtc.Save(ctx) +func (_c *DeviceTokenCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (dtc *DeviceTokenCreate) ExecX(ctx context.Context) { - if err := dtc.Exec(ctx); err != nil { +func (_c *DeviceTokenCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } // defaults sets the default values of the builder before save. -func (dtc *DeviceTokenCreate) defaults() { - if _, ok := dtc.mutation.CodeChallenge(); !ok { +func (_c *DeviceTokenCreate) defaults() { + if _, ok := _c.mutation.CodeChallenge(); !ok { v := devicetoken.DefaultCodeChallenge - dtc.mutation.SetCodeChallenge(v) + _c.mutation.SetCodeChallenge(v) } - if _, ok := dtc.mutation.CodeChallengeMethod(); !ok { + if _, ok := _c.mutation.CodeChallengeMethod(); !ok { v := devicetoken.DefaultCodeChallengeMethod - dtc.mutation.SetCodeChallengeMethod(v) + _c.mutation.SetCodeChallengeMethod(v) } } // check runs all checks and user-defined validators on the builder. -func (dtc *DeviceTokenCreate) check() error { - if _, ok := dtc.mutation.DeviceCode(); !ok { +func (_c *DeviceTokenCreate) check() error { + if _, ok := _c.mutation.DeviceCode(); !ok { return &ValidationError{Name: "device_code", err: errors.New(`db: missing required field "DeviceToken.device_code"`)} } - if v, ok := dtc.mutation.DeviceCode(); ok { + if v, ok := _c.mutation.DeviceCode(); ok { if err := devicetoken.DeviceCodeValidator(v); err != nil { return &ValidationError{Name: "device_code", err: fmt.Errorf(`db: validator failed for field "DeviceToken.device_code": %w`, err)} } } - if _, ok := dtc.mutation.Status(); !ok { + if _, ok := _c.mutation.Status(); !ok { return &ValidationError{Name: "status", err: errors.New(`db: missing required field "DeviceToken.status"`)} } - if v, ok := dtc.mutation.Status(); ok { + if v, ok := _c.mutation.Status(); ok { if err := devicetoken.StatusValidator(v); err != nil { return &ValidationError{Name: "status", err: fmt.Errorf(`db: validator failed for field "DeviceToken.status": %w`, err)} } } - if _, ok := dtc.mutation.Expiry(); !ok { + if _, ok := _c.mutation.Expiry(); !ok { return &ValidationError{Name: "expiry", err: errors.New(`db: missing required field "DeviceToken.expiry"`)} } - if _, ok := dtc.mutation.LastRequest(); !ok { + if _, ok := _c.mutation.LastRequest(); !ok { return &ValidationError{Name: "last_request", err: errors.New(`db: missing required field "DeviceToken.last_request"`)} } - if _, ok := dtc.mutation.PollInterval(); !ok { + if _, ok := _c.mutation.PollInterval(); !ok { return &ValidationError{Name: "poll_interval", err: errors.New(`db: missing required field "DeviceToken.poll_interval"`)} } - if _, ok := dtc.mutation.CodeChallenge(); !ok { + if _, ok := _c.mutation.CodeChallenge(); !ok { return &ValidationError{Name: "code_challenge", err: errors.New(`db: missing required field "DeviceToken.code_challenge"`)} } - if _, ok := dtc.mutation.CodeChallengeMethod(); !ok { + if _, ok := _c.mutation.CodeChallengeMethod(); !ok { return &ValidationError{Name: "code_challenge_method", err: errors.New(`db: missing required field "DeviceToken.code_challenge_method"`)} } return nil } -func (dtc *DeviceTokenCreate) sqlSave(ctx context.Context) (*DeviceToken, error) { - _node, _spec := dtc.createSpec() - if err := sqlgraph.CreateNode(ctx, dtc.driver, _spec); err != nil { +func (_c *DeviceTokenCreate) sqlSave(ctx context.Context) (*DeviceToken, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -217,82 +178,46 @@ func (dtc *DeviceTokenCreate) sqlSave(ctx context.Context) (*DeviceToken, error) } id := _spec.ID.Value.(int64) _node.ID = int(id) + _c.mutation.id = &_node.ID + _c.mutation.done = true return _node, nil } -func (dtc *DeviceTokenCreate) createSpec() (*DeviceToken, *sqlgraph.CreateSpec) { +func (_c *DeviceTokenCreate) createSpec() (*DeviceToken, *sqlgraph.CreateSpec) { var ( - _node = &DeviceToken{config: dtc.config} - _spec = &sqlgraph.CreateSpec{ - Table: devicetoken.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: devicetoken.FieldID, - }, - } + _node = &DeviceToken{config: _c.config} + _spec = sqlgraph.NewCreateSpec(devicetoken.Table, sqlgraph.NewFieldSpec(devicetoken.FieldID, field.TypeInt)) ) - if value, ok := dtc.mutation.DeviceCode(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicetoken.FieldDeviceCode, - }) + if value, ok := _c.mutation.DeviceCode(); ok { + _spec.SetField(devicetoken.FieldDeviceCode, field.TypeString, value) _node.DeviceCode = value } - if value, ok := dtc.mutation.Status(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicetoken.FieldStatus, - }) + if value, ok := _c.mutation.Status(); ok { + _spec.SetField(devicetoken.FieldStatus, field.TypeString, value) _node.Status = value } - if value, ok := dtc.mutation.Token(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: devicetoken.FieldToken, - }) + if value, ok := _c.mutation.Token(); ok { + _spec.SetField(devicetoken.FieldToken, field.TypeBytes, value) _node.Token = &value } - if value, ok := dtc.mutation.Expiry(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: devicetoken.FieldExpiry, - }) + if value, ok := _c.mutation.Expiry(); ok { + _spec.SetField(devicetoken.FieldExpiry, field.TypeTime, value) _node.Expiry = value } - if value, ok := dtc.mutation.LastRequest(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: devicetoken.FieldLastRequest, - }) + if value, ok := _c.mutation.LastRequest(); ok { + _spec.SetField(devicetoken.FieldLastRequest, field.TypeTime, value) _node.LastRequest = value } - if value, ok := dtc.mutation.PollInterval(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Value: value, - Column: devicetoken.FieldPollInterval, - }) + if value, ok := _c.mutation.PollInterval(); ok { + _spec.SetField(devicetoken.FieldPollInterval, field.TypeInt, value) _node.PollInterval = value } - if value, ok := dtc.mutation.CodeChallenge(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicetoken.FieldCodeChallenge, - }) + if value, ok := _c.mutation.CodeChallenge(); ok { + _spec.SetField(devicetoken.FieldCodeChallenge, field.TypeString, value) _node.CodeChallenge = value } - if value, ok := dtc.mutation.CodeChallengeMethod(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicetoken.FieldCodeChallengeMethod, - }) + if value, ok := _c.mutation.CodeChallengeMethod(); ok { + _spec.SetField(devicetoken.FieldCodeChallengeMethod, field.TypeString, value) _node.CodeChallengeMethod = value } return _node, _spec @@ -301,17 +226,21 @@ func (dtc *DeviceTokenCreate) createSpec() (*DeviceToken, *sqlgraph.CreateSpec) // DeviceTokenCreateBulk is the builder for creating many DeviceToken entities in bulk. type DeviceTokenCreateBulk struct { config + err error builders []*DeviceTokenCreate } // Save creates the DeviceToken entities in the database. -func (dtcb *DeviceTokenCreateBulk) Save(ctx context.Context) ([]*DeviceToken, error) { - specs := make([]*sqlgraph.CreateSpec, len(dtcb.builders)) - nodes := make([]*DeviceToken, len(dtcb.builders)) - mutators := make([]Mutator, len(dtcb.builders)) - for i := range dtcb.builders { +func (_c *DeviceTokenCreateBulk) Save(ctx context.Context) ([]*DeviceToken, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*DeviceToken, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { func(i int, root context.Context) { - builder := dtcb.builders[i] + builder := _c.builders[i] builder.defaults() var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { mutation, ok := m.(*DeviceTokenMutation) @@ -322,14 +251,14 @@ func (dtcb *DeviceTokenCreateBulk) Save(ctx context.Context) ([]*DeviceToken, er return nil, err } builder.mutation = mutation - nodes[i], specs[i] = builder.createSpec() var err error + nodes[i], specs[i] = builder.createSpec() if i < len(mutators)-1 { - _, err = mutators[i+1].Mutate(root, dtcb.builders[i+1].mutation) + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} // Invoke the actual operation on the latest mutation in the chain. - if err = sqlgraph.BatchCreate(ctx, dtcb.driver, spec); err != nil { + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -353,7 +282,7 @@ func (dtcb *DeviceTokenCreateBulk) Save(ctx context.Context) ([]*DeviceToken, er }(i, ctx) } if len(mutators) > 0 { - if _, err := mutators[0].Mutate(ctx, dtcb.builders[0].mutation); err != nil { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { return nil, err } } @@ -361,8 +290,8 @@ func (dtcb *DeviceTokenCreateBulk) Save(ctx context.Context) ([]*DeviceToken, er } // SaveX is like Save, but panics if an error occurs. -func (dtcb *DeviceTokenCreateBulk) SaveX(ctx context.Context) []*DeviceToken { - v, err := dtcb.Save(ctx) +func (_c *DeviceTokenCreateBulk) SaveX(ctx context.Context) []*DeviceToken { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -370,14 +299,14 @@ func (dtcb *DeviceTokenCreateBulk) SaveX(ctx context.Context) []*DeviceToken { } // Exec executes the query. -func (dtcb *DeviceTokenCreateBulk) Exec(ctx context.Context) error { - _, err := dtcb.Save(ctx) +func (_c *DeviceTokenCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (dtcb *DeviceTokenCreateBulk) ExecX(ctx context.Context) { - if err := dtcb.Exec(ctx); err != nil { +func (_c *DeviceTokenCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } diff --git a/storage/ent/db/devicetoken_delete.go b/storage/ent/db/devicetoken_delete.go index 3c196aac09..02acd31454 100644 --- a/storage/ent/db/devicetoken_delete.go +++ b/storage/ent/db/devicetoken_delete.go @@ -4,7 +4,6 @@ package db import ( "context" - "fmt" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" @@ -21,84 +20,56 @@ type DeviceTokenDelete struct { } // Where appends a list predicates to the DeviceTokenDelete builder. -func (dtd *DeviceTokenDelete) Where(ps ...predicate.DeviceToken) *DeviceTokenDelete { - dtd.mutation.Where(ps...) - return dtd +func (_d *DeviceTokenDelete) Where(ps ...predicate.DeviceToken) *DeviceTokenDelete { + _d.mutation.Where(ps...) + return _d } // Exec executes the deletion query and returns how many vertices were deleted. -func (dtd *DeviceTokenDelete) Exec(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(dtd.hooks) == 0 { - affected, err = dtd.sqlExec(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*DeviceTokenMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - dtd.mutation = mutation - affected, err = dtd.sqlExec(ctx) - mutation.done = true - return affected, err - }) - for i := len(dtd.hooks) - 1; i >= 0; i-- { - if dtd.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = dtd.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, dtd.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_d *DeviceTokenDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) } // ExecX is like Exec, but panics if an error occurs. -func (dtd *DeviceTokenDelete) ExecX(ctx context.Context) int { - n, err := dtd.Exec(ctx) +func (_d *DeviceTokenDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) if err != nil { panic(err) } return n } -func (dtd *DeviceTokenDelete) sqlExec(ctx context.Context) (int, error) { - _spec := &sqlgraph.DeleteSpec{ - Node: &sqlgraph.NodeSpec{ - Table: devicetoken.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: devicetoken.FieldID, - }, - }, - } - if ps := dtd.mutation.predicates; len(ps) > 0 { +func (_d *DeviceTokenDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(devicetoken.Table, sqlgraph.NewFieldSpec(devicetoken.FieldID, field.TypeInt)) + if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - affected, err := sqlgraph.DeleteNodes(ctx, dtd.driver, _spec) + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) if err != nil && sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } + _d.mutation.done = true return affected, err } // DeviceTokenDeleteOne is the builder for deleting a single DeviceToken entity. type DeviceTokenDeleteOne struct { - dtd *DeviceTokenDelete + _d *DeviceTokenDelete +} + +// Where appends a list predicates to the DeviceTokenDelete builder. +func (_d *DeviceTokenDeleteOne) Where(ps ...predicate.DeviceToken) *DeviceTokenDeleteOne { + _d._d.mutation.Where(ps...) + return _d } // Exec executes the deletion query. -func (dtdo *DeviceTokenDeleteOne) Exec(ctx context.Context) error { - n, err := dtdo.dtd.Exec(ctx) +func (_d *DeviceTokenDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) switch { case err != nil: return err @@ -110,6 +81,8 @@ func (dtdo *DeviceTokenDeleteOne) Exec(ctx context.Context) error { } // ExecX is like Exec, but panics if an error occurs. -func (dtdo *DeviceTokenDeleteOne) ExecX(ctx context.Context) { - dtdo.dtd.ExecX(ctx) +func (_d *DeviceTokenDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } } diff --git a/storage/ent/db/devicetoken_query.go b/storage/ent/db/devicetoken_query.go index 1860a841ad..af910afdc6 100644 --- a/storage/ent/db/devicetoken_query.go +++ b/storage/ent/db/devicetoken_query.go @@ -7,6 +7,7 @@ import ( "fmt" "math" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" @@ -17,11 +18,9 @@ import ( // DeviceTokenQuery is the builder for querying DeviceToken entities. type DeviceTokenQuery struct { config - limit *int - offset *int - unique *bool - order []OrderFunc - fields []string + ctx *QueryContext + order []devicetoken.OrderOption + inters []Interceptor predicates []predicate.DeviceToken // intermediate query (i.e. traversal path). sql *sql.Selector @@ -29,40 +28,40 @@ type DeviceTokenQuery struct { } // Where adds a new predicate for the DeviceTokenQuery builder. -func (dtq *DeviceTokenQuery) Where(ps ...predicate.DeviceToken) *DeviceTokenQuery { - dtq.predicates = append(dtq.predicates, ps...) - return dtq +func (_q *DeviceTokenQuery) Where(ps ...predicate.DeviceToken) *DeviceTokenQuery { + _q.predicates = append(_q.predicates, ps...) + return _q } -// Limit adds a limit step to the query. -func (dtq *DeviceTokenQuery) Limit(limit int) *DeviceTokenQuery { - dtq.limit = &limit - return dtq +// Limit the number of records to be returned by this query. +func (_q *DeviceTokenQuery) Limit(limit int) *DeviceTokenQuery { + _q.ctx.Limit = &limit + return _q } -// Offset adds an offset step to the query. -func (dtq *DeviceTokenQuery) Offset(offset int) *DeviceTokenQuery { - dtq.offset = &offset - return dtq +// Offset to start from. +func (_q *DeviceTokenQuery) Offset(offset int) *DeviceTokenQuery { + _q.ctx.Offset = &offset + return _q } // Unique configures the query builder to filter duplicate records on query. // By default, unique is set to true, and can be disabled using this method. -func (dtq *DeviceTokenQuery) Unique(unique bool) *DeviceTokenQuery { - dtq.unique = &unique - return dtq +func (_q *DeviceTokenQuery) Unique(unique bool) *DeviceTokenQuery { + _q.ctx.Unique = &unique + return _q } -// Order adds an order step to the query. -func (dtq *DeviceTokenQuery) Order(o ...OrderFunc) *DeviceTokenQuery { - dtq.order = append(dtq.order, o...) - return dtq +// Order specifies how the records should be ordered. +func (_q *DeviceTokenQuery) Order(o ...devicetoken.OrderOption) *DeviceTokenQuery { + _q.order = append(_q.order, o...) + return _q } // First returns the first DeviceToken entity from the query. // Returns a *NotFoundError when no DeviceToken was found. -func (dtq *DeviceTokenQuery) First(ctx context.Context) (*DeviceToken, error) { - nodes, err := dtq.Limit(1).All(ctx) +func (_q *DeviceTokenQuery) First(ctx context.Context) (*DeviceToken, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) if err != nil { return nil, err } @@ -73,8 +72,8 @@ func (dtq *DeviceTokenQuery) First(ctx context.Context) (*DeviceToken, error) { } // FirstX is like First, but panics if an error occurs. -func (dtq *DeviceTokenQuery) FirstX(ctx context.Context) *DeviceToken { - node, err := dtq.First(ctx) +func (_q *DeviceTokenQuery) FirstX(ctx context.Context) *DeviceToken { + node, err := _q.First(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -83,9 +82,9 @@ func (dtq *DeviceTokenQuery) FirstX(ctx context.Context) *DeviceToken { // FirstID returns the first DeviceToken ID from the query. // Returns a *NotFoundError when no DeviceToken ID was found. -func (dtq *DeviceTokenQuery) FirstID(ctx context.Context) (id int, err error) { +func (_q *DeviceTokenQuery) FirstID(ctx context.Context) (id int, err error) { var ids []int - if ids, err = dtq.Limit(1).IDs(ctx); err != nil { + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { return } if len(ids) == 0 { @@ -96,8 +95,8 @@ func (dtq *DeviceTokenQuery) FirstID(ctx context.Context) (id int, err error) { } // FirstIDX is like FirstID, but panics if an error occurs. -func (dtq *DeviceTokenQuery) FirstIDX(ctx context.Context) int { - id, err := dtq.FirstID(ctx) +func (_q *DeviceTokenQuery) FirstIDX(ctx context.Context) int { + id, err := _q.FirstID(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -107,8 +106,8 @@ func (dtq *DeviceTokenQuery) FirstIDX(ctx context.Context) int { // Only returns a single DeviceToken entity found by the query, ensuring it only returns one. // Returns a *NotSingularError when more than one DeviceToken entity is found. // Returns a *NotFoundError when no DeviceToken entities are found. -func (dtq *DeviceTokenQuery) Only(ctx context.Context) (*DeviceToken, error) { - nodes, err := dtq.Limit(2).All(ctx) +func (_q *DeviceTokenQuery) Only(ctx context.Context) (*DeviceToken, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) if err != nil { return nil, err } @@ -123,8 +122,8 @@ func (dtq *DeviceTokenQuery) Only(ctx context.Context) (*DeviceToken, error) { } // OnlyX is like Only, but panics if an error occurs. -func (dtq *DeviceTokenQuery) OnlyX(ctx context.Context) *DeviceToken { - node, err := dtq.Only(ctx) +func (_q *DeviceTokenQuery) OnlyX(ctx context.Context) *DeviceToken { + node, err := _q.Only(ctx) if err != nil { panic(err) } @@ -134,9 +133,9 @@ func (dtq *DeviceTokenQuery) OnlyX(ctx context.Context) *DeviceToken { // OnlyID is like Only, but returns the only DeviceToken ID in the query. // Returns a *NotSingularError when more than one DeviceToken ID is found. // Returns a *NotFoundError when no entities are found. -func (dtq *DeviceTokenQuery) OnlyID(ctx context.Context) (id int, err error) { +func (_q *DeviceTokenQuery) OnlyID(ctx context.Context) (id int, err error) { var ids []int - if ids, err = dtq.Limit(2).IDs(ctx); err != nil { + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { return } switch len(ids) { @@ -151,8 +150,8 @@ func (dtq *DeviceTokenQuery) OnlyID(ctx context.Context) (id int, err error) { } // OnlyIDX is like OnlyID, but panics if an error occurs. -func (dtq *DeviceTokenQuery) OnlyIDX(ctx context.Context) int { - id, err := dtq.OnlyID(ctx) +func (_q *DeviceTokenQuery) OnlyIDX(ctx context.Context) int { + id, err := _q.OnlyID(ctx) if err != nil { panic(err) } @@ -160,16 +159,18 @@ func (dtq *DeviceTokenQuery) OnlyIDX(ctx context.Context) int { } // All executes the query and returns a list of DeviceTokens. -func (dtq *DeviceTokenQuery) All(ctx context.Context) ([]*DeviceToken, error) { - if err := dtq.prepareQuery(ctx); err != nil { +func (_q *DeviceTokenQuery) All(ctx context.Context) ([]*DeviceToken, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { return nil, err } - return dtq.sqlAll(ctx) + qr := querierAll[[]*DeviceToken, *DeviceTokenQuery]() + return withInterceptors[[]*DeviceToken](ctx, _q, qr, _q.inters) } // AllX is like All, but panics if an error occurs. -func (dtq *DeviceTokenQuery) AllX(ctx context.Context) []*DeviceToken { - nodes, err := dtq.All(ctx) +func (_q *DeviceTokenQuery) AllX(ctx context.Context) []*DeviceToken { + nodes, err := _q.All(ctx) if err != nil { panic(err) } @@ -177,17 +178,20 @@ func (dtq *DeviceTokenQuery) AllX(ctx context.Context) []*DeviceToken { } // IDs executes the query and returns a list of DeviceToken IDs. -func (dtq *DeviceTokenQuery) IDs(ctx context.Context) ([]int, error) { - var ids []int - if err := dtq.Select(devicetoken.FieldID).Scan(ctx, &ids); err != nil { +func (_q *DeviceTokenQuery) IDs(ctx context.Context) (ids []int, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(devicetoken.FieldID).Scan(ctx, &ids); err != nil { return nil, err } return ids, nil } // IDsX is like IDs, but panics if an error occurs. -func (dtq *DeviceTokenQuery) IDsX(ctx context.Context) []int { - ids, err := dtq.IDs(ctx) +func (_q *DeviceTokenQuery) IDsX(ctx context.Context) []int { + ids, err := _q.IDs(ctx) if err != nil { panic(err) } @@ -195,16 +199,17 @@ func (dtq *DeviceTokenQuery) IDsX(ctx context.Context) []int { } // Count returns the count of the given query. -func (dtq *DeviceTokenQuery) Count(ctx context.Context) (int, error) { - if err := dtq.prepareQuery(ctx); err != nil { +func (_q *DeviceTokenQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { return 0, err } - return dtq.sqlCount(ctx) + return withInterceptors[int](ctx, _q, querierCount[*DeviceTokenQuery](), _q.inters) } // CountX is like Count, but panics if an error occurs. -func (dtq *DeviceTokenQuery) CountX(ctx context.Context) int { - count, err := dtq.Count(ctx) +func (_q *DeviceTokenQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) if err != nil { panic(err) } @@ -212,16 +217,21 @@ func (dtq *DeviceTokenQuery) CountX(ctx context.Context) int { } // Exist returns true if the query has elements in the graph. -func (dtq *DeviceTokenQuery) Exist(ctx context.Context) (bool, error) { - if err := dtq.prepareQuery(ctx); err != nil { - return false, err +func (_q *DeviceTokenQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("db: check existence: %w", err) + default: + return true, nil } - return dtq.sqlExist(ctx) } // ExistX is like Exist, but panics if an error occurs. -func (dtq *DeviceTokenQuery) ExistX(ctx context.Context) bool { - exist, err := dtq.Exist(ctx) +func (_q *DeviceTokenQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) if err != nil { panic(err) } @@ -230,20 +240,19 @@ func (dtq *DeviceTokenQuery) ExistX(ctx context.Context) bool { // Clone returns a duplicate of the DeviceTokenQuery builder, including all associated steps. It can be // used to prepare common query builders and use them differently after the clone is made. -func (dtq *DeviceTokenQuery) Clone() *DeviceTokenQuery { - if dtq == nil { +func (_q *DeviceTokenQuery) Clone() *DeviceTokenQuery { + if _q == nil { return nil } return &DeviceTokenQuery{ - config: dtq.config, - limit: dtq.limit, - offset: dtq.offset, - order: append([]OrderFunc{}, dtq.order...), - predicates: append([]predicate.DeviceToken{}, dtq.predicates...), + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]devicetoken.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.DeviceToken{}, _q.predicates...), // clone intermediate query. - sql: dtq.sql.Clone(), - path: dtq.path, - unique: dtq.unique, + sql: _q.sql.Clone(), + path: _q.path, } } @@ -261,18 +270,12 @@ func (dtq *DeviceTokenQuery) Clone() *DeviceTokenQuery { // GroupBy(devicetoken.FieldDeviceCode). // Aggregate(db.Count()). // Scan(ctx, &v) -// -func (dtq *DeviceTokenQuery) GroupBy(field string, fields ...string) *DeviceTokenGroupBy { - grbuild := &DeviceTokenGroupBy{config: dtq.config} - grbuild.fields = append([]string{field}, fields...) - grbuild.path = func(ctx context.Context) (prev *sql.Selector, err error) { - if err := dtq.prepareQuery(ctx); err != nil { - return nil, err - } - return dtq.sqlQuery(ctx), nil - } +func (_q *DeviceTokenQuery) GroupBy(field string, fields ...string) *DeviceTokenGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &DeviceTokenGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields grbuild.label = devicetoken.Label - grbuild.flds, grbuild.scan = &grbuild.fields, grbuild.Scan + grbuild.scan = grbuild.Scan return grbuild } @@ -288,48 +291,62 @@ func (dtq *DeviceTokenQuery) GroupBy(field string, fields ...string) *DeviceToke // client.DeviceToken.Query(). // Select(devicetoken.FieldDeviceCode). // Scan(ctx, &v) -// -func (dtq *DeviceTokenQuery) Select(fields ...string) *DeviceTokenSelect { - dtq.fields = append(dtq.fields, fields...) - selbuild := &DeviceTokenSelect{DeviceTokenQuery: dtq} - selbuild.label = devicetoken.Label - selbuild.flds, selbuild.scan = &dtq.fields, selbuild.Scan - return selbuild +func (_q *DeviceTokenQuery) Select(fields ...string) *DeviceTokenSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &DeviceTokenSelect{DeviceTokenQuery: _q} + sbuild.label = devicetoken.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a DeviceTokenSelect configured with the given aggregations. +func (_q *DeviceTokenQuery) Aggregate(fns ...AggregateFunc) *DeviceTokenSelect { + return _q.Select().Aggregate(fns...) } -func (dtq *DeviceTokenQuery) prepareQuery(ctx context.Context) error { - for _, f := range dtq.fields { +func (_q *DeviceTokenQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("db: uninitialized interceptor (forgotten import db/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { if !devicetoken.ValidColumn(f) { return &ValidationError{Name: f, err: fmt.Errorf("db: invalid field %q for query", f)} } } - if dtq.path != nil { - prev, err := dtq.path(ctx) + if _q.path != nil { + prev, err := _q.path(ctx) if err != nil { return err } - dtq.sql = prev + _q.sql = prev } return nil } -func (dtq *DeviceTokenQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*DeviceToken, error) { +func (_q *DeviceTokenQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*DeviceToken, error) { var ( nodes = []*DeviceToken{} - _spec = dtq.querySpec() + _spec = _q.querySpec() ) - _spec.ScanValues = func(columns []string) ([]interface{}, error) { + _spec.ScanValues = func(columns []string) ([]any, error) { return (*DeviceToken).scanValues(nil, columns) } - _spec.Assign = func(columns []string, values []interface{}) error { - node := &DeviceToken{config: dtq.config} + _spec.Assign = func(columns []string, values []any) error { + node := &DeviceToken{config: _q.config} nodes = append(nodes, node) return node.assignValues(columns, values) } for i := range hooks { hooks[i](ctx, _spec) } - if err := sqlgraph.QueryNodes(ctx, dtq.driver, _spec); err != nil { + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { return nil, err } if len(nodes) == 0 { @@ -338,40 +355,24 @@ func (dtq *DeviceTokenQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([] return nodes, nil } -func (dtq *DeviceTokenQuery) sqlCount(ctx context.Context) (int, error) { - _spec := dtq.querySpec() - _spec.Node.Columns = dtq.fields - if len(dtq.fields) > 0 { - _spec.Unique = dtq.unique != nil && *dtq.unique - } - return sqlgraph.CountNodes(ctx, dtq.driver, _spec) -} - -func (dtq *DeviceTokenQuery) sqlExist(ctx context.Context) (bool, error) { - n, err := dtq.sqlCount(ctx) - if err != nil { - return false, fmt.Errorf("db: check existence: %w", err) +func (_q *DeviceTokenQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique } - return n > 0, nil + return sqlgraph.CountNodes(ctx, _q.driver, _spec) } -func (dtq *DeviceTokenQuery) querySpec() *sqlgraph.QuerySpec { - _spec := &sqlgraph.QuerySpec{ - Node: &sqlgraph.NodeSpec{ - Table: devicetoken.Table, - Columns: devicetoken.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: devicetoken.FieldID, - }, - }, - From: dtq.sql, - Unique: true, - } - if unique := dtq.unique; unique != nil { +func (_q *DeviceTokenQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(devicetoken.Table, devicetoken.Columns, sqlgraph.NewFieldSpec(devicetoken.FieldID, field.TypeInt)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true } - if fields := dtq.fields; len(fields) > 0 { + if fields := _q.ctx.Fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, devicetoken.FieldID) for i := range fields { @@ -380,20 +381,20 @@ func (dtq *DeviceTokenQuery) querySpec() *sqlgraph.QuerySpec { } } } - if ps := dtq.predicates; len(ps) > 0 { + if ps := _q.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if limit := dtq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { _spec.Limit = *limit } - if offset := dtq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { _spec.Offset = *offset } - if ps := dtq.order; len(ps) > 0 { + if ps := _q.order; len(ps) > 0 { _spec.Order = func(selector *sql.Selector) { for i := range ps { ps[i](selector) @@ -403,33 +404,33 @@ func (dtq *DeviceTokenQuery) querySpec() *sqlgraph.QuerySpec { return _spec } -func (dtq *DeviceTokenQuery) sqlQuery(ctx context.Context) *sql.Selector { - builder := sql.Dialect(dtq.driver.Dialect()) +func (_q *DeviceTokenQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) t1 := builder.Table(devicetoken.Table) - columns := dtq.fields + columns := _q.ctx.Fields if len(columns) == 0 { columns = devicetoken.Columns } selector := builder.Select(t1.Columns(columns...)...).From(t1) - if dtq.sql != nil { - selector = dtq.sql + if _q.sql != nil { + selector = _q.sql selector.Select(selector.Columns(columns...)...) } - if dtq.unique != nil && *dtq.unique { + if _q.ctx.Unique != nil && *_q.ctx.Unique { selector.Distinct() } - for _, p := range dtq.predicates { + for _, p := range _q.predicates { p(selector) } - for _, p := range dtq.order { + for _, p := range _q.order { p(selector) } - if offset := dtq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { // limit is mandatory for offset clause. We start // with default value, and override it below if needed. selector.Offset(*offset).Limit(math.MaxInt32) } - if limit := dtq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { selector.Limit(*limit) } return selector @@ -437,90 +438,88 @@ func (dtq *DeviceTokenQuery) sqlQuery(ctx context.Context) *sql.Selector { // DeviceTokenGroupBy is the group-by builder for DeviceToken entities. type DeviceTokenGroupBy struct { - config selector - fields []string - fns []AggregateFunc - // intermediate query (i.e. traversal path). - sql *sql.Selector - path func(context.Context) (*sql.Selector, error) + build *DeviceTokenQuery } // Aggregate adds the given aggregation functions to the group-by query. -func (dtgb *DeviceTokenGroupBy) Aggregate(fns ...AggregateFunc) *DeviceTokenGroupBy { - dtgb.fns = append(dtgb.fns, fns...) - return dtgb +func (_g *DeviceTokenGroupBy) Aggregate(fns ...AggregateFunc) *DeviceTokenGroupBy { + _g.fns = append(_g.fns, fns...) + return _g } -// Scan applies the group-by query and scans the result into the given value. -func (dtgb *DeviceTokenGroupBy) Scan(ctx context.Context, v interface{}) error { - query, err := dtgb.path(ctx) - if err != nil { +// Scan applies the selector query and scans the result into the given value. +func (_g *DeviceTokenGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { return err } - dtgb.sql = query - return dtgb.sqlScan(ctx, v) + return scanWithInterceptors[*DeviceTokenQuery, *DeviceTokenGroupBy](ctx, _g.build, _g, _g.build.inters, v) } -func (dtgb *DeviceTokenGroupBy) sqlScan(ctx context.Context, v interface{}) error { - for _, f := range dtgb.fields { - if !devicetoken.ValidColumn(f) { - return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)} +func (_g *DeviceTokenGroupBy) sqlScan(ctx context.Context, root *DeviceTokenQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) } + columns = append(columns, aggregation...) + selector.Select(columns...) } - selector := dtgb.sqlQuery() + selector.GroupBy(selector.Columns(*_g.flds...)...) if err := selector.Err(); err != nil { return err } rows := &sql.Rows{} query, args := selector.Query() - if err := dtgb.driver.Query(ctx, query, args, rows); err != nil { + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() return sql.ScanSlice(rows, v) } -func (dtgb *DeviceTokenGroupBy) sqlQuery() *sql.Selector { - selector := dtgb.sql.Select() - aggregation := make([]string, 0, len(dtgb.fns)) - for _, fn := range dtgb.fns { - aggregation = append(aggregation, fn(selector)) - } - // If no columns were selected in a custom aggregation function, the default - // selection is the fields used for "group-by", and the aggregation functions. - if len(selector.SelectedColumns()) == 0 { - columns := make([]string, 0, len(dtgb.fields)+len(dtgb.fns)) - for _, f := range dtgb.fields { - columns = append(columns, selector.C(f)) - } - columns = append(columns, aggregation...) - selector.Select(columns...) - } - return selector.GroupBy(selector.Columns(dtgb.fields...)...) -} - // DeviceTokenSelect is the builder for selecting fields of DeviceToken entities. type DeviceTokenSelect struct { *DeviceTokenQuery selector - // intermediate query (i.e. traversal path). - sql *sql.Selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *DeviceTokenSelect) Aggregate(fns ...AggregateFunc) *DeviceTokenSelect { + _s.fns = append(_s.fns, fns...) + return _s } // Scan applies the selector query and scans the result into the given value. -func (dts *DeviceTokenSelect) Scan(ctx context.Context, v interface{}) error { - if err := dts.prepareQuery(ctx); err != nil { +func (_s *DeviceTokenSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { return err } - dts.sql = dts.DeviceTokenQuery.sqlQuery(ctx) - return dts.sqlScan(ctx, v) + return scanWithInterceptors[*DeviceTokenQuery, *DeviceTokenSelect](ctx, _s.DeviceTokenQuery, _s, _s.inters, v) } -func (dts *DeviceTokenSelect) sqlScan(ctx context.Context, v interface{}) error { +func (_s *DeviceTokenSelect) sqlScan(ctx context.Context, root *DeviceTokenQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } rows := &sql.Rows{} - query, args := dts.sql.Query() - if err := dts.driver.Query(ctx, query, args, rows); err != nil { + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() diff --git a/storage/ent/db/devicetoken_update.go b/storage/ent/db/devicetoken_update.go index cc0b92f5ba..024beb35d1 100644 --- a/storage/ent/db/devicetoken_update.go +++ b/storage/ent/db/devicetoken_update.go @@ -23,134 +23,141 @@ type DeviceTokenUpdate struct { } // Where appends a list predicates to the DeviceTokenUpdate builder. -func (dtu *DeviceTokenUpdate) Where(ps ...predicate.DeviceToken) *DeviceTokenUpdate { - dtu.mutation.Where(ps...) - return dtu +func (_u *DeviceTokenUpdate) Where(ps ...predicate.DeviceToken) *DeviceTokenUpdate { + _u.mutation.Where(ps...) + return _u } // SetDeviceCode sets the "device_code" field. -func (dtu *DeviceTokenUpdate) SetDeviceCode(s string) *DeviceTokenUpdate { - dtu.mutation.SetDeviceCode(s) - return dtu +func (_u *DeviceTokenUpdate) SetDeviceCode(v string) *DeviceTokenUpdate { + _u.mutation.SetDeviceCode(v) + return _u +} + +// SetNillableDeviceCode sets the "device_code" field if the given value is not nil. +func (_u *DeviceTokenUpdate) SetNillableDeviceCode(v *string) *DeviceTokenUpdate { + if v != nil { + _u.SetDeviceCode(*v) + } + return _u } // SetStatus sets the "status" field. -func (dtu *DeviceTokenUpdate) SetStatus(s string) *DeviceTokenUpdate { - dtu.mutation.SetStatus(s) - return dtu +func (_u *DeviceTokenUpdate) SetStatus(v string) *DeviceTokenUpdate { + _u.mutation.SetStatus(v) + return _u +} + +// SetNillableStatus sets the "status" field if the given value is not nil. +func (_u *DeviceTokenUpdate) SetNillableStatus(v *string) *DeviceTokenUpdate { + if v != nil { + _u.SetStatus(*v) + } + return _u } // SetToken sets the "token" field. -func (dtu *DeviceTokenUpdate) SetToken(b []byte) *DeviceTokenUpdate { - dtu.mutation.SetToken(b) - return dtu +func (_u *DeviceTokenUpdate) SetToken(v []byte) *DeviceTokenUpdate { + _u.mutation.SetToken(v) + return _u } // ClearToken clears the value of the "token" field. -func (dtu *DeviceTokenUpdate) ClearToken() *DeviceTokenUpdate { - dtu.mutation.ClearToken() - return dtu +func (_u *DeviceTokenUpdate) ClearToken() *DeviceTokenUpdate { + _u.mutation.ClearToken() + return _u } // SetExpiry sets the "expiry" field. -func (dtu *DeviceTokenUpdate) SetExpiry(t time.Time) *DeviceTokenUpdate { - dtu.mutation.SetExpiry(t) - return dtu +func (_u *DeviceTokenUpdate) SetExpiry(v time.Time) *DeviceTokenUpdate { + _u.mutation.SetExpiry(v) + return _u +} + +// SetNillableExpiry sets the "expiry" field if the given value is not nil. +func (_u *DeviceTokenUpdate) SetNillableExpiry(v *time.Time) *DeviceTokenUpdate { + if v != nil { + _u.SetExpiry(*v) + } + return _u } // SetLastRequest sets the "last_request" field. -func (dtu *DeviceTokenUpdate) SetLastRequest(t time.Time) *DeviceTokenUpdate { - dtu.mutation.SetLastRequest(t) - return dtu +func (_u *DeviceTokenUpdate) SetLastRequest(v time.Time) *DeviceTokenUpdate { + _u.mutation.SetLastRequest(v) + return _u +} + +// SetNillableLastRequest sets the "last_request" field if the given value is not nil. +func (_u *DeviceTokenUpdate) SetNillableLastRequest(v *time.Time) *DeviceTokenUpdate { + if v != nil { + _u.SetLastRequest(*v) + } + return _u } // SetPollInterval sets the "poll_interval" field. -func (dtu *DeviceTokenUpdate) SetPollInterval(i int) *DeviceTokenUpdate { - dtu.mutation.ResetPollInterval() - dtu.mutation.SetPollInterval(i) - return dtu +func (_u *DeviceTokenUpdate) SetPollInterval(v int) *DeviceTokenUpdate { + _u.mutation.ResetPollInterval() + _u.mutation.SetPollInterval(v) + return _u } -// AddPollInterval adds i to the "poll_interval" field. -func (dtu *DeviceTokenUpdate) AddPollInterval(i int) *DeviceTokenUpdate { - dtu.mutation.AddPollInterval(i) - return dtu +// SetNillablePollInterval sets the "poll_interval" field if the given value is not nil. +func (_u *DeviceTokenUpdate) SetNillablePollInterval(v *int) *DeviceTokenUpdate { + if v != nil { + _u.SetPollInterval(*v) + } + return _u +} + +// AddPollInterval adds value to the "poll_interval" field. +func (_u *DeviceTokenUpdate) AddPollInterval(v int) *DeviceTokenUpdate { + _u.mutation.AddPollInterval(v) + return _u } // SetCodeChallenge sets the "code_challenge" field. -func (dtu *DeviceTokenUpdate) SetCodeChallenge(s string) *DeviceTokenUpdate { - dtu.mutation.SetCodeChallenge(s) - return dtu +func (_u *DeviceTokenUpdate) SetCodeChallenge(v string) *DeviceTokenUpdate { + _u.mutation.SetCodeChallenge(v) + return _u } // SetNillableCodeChallenge sets the "code_challenge" field if the given value is not nil. -func (dtu *DeviceTokenUpdate) SetNillableCodeChallenge(s *string) *DeviceTokenUpdate { - if s != nil { - dtu.SetCodeChallenge(*s) +func (_u *DeviceTokenUpdate) SetNillableCodeChallenge(v *string) *DeviceTokenUpdate { + if v != nil { + _u.SetCodeChallenge(*v) } - return dtu + return _u } // SetCodeChallengeMethod sets the "code_challenge_method" field. -func (dtu *DeviceTokenUpdate) SetCodeChallengeMethod(s string) *DeviceTokenUpdate { - dtu.mutation.SetCodeChallengeMethod(s) - return dtu +func (_u *DeviceTokenUpdate) SetCodeChallengeMethod(v string) *DeviceTokenUpdate { + _u.mutation.SetCodeChallengeMethod(v) + return _u } // SetNillableCodeChallengeMethod sets the "code_challenge_method" field if the given value is not nil. -func (dtu *DeviceTokenUpdate) SetNillableCodeChallengeMethod(s *string) *DeviceTokenUpdate { - if s != nil { - dtu.SetCodeChallengeMethod(*s) +func (_u *DeviceTokenUpdate) SetNillableCodeChallengeMethod(v *string) *DeviceTokenUpdate { + if v != nil { + _u.SetCodeChallengeMethod(*v) } - return dtu + return _u } // Mutation returns the DeviceTokenMutation object of the builder. -func (dtu *DeviceTokenUpdate) Mutation() *DeviceTokenMutation { - return dtu.mutation +func (_u *DeviceTokenUpdate) Mutation() *DeviceTokenMutation { + return _u.mutation } // Save executes the query and returns the number of nodes affected by the update operation. -func (dtu *DeviceTokenUpdate) Save(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(dtu.hooks) == 0 { - if err = dtu.check(); err != nil { - return 0, err - } - affected, err = dtu.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*DeviceTokenMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = dtu.check(); err != nil { - return 0, err - } - dtu.mutation = mutation - affected, err = dtu.sqlSave(ctx) - mutation.done = true - return affected, err - }) - for i := len(dtu.hooks) - 1; i >= 0; i-- { - if dtu.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = dtu.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, dtu.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_u *DeviceTokenUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (dtu *DeviceTokenUpdate) SaveX(ctx context.Context) int { - affected, err := dtu.Save(ctx) +func (_u *DeviceTokenUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) if err != nil { panic(err) } @@ -158,26 +165,26 @@ func (dtu *DeviceTokenUpdate) SaveX(ctx context.Context) int { } // Exec executes the query. -func (dtu *DeviceTokenUpdate) Exec(ctx context.Context) error { - _, err := dtu.Save(ctx) +func (_u *DeviceTokenUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (dtu *DeviceTokenUpdate) ExecX(ctx context.Context) { - if err := dtu.Exec(ctx); err != nil { +func (_u *DeviceTokenUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (dtu *DeviceTokenUpdate) check() error { - if v, ok := dtu.mutation.DeviceCode(); ok { +func (_u *DeviceTokenUpdate) check() error { + if v, ok := _u.mutation.DeviceCode(); ok { if err := devicetoken.DeviceCodeValidator(v); err != nil { return &ValidationError{Name: "device_code", err: fmt.Errorf(`db: validator failed for field "DeviceToken.device_code": %w`, err)} } } - if v, ok := dtu.mutation.Status(); ok { + if v, ok := _u.mutation.Status(); ok { if err := devicetoken.StatusValidator(v); err != nil { return &ValidationError{Name: "status", err: fmt.Errorf(`db: validator failed for field "DeviceToken.status": %w`, err)} } @@ -185,94 +192,49 @@ func (dtu *DeviceTokenUpdate) check() error { return nil } -func (dtu *DeviceTokenUpdate) sqlSave(ctx context.Context) (n int, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: devicetoken.Table, - Columns: devicetoken.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: devicetoken.FieldID, - }, - }, +func (_u *DeviceTokenUpdate) sqlSave(ctx context.Context) (_node int, err error) { + if err := _u.check(); err != nil { + return _node, err } - if ps := dtu.mutation.predicates; len(ps) > 0 { + _spec := sqlgraph.NewUpdateSpec(devicetoken.Table, devicetoken.Columns, sqlgraph.NewFieldSpec(devicetoken.FieldID, field.TypeInt)) + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := dtu.mutation.DeviceCode(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicetoken.FieldDeviceCode, - }) - } - if value, ok := dtu.mutation.Status(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicetoken.FieldStatus, - }) - } - if value, ok := dtu.mutation.Token(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: devicetoken.FieldToken, - }) - } - if dtu.mutation.TokenCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Column: devicetoken.FieldToken, - }) - } - if value, ok := dtu.mutation.Expiry(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: devicetoken.FieldExpiry, - }) - } - if value, ok := dtu.mutation.LastRequest(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: devicetoken.FieldLastRequest, - }) - } - if value, ok := dtu.mutation.PollInterval(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Value: value, - Column: devicetoken.FieldPollInterval, - }) - } - if value, ok := dtu.mutation.AddedPollInterval(); ok { - _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Value: value, - Column: devicetoken.FieldPollInterval, - }) - } - if value, ok := dtu.mutation.CodeChallenge(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicetoken.FieldCodeChallenge, - }) - } - if value, ok := dtu.mutation.CodeChallengeMethod(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicetoken.FieldCodeChallengeMethod, - }) - } - if n, err = sqlgraph.UpdateNodes(ctx, dtu.driver, _spec); err != nil { + if value, ok := _u.mutation.DeviceCode(); ok { + _spec.SetField(devicetoken.FieldDeviceCode, field.TypeString, value) + } + if value, ok := _u.mutation.Status(); ok { + _spec.SetField(devicetoken.FieldStatus, field.TypeString, value) + } + if value, ok := _u.mutation.Token(); ok { + _spec.SetField(devicetoken.FieldToken, field.TypeBytes, value) + } + if _u.mutation.TokenCleared() { + _spec.ClearField(devicetoken.FieldToken, field.TypeBytes) + } + if value, ok := _u.mutation.Expiry(); ok { + _spec.SetField(devicetoken.FieldExpiry, field.TypeTime, value) + } + if value, ok := _u.mutation.LastRequest(); ok { + _spec.SetField(devicetoken.FieldLastRequest, field.TypeTime, value) + } + if value, ok := _u.mutation.PollInterval(); ok { + _spec.SetField(devicetoken.FieldPollInterval, field.TypeInt, value) + } + if value, ok := _u.mutation.AddedPollInterval(); ok { + _spec.AddField(devicetoken.FieldPollInterval, field.TypeInt, value) + } + if value, ok := _u.mutation.CodeChallenge(); ok { + _spec.SetField(devicetoken.FieldCodeChallenge, field.TypeString, value) + } + if value, ok := _u.mutation.CodeChallengeMethod(); ok { + _spec.SetField(devicetoken.FieldCodeChallengeMethod, field.TypeString, value) + } + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{devicetoken.Label} } else if sqlgraph.IsConstraintError(err) { @@ -280,7 +242,8 @@ func (dtu *DeviceTokenUpdate) sqlSave(ctx context.Context) (n int, err error) { } return 0, err } - return n, nil + _u.mutation.done = true + return _node, nil } // DeviceTokenUpdateOne is the builder for updating a single DeviceToken entity. @@ -292,141 +255,148 @@ type DeviceTokenUpdateOne struct { } // SetDeviceCode sets the "device_code" field. -func (dtuo *DeviceTokenUpdateOne) SetDeviceCode(s string) *DeviceTokenUpdateOne { - dtuo.mutation.SetDeviceCode(s) - return dtuo +func (_u *DeviceTokenUpdateOne) SetDeviceCode(v string) *DeviceTokenUpdateOne { + _u.mutation.SetDeviceCode(v) + return _u +} + +// SetNillableDeviceCode sets the "device_code" field if the given value is not nil. +func (_u *DeviceTokenUpdateOne) SetNillableDeviceCode(v *string) *DeviceTokenUpdateOne { + if v != nil { + _u.SetDeviceCode(*v) + } + return _u } // SetStatus sets the "status" field. -func (dtuo *DeviceTokenUpdateOne) SetStatus(s string) *DeviceTokenUpdateOne { - dtuo.mutation.SetStatus(s) - return dtuo +func (_u *DeviceTokenUpdateOne) SetStatus(v string) *DeviceTokenUpdateOne { + _u.mutation.SetStatus(v) + return _u +} + +// SetNillableStatus sets the "status" field if the given value is not nil. +func (_u *DeviceTokenUpdateOne) SetNillableStatus(v *string) *DeviceTokenUpdateOne { + if v != nil { + _u.SetStatus(*v) + } + return _u } // SetToken sets the "token" field. -func (dtuo *DeviceTokenUpdateOne) SetToken(b []byte) *DeviceTokenUpdateOne { - dtuo.mutation.SetToken(b) - return dtuo +func (_u *DeviceTokenUpdateOne) SetToken(v []byte) *DeviceTokenUpdateOne { + _u.mutation.SetToken(v) + return _u } // ClearToken clears the value of the "token" field. -func (dtuo *DeviceTokenUpdateOne) ClearToken() *DeviceTokenUpdateOne { - dtuo.mutation.ClearToken() - return dtuo +func (_u *DeviceTokenUpdateOne) ClearToken() *DeviceTokenUpdateOne { + _u.mutation.ClearToken() + return _u } // SetExpiry sets the "expiry" field. -func (dtuo *DeviceTokenUpdateOne) SetExpiry(t time.Time) *DeviceTokenUpdateOne { - dtuo.mutation.SetExpiry(t) - return dtuo +func (_u *DeviceTokenUpdateOne) SetExpiry(v time.Time) *DeviceTokenUpdateOne { + _u.mutation.SetExpiry(v) + return _u +} + +// SetNillableExpiry sets the "expiry" field if the given value is not nil. +func (_u *DeviceTokenUpdateOne) SetNillableExpiry(v *time.Time) *DeviceTokenUpdateOne { + if v != nil { + _u.SetExpiry(*v) + } + return _u } // SetLastRequest sets the "last_request" field. -func (dtuo *DeviceTokenUpdateOne) SetLastRequest(t time.Time) *DeviceTokenUpdateOne { - dtuo.mutation.SetLastRequest(t) - return dtuo +func (_u *DeviceTokenUpdateOne) SetLastRequest(v time.Time) *DeviceTokenUpdateOne { + _u.mutation.SetLastRequest(v) + return _u +} + +// SetNillableLastRequest sets the "last_request" field if the given value is not nil. +func (_u *DeviceTokenUpdateOne) SetNillableLastRequest(v *time.Time) *DeviceTokenUpdateOne { + if v != nil { + _u.SetLastRequest(*v) + } + return _u } // SetPollInterval sets the "poll_interval" field. -func (dtuo *DeviceTokenUpdateOne) SetPollInterval(i int) *DeviceTokenUpdateOne { - dtuo.mutation.ResetPollInterval() - dtuo.mutation.SetPollInterval(i) - return dtuo +func (_u *DeviceTokenUpdateOne) SetPollInterval(v int) *DeviceTokenUpdateOne { + _u.mutation.ResetPollInterval() + _u.mutation.SetPollInterval(v) + return _u +} + +// SetNillablePollInterval sets the "poll_interval" field if the given value is not nil. +func (_u *DeviceTokenUpdateOne) SetNillablePollInterval(v *int) *DeviceTokenUpdateOne { + if v != nil { + _u.SetPollInterval(*v) + } + return _u } -// AddPollInterval adds i to the "poll_interval" field. -func (dtuo *DeviceTokenUpdateOne) AddPollInterval(i int) *DeviceTokenUpdateOne { - dtuo.mutation.AddPollInterval(i) - return dtuo +// AddPollInterval adds value to the "poll_interval" field. +func (_u *DeviceTokenUpdateOne) AddPollInterval(v int) *DeviceTokenUpdateOne { + _u.mutation.AddPollInterval(v) + return _u } // SetCodeChallenge sets the "code_challenge" field. -func (dtuo *DeviceTokenUpdateOne) SetCodeChallenge(s string) *DeviceTokenUpdateOne { - dtuo.mutation.SetCodeChallenge(s) - return dtuo +func (_u *DeviceTokenUpdateOne) SetCodeChallenge(v string) *DeviceTokenUpdateOne { + _u.mutation.SetCodeChallenge(v) + return _u } // SetNillableCodeChallenge sets the "code_challenge" field if the given value is not nil. -func (dtuo *DeviceTokenUpdateOne) SetNillableCodeChallenge(s *string) *DeviceTokenUpdateOne { - if s != nil { - dtuo.SetCodeChallenge(*s) +func (_u *DeviceTokenUpdateOne) SetNillableCodeChallenge(v *string) *DeviceTokenUpdateOne { + if v != nil { + _u.SetCodeChallenge(*v) } - return dtuo + return _u } // SetCodeChallengeMethod sets the "code_challenge_method" field. -func (dtuo *DeviceTokenUpdateOne) SetCodeChallengeMethod(s string) *DeviceTokenUpdateOne { - dtuo.mutation.SetCodeChallengeMethod(s) - return dtuo +func (_u *DeviceTokenUpdateOne) SetCodeChallengeMethod(v string) *DeviceTokenUpdateOne { + _u.mutation.SetCodeChallengeMethod(v) + return _u } // SetNillableCodeChallengeMethod sets the "code_challenge_method" field if the given value is not nil. -func (dtuo *DeviceTokenUpdateOne) SetNillableCodeChallengeMethod(s *string) *DeviceTokenUpdateOne { - if s != nil { - dtuo.SetCodeChallengeMethod(*s) +func (_u *DeviceTokenUpdateOne) SetNillableCodeChallengeMethod(v *string) *DeviceTokenUpdateOne { + if v != nil { + _u.SetCodeChallengeMethod(*v) } - return dtuo + return _u } // Mutation returns the DeviceTokenMutation object of the builder. -func (dtuo *DeviceTokenUpdateOne) Mutation() *DeviceTokenMutation { - return dtuo.mutation +func (_u *DeviceTokenUpdateOne) Mutation() *DeviceTokenMutation { + return _u.mutation +} + +// Where appends a list predicates to the DeviceTokenUpdate builder. +func (_u *DeviceTokenUpdateOne) Where(ps ...predicate.DeviceToken) *DeviceTokenUpdateOne { + _u.mutation.Where(ps...) + return _u } // Select allows selecting one or more fields (columns) of the returned entity. // The default is selecting all fields defined in the entity schema. -func (dtuo *DeviceTokenUpdateOne) Select(field string, fields ...string) *DeviceTokenUpdateOne { - dtuo.fields = append([]string{field}, fields...) - return dtuo +func (_u *DeviceTokenUpdateOne) Select(field string, fields ...string) *DeviceTokenUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u } // Save executes the query and returns the updated DeviceToken entity. -func (dtuo *DeviceTokenUpdateOne) Save(ctx context.Context) (*DeviceToken, error) { - var ( - err error - node *DeviceToken - ) - if len(dtuo.hooks) == 0 { - if err = dtuo.check(); err != nil { - return nil, err - } - node, err = dtuo.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*DeviceTokenMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = dtuo.check(); err != nil { - return nil, err - } - dtuo.mutation = mutation - node, err = dtuo.sqlSave(ctx) - mutation.done = true - return node, err - }) - for i := len(dtuo.hooks) - 1; i >= 0; i-- { - if dtuo.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = dtuo.hooks[i](mut) - } - v, err := mut.Mutate(ctx, dtuo.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*DeviceToken) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from DeviceTokenMutation", v) - } - node = nv - } - return node, err +func (_u *DeviceTokenUpdateOne) Save(ctx context.Context) (*DeviceToken, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (dtuo *DeviceTokenUpdateOne) SaveX(ctx context.Context) *DeviceToken { - node, err := dtuo.Save(ctx) +func (_u *DeviceTokenUpdateOne) SaveX(ctx context.Context) *DeviceToken { + node, err := _u.Save(ctx) if err != nil { panic(err) } @@ -434,26 +404,26 @@ func (dtuo *DeviceTokenUpdateOne) SaveX(ctx context.Context) *DeviceToken { } // Exec executes the query on the entity. -func (dtuo *DeviceTokenUpdateOne) Exec(ctx context.Context) error { - _, err := dtuo.Save(ctx) +func (_u *DeviceTokenUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (dtuo *DeviceTokenUpdateOne) ExecX(ctx context.Context) { - if err := dtuo.Exec(ctx); err != nil { +func (_u *DeviceTokenUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (dtuo *DeviceTokenUpdateOne) check() error { - if v, ok := dtuo.mutation.DeviceCode(); ok { +func (_u *DeviceTokenUpdateOne) check() error { + if v, ok := _u.mutation.DeviceCode(); ok { if err := devicetoken.DeviceCodeValidator(v); err != nil { return &ValidationError{Name: "device_code", err: fmt.Errorf(`db: validator failed for field "DeviceToken.device_code": %w`, err)} } } - if v, ok := dtuo.mutation.Status(); ok { + if v, ok := _u.mutation.Status(); ok { if err := devicetoken.StatusValidator(v); err != nil { return &ValidationError{Name: "status", err: fmt.Errorf(`db: validator failed for field "DeviceToken.status": %w`, err)} } @@ -461,23 +431,17 @@ func (dtuo *DeviceTokenUpdateOne) check() error { return nil } -func (dtuo *DeviceTokenUpdateOne) sqlSave(ctx context.Context) (_node *DeviceToken, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: devicetoken.Table, - Columns: devicetoken.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: devicetoken.FieldID, - }, - }, +func (_u *DeviceTokenUpdateOne) sqlSave(ctx context.Context) (_node *DeviceToken, err error) { + if err := _u.check(); err != nil { + return _node, err } - id, ok := dtuo.mutation.ID() + _spec := sqlgraph.NewUpdateSpec(devicetoken.Table, devicetoken.Columns, sqlgraph.NewFieldSpec(devicetoken.FieldID, field.TypeInt)) + id, ok := _u.mutation.ID() if !ok { return nil, &ValidationError{Name: "id", err: errors.New(`db: missing "DeviceToken.id" for update`)} } _spec.Node.ID.Value = id - if fields := dtuo.fields; len(fields) > 0 { + if fields := _u.fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, devicetoken.FieldID) for _, f := range fields { @@ -489,86 +453,47 @@ func (dtuo *DeviceTokenUpdateOne) sqlSave(ctx context.Context) (_node *DeviceTok } } } - if ps := dtuo.mutation.predicates; len(ps) > 0 { + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := dtuo.mutation.DeviceCode(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicetoken.FieldDeviceCode, - }) - } - if value, ok := dtuo.mutation.Status(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicetoken.FieldStatus, - }) - } - if value, ok := dtuo.mutation.Token(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: devicetoken.FieldToken, - }) - } - if dtuo.mutation.TokenCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Column: devicetoken.FieldToken, - }) - } - if value, ok := dtuo.mutation.Expiry(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: devicetoken.FieldExpiry, - }) - } - if value, ok := dtuo.mutation.LastRequest(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: devicetoken.FieldLastRequest, - }) - } - if value, ok := dtuo.mutation.PollInterval(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Value: value, - Column: devicetoken.FieldPollInterval, - }) - } - if value, ok := dtuo.mutation.AddedPollInterval(); ok { - _spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Value: value, - Column: devicetoken.FieldPollInterval, - }) - } - if value, ok := dtuo.mutation.CodeChallenge(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicetoken.FieldCodeChallenge, - }) - } - if value, ok := dtuo.mutation.CodeChallengeMethod(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: devicetoken.FieldCodeChallengeMethod, - }) - } - _node = &DeviceToken{config: dtuo.config} + if value, ok := _u.mutation.DeviceCode(); ok { + _spec.SetField(devicetoken.FieldDeviceCode, field.TypeString, value) + } + if value, ok := _u.mutation.Status(); ok { + _spec.SetField(devicetoken.FieldStatus, field.TypeString, value) + } + if value, ok := _u.mutation.Token(); ok { + _spec.SetField(devicetoken.FieldToken, field.TypeBytes, value) + } + if _u.mutation.TokenCleared() { + _spec.ClearField(devicetoken.FieldToken, field.TypeBytes) + } + if value, ok := _u.mutation.Expiry(); ok { + _spec.SetField(devicetoken.FieldExpiry, field.TypeTime, value) + } + if value, ok := _u.mutation.LastRequest(); ok { + _spec.SetField(devicetoken.FieldLastRequest, field.TypeTime, value) + } + if value, ok := _u.mutation.PollInterval(); ok { + _spec.SetField(devicetoken.FieldPollInterval, field.TypeInt, value) + } + if value, ok := _u.mutation.AddedPollInterval(); ok { + _spec.AddField(devicetoken.FieldPollInterval, field.TypeInt, value) + } + if value, ok := _u.mutation.CodeChallenge(); ok { + _spec.SetField(devicetoken.FieldCodeChallenge, field.TypeString, value) + } + if value, ok := _u.mutation.CodeChallengeMethod(); ok { + _spec.SetField(devicetoken.FieldCodeChallengeMethod, field.TypeString, value) + } + _node = &DeviceToken{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues - if err = sqlgraph.UpdateNode(ctx, dtuo.driver, _spec); err != nil { + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{devicetoken.Label} } else if sqlgraph.IsConstraintError(err) { @@ -576,5 +501,6 @@ func (dtuo *DeviceTokenUpdateOne) sqlSave(ctx context.Context) (_node *DeviceTok } return nil, err } + _u.mutation.done = true return _node, nil } diff --git a/storage/ent/db/ent.go b/storage/ent/db/ent.go index ed76b32b51..06bee261c8 100644 --- a/storage/ent/db/ent.go +++ b/storage/ent/db/ent.go @@ -6,6 +6,8 @@ import ( "context" "errors" "fmt" + "reflect" + "sync" "entgo.io/ent" "entgo.io/ent/dialect/sql" @@ -24,53 +26,82 @@ import ( // ent aliases to avoid import conflicts in user's code. type ( - Op = ent.Op - Hook = ent.Hook - Value = ent.Value - Query = ent.Query - Policy = ent.Policy - Mutator = ent.Mutator - Mutation = ent.Mutation - MutateFunc = ent.MutateFunc + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Query = ent.Query + QueryContext = ent.QueryContext + Querier = ent.Querier + QuerierFunc = ent.QuerierFunc + Interceptor = ent.Interceptor + InterceptFunc = ent.InterceptFunc + Traverser = ent.Traverser + TraverseFunc = ent.TraverseFunc + Policy = ent.Policy + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc ) +type clientCtxKey struct{} + +// FromContext returns a Client stored inside a context, or nil if there isn't one. +func FromContext(ctx context.Context) *Client { + c, _ := ctx.Value(clientCtxKey{}).(*Client) + return c +} + +// NewContext returns a new context with the given Client attached. +func NewContext(parent context.Context, c *Client) context.Context { + return context.WithValue(parent, clientCtxKey{}, c) +} + +type txCtxKey struct{} + +// TxFromContext returns a Tx stored inside a context, or nil if there isn't one. +func TxFromContext(ctx context.Context) *Tx { + tx, _ := ctx.Value(txCtxKey{}).(*Tx) + return tx +} + +// NewTxContext returns a new context with the given Tx attached. +func NewTxContext(parent context.Context, tx *Tx) context.Context { + return context.WithValue(parent, txCtxKey{}, tx) +} + // OrderFunc applies an ordering on the sql selector. +// Deprecated: Use Asc/Desc functions or the package builders instead. type OrderFunc func(*sql.Selector) -// columnChecker returns a function indicates if the column exists in the given column. -func columnChecker(table string) func(string) error { - checks := map[string]func(string) bool{ - authcode.Table: authcode.ValidColumn, - authrequest.Table: authrequest.ValidColumn, - connector.Table: connector.ValidColumn, - devicerequest.Table: devicerequest.ValidColumn, - devicetoken.Table: devicetoken.ValidColumn, - keys.Table: keys.ValidColumn, - oauth2client.Table: oauth2client.ValidColumn, - offlinesession.Table: offlinesession.ValidColumn, - password.Table: password.ValidColumn, - refreshtoken.Table: refreshtoken.ValidColumn, - } - check, ok := checks[table] - if !ok { - return func(string) error { - return fmt.Errorf("unknown table %q", table) - } - } - return func(column string) error { - if !check(column) { - return fmt.Errorf("unknown column %q for table %q", column, table) - } - return nil - } +var ( + initCheck sync.Once + columnCheck sql.ColumnCheck +) + +// checkColumn checks if the column exists in the given table. +func checkColumn(t, c string) error { + initCheck.Do(func() { + columnCheck = sql.NewColumnCheck(map[string]func(string) bool{ + authcode.Table: authcode.ValidColumn, + authrequest.Table: authrequest.ValidColumn, + connector.Table: connector.ValidColumn, + devicerequest.Table: devicerequest.ValidColumn, + devicetoken.Table: devicetoken.ValidColumn, + keys.Table: keys.ValidColumn, + oauth2client.Table: oauth2client.ValidColumn, + offlinesession.Table: offlinesession.ValidColumn, + password.Table: password.ValidColumn, + refreshtoken.Table: refreshtoken.ValidColumn, + }) + }) + return columnCheck(t, c) } // Asc applies the given fields in ASC order. -func Asc(fields ...string) OrderFunc { +func Asc(fields ...string) func(*sql.Selector) { return func(s *sql.Selector) { - check := columnChecker(s.TableName()) for _, f := range fields { - if err := check(f); err != nil { + if err := checkColumn(s.TableName(), f); err != nil { s.AddError(&ValidationError{Name: f, err: fmt.Errorf("db: %w", err)}) } s.OrderBy(sql.Asc(s.C(f))) @@ -79,11 +110,10 @@ func Asc(fields ...string) OrderFunc { } // Desc applies the given fields in DESC order. -func Desc(fields ...string) OrderFunc { +func Desc(fields ...string) func(*sql.Selector) { return func(s *sql.Selector) { - check := columnChecker(s.TableName()) for _, f := range fields { - if err := check(f); err != nil { + if err := checkColumn(s.TableName(), f); err != nil { s.AddError(&ValidationError{Name: f, err: fmt.Errorf("db: %w", err)}) } s.OrderBy(sql.Desc(s.C(f))) @@ -99,7 +129,6 @@ type AggregateFunc func(*sql.Selector) string // GroupBy(field1, field2). // Aggregate(db.As(db.Sum(field1), "sum_field1"), (db.As(db.Sum(field2), "sum_field2")). // Scan(ctx, &v) -// func As(fn AggregateFunc, end string) AggregateFunc { return func(s *sql.Selector) string { return sql.As(fn(s), end) @@ -116,8 +145,7 @@ func Count() AggregateFunc { // Max applies the "max" aggregation function on the given field of each group. func Max(field string) AggregateFunc { return func(s *sql.Selector) string { - check := columnChecker(s.TableName()) - if err := check(field); err != nil { + if err := checkColumn(s.TableName(), field); err != nil { s.AddError(&ValidationError{Name: field, err: fmt.Errorf("db: %w", err)}) return "" } @@ -128,8 +156,7 @@ func Max(field string) AggregateFunc { // Mean applies the "mean" aggregation function on the given field of each group. func Mean(field string) AggregateFunc { return func(s *sql.Selector) string { - check := columnChecker(s.TableName()) - if err := check(field); err != nil { + if err := checkColumn(s.TableName(), field); err != nil { s.AddError(&ValidationError{Name: field, err: fmt.Errorf("db: %w", err)}) return "" } @@ -140,8 +167,7 @@ func Mean(field string) AggregateFunc { // Min applies the "min" aggregation function on the given field of each group. func Min(field string) AggregateFunc { return func(s *sql.Selector) string { - check := columnChecker(s.TableName()) - if err := check(field); err != nil { + if err := checkColumn(s.TableName(), field); err != nil { s.AddError(&ValidationError{Name: field, err: fmt.Errorf("db: %w", err)}) return "" } @@ -152,8 +178,7 @@ func Min(field string) AggregateFunc { // Sum applies the "sum" aggregation function on the given field of each group. func Sum(field string) AggregateFunc { return func(s *sql.Selector) string { - check := columnChecker(s.TableName()) - if err := check(field); err != nil { + if err := checkColumn(s.TableName(), field); err != nil { s.AddError(&ValidationError{Name: field, err: fmt.Errorf("db: %w", err)}) return "" } @@ -282,11 +307,12 @@ func IsConstraintError(err error) bool { type selector struct { label string flds *[]string - scan func(context.Context, interface{}) error + fns []AggregateFunc + scan func(context.Context, any) error } // ScanX is like Scan, but panics if an error occurs. -func (s *selector) ScanX(ctx context.Context, v interface{}) { +func (s *selector) ScanX(ctx context.Context, v any) { if err := s.scan(ctx, v); err != nil { panic(err) } @@ -480,5 +506,121 @@ func (s *selector) BoolX(ctx context.Context) bool { return v } +// withHooks invokes the builder operation with the given hooks, if any. +func withHooks[V Value, M any, PM interface { + *M + Mutation +}](ctx context.Context, exec func(context.Context) (V, error), mutation PM, hooks []Hook) (value V, err error) { + if len(hooks) == 0 { + return exec(ctx) + } + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutationT, ok := any(m).(PM) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + // Set the mutation to the builder. + *mutation = *mutationT + return exec(ctx) + }) + for i := len(hooks) - 1; i >= 0; i-- { + if hooks[i] == nil { + return value, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)") + } + mut = hooks[i](mut) + } + v, err := mut.Mutate(ctx, mutation) + if err != nil { + return value, err + } + nv, ok := v.(V) + if !ok { + return value, fmt.Errorf("unexpected node type %T returned from %T", v, mutation) + } + return nv, nil +} + +// setContextOp returns a new context with the given QueryContext attached (including its op) in case it does not exist. +func setContextOp(ctx context.Context, qc *QueryContext, op string) context.Context { + if ent.QueryFromContext(ctx) == nil { + qc.Op = op + ctx = ent.NewQueryContext(ctx, qc) + } + return ctx +} + +func querierAll[V Value, Q interface { + sqlAll(context.Context, ...queryHook) (V, error) +}]() Querier { + return QuerierFunc(func(ctx context.Context, q Query) (Value, error) { + query, ok := q.(Q) + if !ok { + return nil, fmt.Errorf("unexpected query type %T", q) + } + return query.sqlAll(ctx) + }) +} + +func querierCount[Q interface { + sqlCount(context.Context) (int, error) +}]() Querier { + return QuerierFunc(func(ctx context.Context, q Query) (Value, error) { + query, ok := q.(Q) + if !ok { + return nil, fmt.Errorf("unexpected query type %T", q) + } + return query.sqlCount(ctx) + }) +} + +func withInterceptors[V Value](ctx context.Context, q Query, qr Querier, inters []Interceptor) (v V, err error) { + for i := len(inters) - 1; i >= 0; i-- { + qr = inters[i].Intercept(qr) + } + rv, err := qr.Query(ctx, q) + if err != nil { + return v, err + } + vt, ok := rv.(V) + if !ok { + return v, fmt.Errorf("unexpected type %T returned from %T. expected type: %T", vt, q, v) + } + return vt, nil +} + +func scanWithInterceptors[Q1 ent.Query, Q2 interface { + sqlScan(context.Context, Q1, any) error +}](ctx context.Context, rootQuery Q1, selectOrGroup Q2, inters []Interceptor, v any) error { + rv := reflect.ValueOf(v) + var qr Querier = QuerierFunc(func(ctx context.Context, q Query) (Value, error) { + query, ok := q.(Q1) + if !ok { + return nil, fmt.Errorf("unexpected query type %T", q) + } + if err := selectOrGroup.sqlScan(ctx, query, v); err != nil { + return nil, err + } + if k := rv.Kind(); k == reflect.Pointer && rv.Elem().CanInterface() { + return rv.Elem().Interface(), nil + } + return v, nil + }) + for i := len(inters) - 1; i >= 0; i-- { + qr = inters[i].Intercept(qr) + } + vv, err := qr.Query(ctx, rootQuery) + if err != nil { + return err + } + switch rv2 := reflect.ValueOf(vv); { + case rv.IsNil(), rv2.IsNil(), rv.Kind() != reflect.Pointer: + case rv.Type() == rv2.Type(): + rv.Elem().Set(rv2.Elem()) + case rv.Elem().Type() == rv2.Type(): + rv.Elem().Set(rv2) + } + return nil +} + // queryHook describes an internal hook for the different sqlAll methods. type queryHook func(context.Context, *sqlgraph.QuerySpec) diff --git a/storage/ent/db/enttest/enttest.go b/storage/ent/db/enttest/enttest.go index ecbb02d930..65702d99c9 100644 --- a/storage/ent/db/enttest/enttest.go +++ b/storage/ent/db/enttest/enttest.go @@ -18,7 +18,7 @@ type ( // testing.T and testing.B and used by enttest. TestingT interface { FailNow() - Error(...interface{}) + Error(...any) } // Option configures client creation. diff --git a/storage/ent/db/hook/hook.go b/storage/ent/db/hook/hook.go index 856e5e5949..12cb91c65e 100644 --- a/storage/ent/db/hook/hook.go +++ b/storage/ent/db/hook/hook.go @@ -15,11 +15,10 @@ type AuthCodeFunc func(context.Context, *db.AuthCodeMutation) (db.Value, error) // Mutate calls f(ctx, m). func (f AuthCodeFunc) Mutate(ctx context.Context, m db.Mutation) (db.Value, error) { - mv, ok := m.(*db.AuthCodeMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T. expect *db.AuthCodeMutation", m) + if mv, ok := m.(*db.AuthCodeMutation); ok { + return f(ctx, mv) } - return f(ctx, mv) + return nil, fmt.Errorf("unexpected mutation type %T. expect *db.AuthCodeMutation", m) } // The AuthRequestFunc type is an adapter to allow the use of ordinary @@ -28,11 +27,10 @@ type AuthRequestFunc func(context.Context, *db.AuthRequestMutation) (db.Value, e // Mutate calls f(ctx, m). func (f AuthRequestFunc) Mutate(ctx context.Context, m db.Mutation) (db.Value, error) { - mv, ok := m.(*db.AuthRequestMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T. expect *db.AuthRequestMutation", m) + if mv, ok := m.(*db.AuthRequestMutation); ok { + return f(ctx, mv) } - return f(ctx, mv) + return nil, fmt.Errorf("unexpected mutation type %T. expect *db.AuthRequestMutation", m) } // The ConnectorFunc type is an adapter to allow the use of ordinary @@ -41,11 +39,10 @@ type ConnectorFunc func(context.Context, *db.ConnectorMutation) (db.Value, error // Mutate calls f(ctx, m). func (f ConnectorFunc) Mutate(ctx context.Context, m db.Mutation) (db.Value, error) { - mv, ok := m.(*db.ConnectorMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T. expect *db.ConnectorMutation", m) + if mv, ok := m.(*db.ConnectorMutation); ok { + return f(ctx, mv) } - return f(ctx, mv) + return nil, fmt.Errorf("unexpected mutation type %T. expect *db.ConnectorMutation", m) } // The DeviceRequestFunc type is an adapter to allow the use of ordinary @@ -54,11 +51,10 @@ type DeviceRequestFunc func(context.Context, *db.DeviceRequestMutation) (db.Valu // Mutate calls f(ctx, m). func (f DeviceRequestFunc) Mutate(ctx context.Context, m db.Mutation) (db.Value, error) { - mv, ok := m.(*db.DeviceRequestMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T. expect *db.DeviceRequestMutation", m) + if mv, ok := m.(*db.DeviceRequestMutation); ok { + return f(ctx, mv) } - return f(ctx, mv) + return nil, fmt.Errorf("unexpected mutation type %T. expect *db.DeviceRequestMutation", m) } // The DeviceTokenFunc type is an adapter to allow the use of ordinary @@ -67,11 +63,10 @@ type DeviceTokenFunc func(context.Context, *db.DeviceTokenMutation) (db.Value, e // Mutate calls f(ctx, m). func (f DeviceTokenFunc) Mutate(ctx context.Context, m db.Mutation) (db.Value, error) { - mv, ok := m.(*db.DeviceTokenMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T. expect *db.DeviceTokenMutation", m) + if mv, ok := m.(*db.DeviceTokenMutation); ok { + return f(ctx, mv) } - return f(ctx, mv) + return nil, fmt.Errorf("unexpected mutation type %T. expect *db.DeviceTokenMutation", m) } // The KeysFunc type is an adapter to allow the use of ordinary @@ -80,11 +75,10 @@ type KeysFunc func(context.Context, *db.KeysMutation) (db.Value, error) // Mutate calls f(ctx, m). func (f KeysFunc) Mutate(ctx context.Context, m db.Mutation) (db.Value, error) { - mv, ok := m.(*db.KeysMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T. expect *db.KeysMutation", m) + if mv, ok := m.(*db.KeysMutation); ok { + return f(ctx, mv) } - return f(ctx, mv) + return nil, fmt.Errorf("unexpected mutation type %T. expect *db.KeysMutation", m) } // The OAuth2ClientFunc type is an adapter to allow the use of ordinary @@ -93,11 +87,10 @@ type OAuth2ClientFunc func(context.Context, *db.OAuth2ClientMutation) (db.Value, // Mutate calls f(ctx, m). func (f OAuth2ClientFunc) Mutate(ctx context.Context, m db.Mutation) (db.Value, error) { - mv, ok := m.(*db.OAuth2ClientMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T. expect *db.OAuth2ClientMutation", m) + if mv, ok := m.(*db.OAuth2ClientMutation); ok { + return f(ctx, mv) } - return f(ctx, mv) + return nil, fmt.Errorf("unexpected mutation type %T. expect *db.OAuth2ClientMutation", m) } // The OfflineSessionFunc type is an adapter to allow the use of ordinary @@ -106,11 +99,10 @@ type OfflineSessionFunc func(context.Context, *db.OfflineSessionMutation) (db.Va // Mutate calls f(ctx, m). func (f OfflineSessionFunc) Mutate(ctx context.Context, m db.Mutation) (db.Value, error) { - mv, ok := m.(*db.OfflineSessionMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T. expect *db.OfflineSessionMutation", m) + if mv, ok := m.(*db.OfflineSessionMutation); ok { + return f(ctx, mv) } - return f(ctx, mv) + return nil, fmt.Errorf("unexpected mutation type %T. expect *db.OfflineSessionMutation", m) } // The PasswordFunc type is an adapter to allow the use of ordinary @@ -119,11 +111,10 @@ type PasswordFunc func(context.Context, *db.PasswordMutation) (db.Value, error) // Mutate calls f(ctx, m). func (f PasswordFunc) Mutate(ctx context.Context, m db.Mutation) (db.Value, error) { - mv, ok := m.(*db.PasswordMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T. expect *db.PasswordMutation", m) + if mv, ok := m.(*db.PasswordMutation); ok { + return f(ctx, mv) } - return f(ctx, mv) + return nil, fmt.Errorf("unexpected mutation type %T. expect *db.PasswordMutation", m) } // The RefreshTokenFunc type is an adapter to allow the use of ordinary @@ -132,11 +123,10 @@ type RefreshTokenFunc func(context.Context, *db.RefreshTokenMutation) (db.Value, // Mutate calls f(ctx, m). func (f RefreshTokenFunc) Mutate(ctx context.Context, m db.Mutation) (db.Value, error) { - mv, ok := m.(*db.RefreshTokenMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T. expect *db.RefreshTokenMutation", m) + if mv, ok := m.(*db.RefreshTokenMutation); ok { + return f(ctx, mv) } - return f(ctx, mv) + return nil, fmt.Errorf("unexpected mutation type %T. expect *db.RefreshTokenMutation", m) } // Condition is a hook condition function. @@ -234,7 +224,6 @@ func HasFields(field string, fields ...string) Condition { // If executes the given hook under condition. // // hook.If(ComputeAverage, And(HasFields(...), HasAddedFields(...))) -// func If(hk db.Hook, cond Condition) db.Hook { return func(next db.Mutator) db.Mutator { return db.MutateFunc(func(ctx context.Context, m db.Mutation) (db.Value, error) { @@ -249,7 +238,6 @@ func If(hk db.Hook, cond Condition) db.Hook { // On executes the given hook only for the given operation. // // hook.On(Log, db.Delete|db.Create) -// func On(hk db.Hook, op db.Op) db.Hook { return If(hk, HasOp(op)) } @@ -257,7 +245,6 @@ func On(hk db.Hook, op db.Op) db.Hook { // Unless skips the given hook only for the given operation. // // hook.Unless(Log, db.Update|db.UpdateOne) -// func Unless(hk db.Hook, op db.Op) db.Hook { return If(hk, Not(HasOp(op))) } @@ -278,7 +265,6 @@ func FixedError(err error) db.Hook { // Reject(db.Delete|db.Update), // } // } -// func Reject(op db.Op) db.Hook { hk := FixedError(fmt.Errorf("%s operation is not allowed", op)) return On(hk, op) diff --git a/storage/ent/db/keys.go b/storage/ent/db/keys.go index d307ad8ed2..bd3c02bcac 100644 --- a/storage/ent/db/keys.go +++ b/storage/ent/db/keys.go @@ -8,10 +8,11 @@ import ( "strings" "time" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/dexidp/dex/storage" "github.com/dexidp/dex/storage/ent/db/keys" - jose "gopkg.in/square/go-jose.v2" + jose "github.com/go-jose/go-jose/v4" ) // Keys is the model entity for the Keys schema. @@ -27,11 +28,12 @@ type Keys struct { SigningKeyPub jose.JSONWebKey `json:"signing_key_pub,omitempty"` // NextRotation holds the value of the "next_rotation" field. NextRotation time.Time `json:"next_rotation,omitempty"` + selectValues sql.SelectValues } // scanValues returns the types for scanning values from sql.Rows. -func (*Keys) scanValues(columns []string) ([]interface{}, error) { - values := make([]interface{}, len(columns)) +func (*Keys) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) for i := range columns { switch columns[i] { case keys.FieldVerificationKeys, keys.FieldSigningKey, keys.FieldSigningKeyPub: @@ -41,7 +43,7 @@ func (*Keys) scanValues(columns []string) ([]interface{}, error) { case keys.FieldNextRotation: values[i] = new(sql.NullTime) default: - return nil, fmt.Errorf("unexpected column %q for type Keys", columns[i]) + values[i] = new(sql.UnknownType) } } return values, nil @@ -49,7 +51,7 @@ func (*Keys) scanValues(columns []string) ([]interface{}, error) { // assignValues assigns the values that were returned from sql.Rows (after scanning) // to the Keys fields. -func (k *Keys) assignValues(columns []string, values []interface{}) error { +func (_m *Keys) assignValues(columns []string, values []any) error { if m, n := len(values), len(columns); m < n { return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) } @@ -59,13 +61,13 @@ func (k *Keys) assignValues(columns []string, values []interface{}) error { if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field id", values[i]) } else if value.Valid { - k.ID = value.String + _m.ID = value.String } case keys.FieldVerificationKeys: if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field verification_keys", values[i]) } else if value != nil && len(*value) > 0 { - if err := json.Unmarshal(*value, &k.VerificationKeys); err != nil { + if err := json.Unmarshal(*value, &_m.VerificationKeys); err != nil { return fmt.Errorf("unmarshal field verification_keys: %w", err) } } @@ -73,7 +75,7 @@ func (k *Keys) assignValues(columns []string, values []interface{}) error { if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field signing_key", values[i]) } else if value != nil && len(*value) > 0 { - if err := json.Unmarshal(*value, &k.SigningKey); err != nil { + if err := json.Unmarshal(*value, &_m.SigningKey); err != nil { return fmt.Errorf("unmarshal field signing_key: %w", err) } } @@ -81,7 +83,7 @@ func (k *Keys) assignValues(columns []string, values []interface{}) error { if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field signing_key_pub", values[i]) } else if value != nil && len(*value) > 0 { - if err := json.Unmarshal(*value, &k.SigningKeyPub); err != nil { + if err := json.Unmarshal(*value, &_m.SigningKeyPub); err != nil { return fmt.Errorf("unmarshal field signing_key_pub: %w", err) } } @@ -89,56 +91,58 @@ func (k *Keys) assignValues(columns []string, values []interface{}) error { if value, ok := values[i].(*sql.NullTime); !ok { return fmt.Errorf("unexpected type %T for field next_rotation", values[i]) } else if value.Valid { - k.NextRotation = value.Time + _m.NextRotation = value.Time } + default: + _m.selectValues.Set(columns[i], values[i]) } } return nil } +// Value returns the ent.Value that was dynamically selected and assigned to the Keys. +// This includes values selected through modifiers, order, etc. +func (_m *Keys) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + // Update returns a builder for updating this Keys. // Note that you need to call Keys.Unwrap() before calling this method if this Keys // was returned from a transaction, and the transaction was committed or rolled back. -func (k *Keys) Update() *KeysUpdateOne { - return (&KeysClient{config: k.config}).UpdateOne(k) +func (_m *Keys) Update() *KeysUpdateOne { + return NewKeysClient(_m.config).UpdateOne(_m) } // Unwrap unwraps the Keys entity that was returned from a transaction after it was closed, // so that all future queries will be executed through the driver which created the transaction. -func (k *Keys) Unwrap() *Keys { - _tx, ok := k.config.driver.(*txDriver) +func (_m *Keys) Unwrap() *Keys { + _tx, ok := _m.config.driver.(*txDriver) if !ok { panic("db: Keys is not a transactional entity") } - k.config.driver = _tx.drv - return k + _m.config.driver = _tx.drv + return _m } // String implements the fmt.Stringer. -func (k *Keys) String() string { +func (_m *Keys) String() string { var builder strings.Builder builder.WriteString("Keys(") - builder.WriteString(fmt.Sprintf("id=%v, ", k.ID)) + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) builder.WriteString("verification_keys=") - builder.WriteString(fmt.Sprintf("%v", k.VerificationKeys)) + builder.WriteString(fmt.Sprintf("%v", _m.VerificationKeys)) builder.WriteString(", ") builder.WriteString("signing_key=") - builder.WriteString(fmt.Sprintf("%v", k.SigningKey)) + builder.WriteString(fmt.Sprintf("%v", _m.SigningKey)) builder.WriteString(", ") builder.WriteString("signing_key_pub=") - builder.WriteString(fmt.Sprintf("%v", k.SigningKeyPub)) + builder.WriteString(fmt.Sprintf("%v", _m.SigningKeyPub)) builder.WriteString(", ") builder.WriteString("next_rotation=") - builder.WriteString(k.NextRotation.Format(time.ANSIC)) + builder.WriteString(_m.NextRotation.Format(time.ANSIC)) builder.WriteByte(')') return builder.String() } // KeysSlice is a parsable slice of Keys. type KeysSlice []*Keys - -func (k KeysSlice) config(cfg config) { - for _i := range k { - k[_i].config = cfg - } -} diff --git a/storage/ent/db/keys/keys.go b/storage/ent/db/keys/keys.go index eb96d92a11..a00f39b1fd 100644 --- a/storage/ent/db/keys/keys.go +++ b/storage/ent/db/keys/keys.go @@ -2,6 +2,10 @@ package keys +import ( + "entgo.io/ent/dialect/sql" +) + const ( // Label holds the string label denoting the keys type in the database. Label = "keys" @@ -42,3 +46,16 @@ var ( // IDValidator is a validator for the "id" field. It is called by the builders before save. IDValidator func(string) error ) + +// OrderOption defines the ordering options for the Keys queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByNextRotation orders the results by the next_rotation field. +func ByNextRotation(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldNextRotation, opts...).ToFunc() +} diff --git a/storage/ent/db/keys/where.go b/storage/ent/db/keys/where.go index f918579da8..04bec3baec 100644 --- a/storage/ent/db/keys/where.go +++ b/storage/ent/db/keys/where.go @@ -11,174 +11,115 @@ import ( // ID filters vertices based on their ID field. func ID(id string) predicate.Keys { - return predicate.Keys(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.Keys(sql.FieldEQ(FieldID, id)) } // IDEQ applies the EQ predicate on the ID field. func IDEQ(id string) predicate.Keys { - return predicate.Keys(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.Keys(sql.FieldEQ(FieldID, id)) } // IDNEQ applies the NEQ predicate on the ID field. func IDNEQ(id string) predicate.Keys { - return predicate.Keys(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldID), id)) - }) + return predicate.Keys(sql.FieldNEQ(FieldID, id)) } // IDIn applies the In predicate on the ID field. func IDIn(ids ...string) predicate.Keys { - return predicate.Keys(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.In(s.C(FieldID), v...)) - }) + return predicate.Keys(sql.FieldIn(FieldID, ids...)) } // IDNotIn applies the NotIn predicate on the ID field. func IDNotIn(ids ...string) predicate.Keys { - return predicate.Keys(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.NotIn(s.C(FieldID), v...)) - }) + return predicate.Keys(sql.FieldNotIn(FieldID, ids...)) } // IDGT applies the GT predicate on the ID field. func IDGT(id string) predicate.Keys { - return predicate.Keys(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldID), id)) - }) + return predicate.Keys(sql.FieldGT(FieldID, id)) } // IDGTE applies the GTE predicate on the ID field. func IDGTE(id string) predicate.Keys { - return predicate.Keys(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldID), id)) - }) + return predicate.Keys(sql.FieldGTE(FieldID, id)) } // IDLT applies the LT predicate on the ID field. func IDLT(id string) predicate.Keys { - return predicate.Keys(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldID), id)) - }) + return predicate.Keys(sql.FieldLT(FieldID, id)) } // IDLTE applies the LTE predicate on the ID field. func IDLTE(id string) predicate.Keys { - return predicate.Keys(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldID), id)) - }) + return predicate.Keys(sql.FieldLTE(FieldID, id)) +} + +// IDEqualFold applies the EqualFold predicate on the ID field. +func IDEqualFold(id string) predicate.Keys { + return predicate.Keys(sql.FieldEqualFold(FieldID, id)) +} + +// IDContainsFold applies the ContainsFold predicate on the ID field. +func IDContainsFold(id string) predicate.Keys { + return predicate.Keys(sql.FieldContainsFold(FieldID, id)) } // NextRotation applies equality check predicate on the "next_rotation" field. It's identical to NextRotationEQ. func NextRotation(v time.Time) predicate.Keys { - return predicate.Keys(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldNextRotation), v)) - }) + return predicate.Keys(sql.FieldEQ(FieldNextRotation, v)) } // NextRotationEQ applies the EQ predicate on the "next_rotation" field. func NextRotationEQ(v time.Time) predicate.Keys { - return predicate.Keys(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldNextRotation), v)) - }) + return predicate.Keys(sql.FieldEQ(FieldNextRotation, v)) } // NextRotationNEQ applies the NEQ predicate on the "next_rotation" field. func NextRotationNEQ(v time.Time) predicate.Keys { - return predicate.Keys(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldNextRotation), v)) - }) + return predicate.Keys(sql.FieldNEQ(FieldNextRotation, v)) } // NextRotationIn applies the In predicate on the "next_rotation" field. func NextRotationIn(vs ...time.Time) predicate.Keys { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Keys(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldNextRotation), v...)) - }) + return predicate.Keys(sql.FieldIn(FieldNextRotation, vs...)) } // NextRotationNotIn applies the NotIn predicate on the "next_rotation" field. func NextRotationNotIn(vs ...time.Time) predicate.Keys { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Keys(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldNextRotation), v...)) - }) + return predicate.Keys(sql.FieldNotIn(FieldNextRotation, vs...)) } // NextRotationGT applies the GT predicate on the "next_rotation" field. func NextRotationGT(v time.Time) predicate.Keys { - return predicate.Keys(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldNextRotation), v)) - }) + return predicate.Keys(sql.FieldGT(FieldNextRotation, v)) } // NextRotationGTE applies the GTE predicate on the "next_rotation" field. func NextRotationGTE(v time.Time) predicate.Keys { - return predicate.Keys(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldNextRotation), v)) - }) + return predicate.Keys(sql.FieldGTE(FieldNextRotation, v)) } // NextRotationLT applies the LT predicate on the "next_rotation" field. func NextRotationLT(v time.Time) predicate.Keys { - return predicate.Keys(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldNextRotation), v)) - }) + return predicate.Keys(sql.FieldLT(FieldNextRotation, v)) } // NextRotationLTE applies the LTE predicate on the "next_rotation" field. func NextRotationLTE(v time.Time) predicate.Keys { - return predicate.Keys(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldNextRotation), v)) - }) + return predicate.Keys(sql.FieldLTE(FieldNextRotation, v)) } // And groups predicates with the AND operator between them. func And(predicates ...predicate.Keys) predicate.Keys { - return predicate.Keys(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for _, p := range predicates { - p(s1) - } - s.Where(s1.P()) - }) + return predicate.Keys(sql.AndPredicates(predicates...)) } // Or groups predicates with the OR operator between them. func Or(predicates ...predicate.Keys) predicate.Keys { - return predicate.Keys(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for i, p := range predicates { - if i > 0 { - s1.Or() - } - p(s1) - } - s.Where(s1.P()) - }) + return predicate.Keys(sql.OrPredicates(predicates...)) } // Not applies the not operator on the given predicate. func Not(p predicate.Keys) predicate.Keys { - return predicate.Keys(func(s *sql.Selector) { - p(s.Not()) - }) + return predicate.Keys(sql.NotPredicates(p)) } diff --git a/storage/ent/db/keys_create.go b/storage/ent/db/keys_create.go index 818ca27891..9cafd80a16 100644 --- a/storage/ent/db/keys_create.go +++ b/storage/ent/db/keys_create.go @@ -12,7 +12,7 @@ import ( "entgo.io/ent/schema/field" "github.com/dexidp/dex/storage" "github.com/dexidp/dex/storage/ent/db/keys" - jose "gopkg.in/square/go-jose.v2" + jose "github.com/go-jose/go-jose/v4" ) // KeysCreate is the builder for creating a Keys entity. @@ -23,90 +23,48 @@ type KeysCreate struct { } // SetVerificationKeys sets the "verification_keys" field. -func (kc *KeysCreate) SetVerificationKeys(sk []storage.VerificationKey) *KeysCreate { - kc.mutation.SetVerificationKeys(sk) - return kc +func (_c *KeysCreate) SetVerificationKeys(v []storage.VerificationKey) *KeysCreate { + _c.mutation.SetVerificationKeys(v) + return _c } // SetSigningKey sets the "signing_key" field. -func (kc *KeysCreate) SetSigningKey(jwk jose.JSONWebKey) *KeysCreate { - kc.mutation.SetSigningKey(jwk) - return kc +func (_c *KeysCreate) SetSigningKey(v jose.JSONWebKey) *KeysCreate { + _c.mutation.SetSigningKey(v) + return _c } // SetSigningKeyPub sets the "signing_key_pub" field. -func (kc *KeysCreate) SetSigningKeyPub(jwk jose.JSONWebKey) *KeysCreate { - kc.mutation.SetSigningKeyPub(jwk) - return kc +func (_c *KeysCreate) SetSigningKeyPub(v jose.JSONWebKey) *KeysCreate { + _c.mutation.SetSigningKeyPub(v) + return _c } // SetNextRotation sets the "next_rotation" field. -func (kc *KeysCreate) SetNextRotation(t time.Time) *KeysCreate { - kc.mutation.SetNextRotation(t) - return kc +func (_c *KeysCreate) SetNextRotation(v time.Time) *KeysCreate { + _c.mutation.SetNextRotation(v) + return _c } // SetID sets the "id" field. -func (kc *KeysCreate) SetID(s string) *KeysCreate { - kc.mutation.SetID(s) - return kc +func (_c *KeysCreate) SetID(v string) *KeysCreate { + _c.mutation.SetID(v) + return _c } // Mutation returns the KeysMutation object of the builder. -func (kc *KeysCreate) Mutation() *KeysMutation { - return kc.mutation +func (_c *KeysCreate) Mutation() *KeysMutation { + return _c.mutation } // Save creates the Keys in the database. -func (kc *KeysCreate) Save(ctx context.Context) (*Keys, error) { - var ( - err error - node *Keys - ) - if len(kc.hooks) == 0 { - if err = kc.check(); err != nil { - return nil, err - } - node, err = kc.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*KeysMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = kc.check(); err != nil { - return nil, err - } - kc.mutation = mutation - if node, err = kc.sqlSave(ctx); err != nil { - return nil, err - } - mutation.id = &node.ID - mutation.done = true - return node, err - }) - for i := len(kc.hooks) - 1; i >= 0; i-- { - if kc.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = kc.hooks[i](mut) - } - v, err := mut.Mutate(ctx, kc.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*Keys) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from KeysMutation", v) - } - node = nv - } - return node, err +func (_c *KeysCreate) Save(ctx context.Context) (*Keys, error) { + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) } // SaveX calls Save and panics if Save returns an error. -func (kc *KeysCreate) SaveX(ctx context.Context) *Keys { - v, err := kc.Save(ctx) +func (_c *KeysCreate) SaveX(ctx context.Context) *Keys { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -114,33 +72,33 @@ func (kc *KeysCreate) SaveX(ctx context.Context) *Keys { } // Exec executes the query. -func (kc *KeysCreate) Exec(ctx context.Context) error { - _, err := kc.Save(ctx) +func (_c *KeysCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (kc *KeysCreate) ExecX(ctx context.Context) { - if err := kc.Exec(ctx); err != nil { +func (_c *KeysCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (kc *KeysCreate) check() error { - if _, ok := kc.mutation.VerificationKeys(); !ok { +func (_c *KeysCreate) check() error { + if _, ok := _c.mutation.VerificationKeys(); !ok { return &ValidationError{Name: "verification_keys", err: errors.New(`db: missing required field "Keys.verification_keys"`)} } - if _, ok := kc.mutation.SigningKey(); !ok { + if _, ok := _c.mutation.SigningKey(); !ok { return &ValidationError{Name: "signing_key", err: errors.New(`db: missing required field "Keys.signing_key"`)} } - if _, ok := kc.mutation.SigningKeyPub(); !ok { + if _, ok := _c.mutation.SigningKeyPub(); !ok { return &ValidationError{Name: "signing_key_pub", err: errors.New(`db: missing required field "Keys.signing_key_pub"`)} } - if _, ok := kc.mutation.NextRotation(); !ok { + if _, ok := _c.mutation.NextRotation(); !ok { return &ValidationError{Name: "next_rotation", err: errors.New(`db: missing required field "Keys.next_rotation"`)} } - if v, ok := kc.mutation.ID(); ok { + if v, ok := _c.mutation.ID(); ok { if err := keys.IDValidator(v); err != nil { return &ValidationError{Name: "id", err: fmt.Errorf(`db: validator failed for field "Keys.id": %w`, err)} } @@ -148,9 +106,12 @@ func (kc *KeysCreate) check() error { return nil } -func (kc *KeysCreate) sqlSave(ctx context.Context) (*Keys, error) { - _node, _spec := kc.createSpec() - if err := sqlgraph.CreateNode(ctx, kc.driver, _spec); err != nil { +func (_c *KeysCreate) sqlSave(ctx context.Context) (*Keys, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -163,54 +124,34 @@ func (kc *KeysCreate) sqlSave(ctx context.Context) (*Keys, error) { return nil, fmt.Errorf("unexpected Keys.ID type: %T", _spec.ID.Value) } } + _c.mutation.id = &_node.ID + _c.mutation.done = true return _node, nil } -func (kc *KeysCreate) createSpec() (*Keys, *sqlgraph.CreateSpec) { +func (_c *KeysCreate) createSpec() (*Keys, *sqlgraph.CreateSpec) { var ( - _node = &Keys{config: kc.config} - _spec = &sqlgraph.CreateSpec{ - Table: keys.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: keys.FieldID, - }, - } + _node = &Keys{config: _c.config} + _spec = sqlgraph.NewCreateSpec(keys.Table, sqlgraph.NewFieldSpec(keys.FieldID, field.TypeString)) ) - if id, ok := kc.mutation.ID(); ok { + if id, ok := _c.mutation.ID(); ok { _node.ID = id _spec.ID.Value = id } - if value, ok := kc.mutation.VerificationKeys(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: keys.FieldVerificationKeys, - }) + if value, ok := _c.mutation.VerificationKeys(); ok { + _spec.SetField(keys.FieldVerificationKeys, field.TypeJSON, value) _node.VerificationKeys = value } - if value, ok := kc.mutation.SigningKey(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: keys.FieldSigningKey, - }) + if value, ok := _c.mutation.SigningKey(); ok { + _spec.SetField(keys.FieldSigningKey, field.TypeJSON, value) _node.SigningKey = value } - if value, ok := kc.mutation.SigningKeyPub(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: keys.FieldSigningKeyPub, - }) + if value, ok := _c.mutation.SigningKeyPub(); ok { + _spec.SetField(keys.FieldSigningKeyPub, field.TypeJSON, value) _node.SigningKeyPub = value } - if value, ok := kc.mutation.NextRotation(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: keys.FieldNextRotation, - }) + if value, ok := _c.mutation.NextRotation(); ok { + _spec.SetField(keys.FieldNextRotation, field.TypeTime, value) _node.NextRotation = value } return _node, _spec @@ -219,17 +160,21 @@ func (kc *KeysCreate) createSpec() (*Keys, *sqlgraph.CreateSpec) { // KeysCreateBulk is the builder for creating many Keys entities in bulk. type KeysCreateBulk struct { config + err error builders []*KeysCreate } // Save creates the Keys entities in the database. -func (kcb *KeysCreateBulk) Save(ctx context.Context) ([]*Keys, error) { - specs := make([]*sqlgraph.CreateSpec, len(kcb.builders)) - nodes := make([]*Keys, len(kcb.builders)) - mutators := make([]Mutator, len(kcb.builders)) - for i := range kcb.builders { +func (_c *KeysCreateBulk) Save(ctx context.Context) ([]*Keys, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*Keys, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { func(i int, root context.Context) { - builder := kcb.builders[i] + builder := _c.builders[i] var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { mutation, ok := m.(*KeysMutation) if !ok { @@ -239,14 +184,14 @@ func (kcb *KeysCreateBulk) Save(ctx context.Context) ([]*Keys, error) { return nil, err } builder.mutation = mutation - nodes[i], specs[i] = builder.createSpec() var err error + nodes[i], specs[i] = builder.createSpec() if i < len(mutators)-1 { - _, err = mutators[i+1].Mutate(root, kcb.builders[i+1].mutation) + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} // Invoke the actual operation on the latest mutation in the chain. - if err = sqlgraph.BatchCreate(ctx, kcb.driver, spec); err != nil { + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -266,7 +211,7 @@ func (kcb *KeysCreateBulk) Save(ctx context.Context) ([]*Keys, error) { }(i, ctx) } if len(mutators) > 0 { - if _, err := mutators[0].Mutate(ctx, kcb.builders[0].mutation); err != nil { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { return nil, err } } @@ -274,8 +219,8 @@ func (kcb *KeysCreateBulk) Save(ctx context.Context) ([]*Keys, error) { } // SaveX is like Save, but panics if an error occurs. -func (kcb *KeysCreateBulk) SaveX(ctx context.Context) []*Keys { - v, err := kcb.Save(ctx) +func (_c *KeysCreateBulk) SaveX(ctx context.Context) []*Keys { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -283,14 +228,14 @@ func (kcb *KeysCreateBulk) SaveX(ctx context.Context) []*Keys { } // Exec executes the query. -func (kcb *KeysCreateBulk) Exec(ctx context.Context) error { - _, err := kcb.Save(ctx) +func (_c *KeysCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (kcb *KeysCreateBulk) ExecX(ctx context.Context) { - if err := kcb.Exec(ctx); err != nil { +func (_c *KeysCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } diff --git a/storage/ent/db/keys_delete.go b/storage/ent/db/keys_delete.go index 5bcf970f58..b4e838eb62 100644 --- a/storage/ent/db/keys_delete.go +++ b/storage/ent/db/keys_delete.go @@ -4,7 +4,6 @@ package db import ( "context" - "fmt" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" @@ -21,84 +20,56 @@ type KeysDelete struct { } // Where appends a list predicates to the KeysDelete builder. -func (kd *KeysDelete) Where(ps ...predicate.Keys) *KeysDelete { - kd.mutation.Where(ps...) - return kd +func (_d *KeysDelete) Where(ps ...predicate.Keys) *KeysDelete { + _d.mutation.Where(ps...) + return _d } // Exec executes the deletion query and returns how many vertices were deleted. -func (kd *KeysDelete) Exec(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(kd.hooks) == 0 { - affected, err = kd.sqlExec(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*KeysMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - kd.mutation = mutation - affected, err = kd.sqlExec(ctx) - mutation.done = true - return affected, err - }) - for i := len(kd.hooks) - 1; i >= 0; i-- { - if kd.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = kd.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, kd.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_d *KeysDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) } // ExecX is like Exec, but panics if an error occurs. -func (kd *KeysDelete) ExecX(ctx context.Context) int { - n, err := kd.Exec(ctx) +func (_d *KeysDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) if err != nil { panic(err) } return n } -func (kd *KeysDelete) sqlExec(ctx context.Context) (int, error) { - _spec := &sqlgraph.DeleteSpec{ - Node: &sqlgraph.NodeSpec{ - Table: keys.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: keys.FieldID, - }, - }, - } - if ps := kd.mutation.predicates; len(ps) > 0 { +func (_d *KeysDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(keys.Table, sqlgraph.NewFieldSpec(keys.FieldID, field.TypeString)) + if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - affected, err := sqlgraph.DeleteNodes(ctx, kd.driver, _spec) + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) if err != nil && sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } + _d.mutation.done = true return affected, err } // KeysDeleteOne is the builder for deleting a single Keys entity. type KeysDeleteOne struct { - kd *KeysDelete + _d *KeysDelete +} + +// Where appends a list predicates to the KeysDelete builder. +func (_d *KeysDeleteOne) Where(ps ...predicate.Keys) *KeysDeleteOne { + _d._d.mutation.Where(ps...) + return _d } // Exec executes the deletion query. -func (kdo *KeysDeleteOne) Exec(ctx context.Context) error { - n, err := kdo.kd.Exec(ctx) +func (_d *KeysDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) switch { case err != nil: return err @@ -110,6 +81,8 @@ func (kdo *KeysDeleteOne) Exec(ctx context.Context) error { } // ExecX is like Exec, but panics if an error occurs. -func (kdo *KeysDeleteOne) ExecX(ctx context.Context) { - kdo.kd.ExecX(ctx) +func (_d *KeysDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } } diff --git a/storage/ent/db/keys_query.go b/storage/ent/db/keys_query.go index 7d9ea9082d..1c86b797a4 100644 --- a/storage/ent/db/keys_query.go +++ b/storage/ent/db/keys_query.go @@ -7,6 +7,7 @@ import ( "fmt" "math" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" @@ -17,11 +18,9 @@ import ( // KeysQuery is the builder for querying Keys entities. type KeysQuery struct { config - limit *int - offset *int - unique *bool - order []OrderFunc - fields []string + ctx *QueryContext + order []keys.OrderOption + inters []Interceptor predicates []predicate.Keys // intermediate query (i.e. traversal path). sql *sql.Selector @@ -29,40 +28,40 @@ type KeysQuery struct { } // Where adds a new predicate for the KeysQuery builder. -func (kq *KeysQuery) Where(ps ...predicate.Keys) *KeysQuery { - kq.predicates = append(kq.predicates, ps...) - return kq +func (_q *KeysQuery) Where(ps ...predicate.Keys) *KeysQuery { + _q.predicates = append(_q.predicates, ps...) + return _q } -// Limit adds a limit step to the query. -func (kq *KeysQuery) Limit(limit int) *KeysQuery { - kq.limit = &limit - return kq +// Limit the number of records to be returned by this query. +func (_q *KeysQuery) Limit(limit int) *KeysQuery { + _q.ctx.Limit = &limit + return _q } -// Offset adds an offset step to the query. -func (kq *KeysQuery) Offset(offset int) *KeysQuery { - kq.offset = &offset - return kq +// Offset to start from. +func (_q *KeysQuery) Offset(offset int) *KeysQuery { + _q.ctx.Offset = &offset + return _q } // Unique configures the query builder to filter duplicate records on query. // By default, unique is set to true, and can be disabled using this method. -func (kq *KeysQuery) Unique(unique bool) *KeysQuery { - kq.unique = &unique - return kq +func (_q *KeysQuery) Unique(unique bool) *KeysQuery { + _q.ctx.Unique = &unique + return _q } -// Order adds an order step to the query. -func (kq *KeysQuery) Order(o ...OrderFunc) *KeysQuery { - kq.order = append(kq.order, o...) - return kq +// Order specifies how the records should be ordered. +func (_q *KeysQuery) Order(o ...keys.OrderOption) *KeysQuery { + _q.order = append(_q.order, o...) + return _q } // First returns the first Keys entity from the query. // Returns a *NotFoundError when no Keys was found. -func (kq *KeysQuery) First(ctx context.Context) (*Keys, error) { - nodes, err := kq.Limit(1).All(ctx) +func (_q *KeysQuery) First(ctx context.Context) (*Keys, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) if err != nil { return nil, err } @@ -73,8 +72,8 @@ func (kq *KeysQuery) First(ctx context.Context) (*Keys, error) { } // FirstX is like First, but panics if an error occurs. -func (kq *KeysQuery) FirstX(ctx context.Context) *Keys { - node, err := kq.First(ctx) +func (_q *KeysQuery) FirstX(ctx context.Context) *Keys { + node, err := _q.First(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -83,9 +82,9 @@ func (kq *KeysQuery) FirstX(ctx context.Context) *Keys { // FirstID returns the first Keys ID from the query. // Returns a *NotFoundError when no Keys ID was found. -func (kq *KeysQuery) FirstID(ctx context.Context) (id string, err error) { +func (_q *KeysQuery) FirstID(ctx context.Context) (id string, err error) { var ids []string - if ids, err = kq.Limit(1).IDs(ctx); err != nil { + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { return } if len(ids) == 0 { @@ -96,8 +95,8 @@ func (kq *KeysQuery) FirstID(ctx context.Context) (id string, err error) { } // FirstIDX is like FirstID, but panics if an error occurs. -func (kq *KeysQuery) FirstIDX(ctx context.Context) string { - id, err := kq.FirstID(ctx) +func (_q *KeysQuery) FirstIDX(ctx context.Context) string { + id, err := _q.FirstID(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -107,8 +106,8 @@ func (kq *KeysQuery) FirstIDX(ctx context.Context) string { // Only returns a single Keys entity found by the query, ensuring it only returns one. // Returns a *NotSingularError when more than one Keys entity is found. // Returns a *NotFoundError when no Keys entities are found. -func (kq *KeysQuery) Only(ctx context.Context) (*Keys, error) { - nodes, err := kq.Limit(2).All(ctx) +func (_q *KeysQuery) Only(ctx context.Context) (*Keys, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) if err != nil { return nil, err } @@ -123,8 +122,8 @@ func (kq *KeysQuery) Only(ctx context.Context) (*Keys, error) { } // OnlyX is like Only, but panics if an error occurs. -func (kq *KeysQuery) OnlyX(ctx context.Context) *Keys { - node, err := kq.Only(ctx) +func (_q *KeysQuery) OnlyX(ctx context.Context) *Keys { + node, err := _q.Only(ctx) if err != nil { panic(err) } @@ -134,9 +133,9 @@ func (kq *KeysQuery) OnlyX(ctx context.Context) *Keys { // OnlyID is like Only, but returns the only Keys ID in the query. // Returns a *NotSingularError when more than one Keys ID is found. // Returns a *NotFoundError when no entities are found. -func (kq *KeysQuery) OnlyID(ctx context.Context) (id string, err error) { +func (_q *KeysQuery) OnlyID(ctx context.Context) (id string, err error) { var ids []string - if ids, err = kq.Limit(2).IDs(ctx); err != nil { + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { return } switch len(ids) { @@ -151,8 +150,8 @@ func (kq *KeysQuery) OnlyID(ctx context.Context) (id string, err error) { } // OnlyIDX is like OnlyID, but panics if an error occurs. -func (kq *KeysQuery) OnlyIDX(ctx context.Context) string { - id, err := kq.OnlyID(ctx) +func (_q *KeysQuery) OnlyIDX(ctx context.Context) string { + id, err := _q.OnlyID(ctx) if err != nil { panic(err) } @@ -160,16 +159,18 @@ func (kq *KeysQuery) OnlyIDX(ctx context.Context) string { } // All executes the query and returns a list of KeysSlice. -func (kq *KeysQuery) All(ctx context.Context) ([]*Keys, error) { - if err := kq.prepareQuery(ctx); err != nil { +func (_q *KeysQuery) All(ctx context.Context) ([]*Keys, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { return nil, err } - return kq.sqlAll(ctx) + qr := querierAll[[]*Keys, *KeysQuery]() + return withInterceptors[[]*Keys](ctx, _q, qr, _q.inters) } // AllX is like All, but panics if an error occurs. -func (kq *KeysQuery) AllX(ctx context.Context) []*Keys { - nodes, err := kq.All(ctx) +func (_q *KeysQuery) AllX(ctx context.Context) []*Keys { + nodes, err := _q.All(ctx) if err != nil { panic(err) } @@ -177,17 +178,20 @@ func (kq *KeysQuery) AllX(ctx context.Context) []*Keys { } // IDs executes the query and returns a list of Keys IDs. -func (kq *KeysQuery) IDs(ctx context.Context) ([]string, error) { - var ids []string - if err := kq.Select(keys.FieldID).Scan(ctx, &ids); err != nil { +func (_q *KeysQuery) IDs(ctx context.Context) (ids []string, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(keys.FieldID).Scan(ctx, &ids); err != nil { return nil, err } return ids, nil } // IDsX is like IDs, but panics if an error occurs. -func (kq *KeysQuery) IDsX(ctx context.Context) []string { - ids, err := kq.IDs(ctx) +func (_q *KeysQuery) IDsX(ctx context.Context) []string { + ids, err := _q.IDs(ctx) if err != nil { panic(err) } @@ -195,16 +199,17 @@ func (kq *KeysQuery) IDsX(ctx context.Context) []string { } // Count returns the count of the given query. -func (kq *KeysQuery) Count(ctx context.Context) (int, error) { - if err := kq.prepareQuery(ctx); err != nil { +func (_q *KeysQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { return 0, err } - return kq.sqlCount(ctx) + return withInterceptors[int](ctx, _q, querierCount[*KeysQuery](), _q.inters) } // CountX is like Count, but panics if an error occurs. -func (kq *KeysQuery) CountX(ctx context.Context) int { - count, err := kq.Count(ctx) +func (_q *KeysQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) if err != nil { panic(err) } @@ -212,16 +217,21 @@ func (kq *KeysQuery) CountX(ctx context.Context) int { } // Exist returns true if the query has elements in the graph. -func (kq *KeysQuery) Exist(ctx context.Context) (bool, error) { - if err := kq.prepareQuery(ctx); err != nil { - return false, err +func (_q *KeysQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("db: check existence: %w", err) + default: + return true, nil } - return kq.sqlExist(ctx) } // ExistX is like Exist, but panics if an error occurs. -func (kq *KeysQuery) ExistX(ctx context.Context) bool { - exist, err := kq.Exist(ctx) +func (_q *KeysQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) if err != nil { panic(err) } @@ -230,20 +240,19 @@ func (kq *KeysQuery) ExistX(ctx context.Context) bool { // Clone returns a duplicate of the KeysQuery builder, including all associated steps. It can be // used to prepare common query builders and use them differently after the clone is made. -func (kq *KeysQuery) Clone() *KeysQuery { - if kq == nil { +func (_q *KeysQuery) Clone() *KeysQuery { + if _q == nil { return nil } return &KeysQuery{ - config: kq.config, - limit: kq.limit, - offset: kq.offset, - order: append([]OrderFunc{}, kq.order...), - predicates: append([]predicate.Keys{}, kq.predicates...), + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]keys.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.Keys{}, _q.predicates...), // clone intermediate query. - sql: kq.sql.Clone(), - path: kq.path, - unique: kq.unique, + sql: _q.sql.Clone(), + path: _q.path, } } @@ -261,18 +270,12 @@ func (kq *KeysQuery) Clone() *KeysQuery { // GroupBy(keys.FieldVerificationKeys). // Aggregate(db.Count()). // Scan(ctx, &v) -// -func (kq *KeysQuery) GroupBy(field string, fields ...string) *KeysGroupBy { - grbuild := &KeysGroupBy{config: kq.config} - grbuild.fields = append([]string{field}, fields...) - grbuild.path = func(ctx context.Context) (prev *sql.Selector, err error) { - if err := kq.prepareQuery(ctx); err != nil { - return nil, err - } - return kq.sqlQuery(ctx), nil - } +func (_q *KeysQuery) GroupBy(field string, fields ...string) *KeysGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &KeysGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields grbuild.label = keys.Label - grbuild.flds, grbuild.scan = &grbuild.fields, grbuild.Scan + grbuild.scan = grbuild.Scan return grbuild } @@ -288,48 +291,62 @@ func (kq *KeysQuery) GroupBy(field string, fields ...string) *KeysGroupBy { // client.Keys.Query(). // Select(keys.FieldVerificationKeys). // Scan(ctx, &v) -// -func (kq *KeysQuery) Select(fields ...string) *KeysSelect { - kq.fields = append(kq.fields, fields...) - selbuild := &KeysSelect{KeysQuery: kq} - selbuild.label = keys.Label - selbuild.flds, selbuild.scan = &kq.fields, selbuild.Scan - return selbuild +func (_q *KeysQuery) Select(fields ...string) *KeysSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &KeysSelect{KeysQuery: _q} + sbuild.label = keys.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a KeysSelect configured with the given aggregations. +func (_q *KeysQuery) Aggregate(fns ...AggregateFunc) *KeysSelect { + return _q.Select().Aggregate(fns...) } -func (kq *KeysQuery) prepareQuery(ctx context.Context) error { - for _, f := range kq.fields { +func (_q *KeysQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("db: uninitialized interceptor (forgotten import db/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { if !keys.ValidColumn(f) { return &ValidationError{Name: f, err: fmt.Errorf("db: invalid field %q for query", f)} } } - if kq.path != nil { - prev, err := kq.path(ctx) + if _q.path != nil { + prev, err := _q.path(ctx) if err != nil { return err } - kq.sql = prev + _q.sql = prev } return nil } -func (kq *KeysQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Keys, error) { +func (_q *KeysQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Keys, error) { var ( nodes = []*Keys{} - _spec = kq.querySpec() + _spec = _q.querySpec() ) - _spec.ScanValues = func(columns []string) ([]interface{}, error) { + _spec.ScanValues = func(columns []string) ([]any, error) { return (*Keys).scanValues(nil, columns) } - _spec.Assign = func(columns []string, values []interface{}) error { - node := &Keys{config: kq.config} + _spec.Assign = func(columns []string, values []any) error { + node := &Keys{config: _q.config} nodes = append(nodes, node) return node.assignValues(columns, values) } for i := range hooks { hooks[i](ctx, _spec) } - if err := sqlgraph.QueryNodes(ctx, kq.driver, _spec); err != nil { + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { return nil, err } if len(nodes) == 0 { @@ -338,40 +355,24 @@ func (kq *KeysQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Keys, e return nodes, nil } -func (kq *KeysQuery) sqlCount(ctx context.Context) (int, error) { - _spec := kq.querySpec() - _spec.Node.Columns = kq.fields - if len(kq.fields) > 0 { - _spec.Unique = kq.unique != nil && *kq.unique - } - return sqlgraph.CountNodes(ctx, kq.driver, _spec) -} - -func (kq *KeysQuery) sqlExist(ctx context.Context) (bool, error) { - n, err := kq.sqlCount(ctx) - if err != nil { - return false, fmt.Errorf("db: check existence: %w", err) +func (_q *KeysQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique } - return n > 0, nil + return sqlgraph.CountNodes(ctx, _q.driver, _spec) } -func (kq *KeysQuery) querySpec() *sqlgraph.QuerySpec { - _spec := &sqlgraph.QuerySpec{ - Node: &sqlgraph.NodeSpec{ - Table: keys.Table, - Columns: keys.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: keys.FieldID, - }, - }, - From: kq.sql, - Unique: true, - } - if unique := kq.unique; unique != nil { +func (_q *KeysQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(keys.Table, keys.Columns, sqlgraph.NewFieldSpec(keys.FieldID, field.TypeString)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true } - if fields := kq.fields; len(fields) > 0 { + if fields := _q.ctx.Fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, keys.FieldID) for i := range fields { @@ -380,20 +381,20 @@ func (kq *KeysQuery) querySpec() *sqlgraph.QuerySpec { } } } - if ps := kq.predicates; len(ps) > 0 { + if ps := _q.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if limit := kq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { _spec.Limit = *limit } - if offset := kq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { _spec.Offset = *offset } - if ps := kq.order; len(ps) > 0 { + if ps := _q.order; len(ps) > 0 { _spec.Order = func(selector *sql.Selector) { for i := range ps { ps[i](selector) @@ -403,33 +404,33 @@ func (kq *KeysQuery) querySpec() *sqlgraph.QuerySpec { return _spec } -func (kq *KeysQuery) sqlQuery(ctx context.Context) *sql.Selector { - builder := sql.Dialect(kq.driver.Dialect()) +func (_q *KeysQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) t1 := builder.Table(keys.Table) - columns := kq.fields + columns := _q.ctx.Fields if len(columns) == 0 { columns = keys.Columns } selector := builder.Select(t1.Columns(columns...)...).From(t1) - if kq.sql != nil { - selector = kq.sql + if _q.sql != nil { + selector = _q.sql selector.Select(selector.Columns(columns...)...) } - if kq.unique != nil && *kq.unique { + if _q.ctx.Unique != nil && *_q.ctx.Unique { selector.Distinct() } - for _, p := range kq.predicates { + for _, p := range _q.predicates { p(selector) } - for _, p := range kq.order { + for _, p := range _q.order { p(selector) } - if offset := kq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { // limit is mandatory for offset clause. We start // with default value, and override it below if needed. selector.Offset(*offset).Limit(math.MaxInt32) } - if limit := kq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { selector.Limit(*limit) } return selector @@ -437,90 +438,88 @@ func (kq *KeysQuery) sqlQuery(ctx context.Context) *sql.Selector { // KeysGroupBy is the group-by builder for Keys entities. type KeysGroupBy struct { - config selector - fields []string - fns []AggregateFunc - // intermediate query (i.e. traversal path). - sql *sql.Selector - path func(context.Context) (*sql.Selector, error) + build *KeysQuery } // Aggregate adds the given aggregation functions to the group-by query. -func (kgb *KeysGroupBy) Aggregate(fns ...AggregateFunc) *KeysGroupBy { - kgb.fns = append(kgb.fns, fns...) - return kgb +func (_g *KeysGroupBy) Aggregate(fns ...AggregateFunc) *KeysGroupBy { + _g.fns = append(_g.fns, fns...) + return _g } -// Scan applies the group-by query and scans the result into the given value. -func (kgb *KeysGroupBy) Scan(ctx context.Context, v interface{}) error { - query, err := kgb.path(ctx) - if err != nil { +// Scan applies the selector query and scans the result into the given value. +func (_g *KeysGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { return err } - kgb.sql = query - return kgb.sqlScan(ctx, v) + return scanWithInterceptors[*KeysQuery, *KeysGroupBy](ctx, _g.build, _g, _g.build.inters, v) } -func (kgb *KeysGroupBy) sqlScan(ctx context.Context, v interface{}) error { - for _, f := range kgb.fields { - if !keys.ValidColumn(f) { - return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)} +func (_g *KeysGroupBy) sqlScan(ctx context.Context, root *KeysQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) } + columns = append(columns, aggregation...) + selector.Select(columns...) } - selector := kgb.sqlQuery() + selector.GroupBy(selector.Columns(*_g.flds...)...) if err := selector.Err(); err != nil { return err } rows := &sql.Rows{} query, args := selector.Query() - if err := kgb.driver.Query(ctx, query, args, rows); err != nil { + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() return sql.ScanSlice(rows, v) } -func (kgb *KeysGroupBy) sqlQuery() *sql.Selector { - selector := kgb.sql.Select() - aggregation := make([]string, 0, len(kgb.fns)) - for _, fn := range kgb.fns { - aggregation = append(aggregation, fn(selector)) - } - // If no columns were selected in a custom aggregation function, the default - // selection is the fields used for "group-by", and the aggregation functions. - if len(selector.SelectedColumns()) == 0 { - columns := make([]string, 0, len(kgb.fields)+len(kgb.fns)) - for _, f := range kgb.fields { - columns = append(columns, selector.C(f)) - } - columns = append(columns, aggregation...) - selector.Select(columns...) - } - return selector.GroupBy(selector.Columns(kgb.fields...)...) -} - // KeysSelect is the builder for selecting fields of Keys entities. type KeysSelect struct { *KeysQuery selector - // intermediate query (i.e. traversal path). - sql *sql.Selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *KeysSelect) Aggregate(fns ...AggregateFunc) *KeysSelect { + _s.fns = append(_s.fns, fns...) + return _s } // Scan applies the selector query and scans the result into the given value. -func (ks *KeysSelect) Scan(ctx context.Context, v interface{}) error { - if err := ks.prepareQuery(ctx); err != nil { +func (_s *KeysSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { return err } - ks.sql = ks.KeysQuery.sqlQuery(ctx) - return ks.sqlScan(ctx, v) + return scanWithInterceptors[*KeysQuery, *KeysSelect](ctx, _s.KeysQuery, _s, _s.inters, v) } -func (ks *KeysSelect) sqlScan(ctx context.Context, v interface{}) error { +func (_s *KeysSelect) sqlScan(ctx context.Context, root *KeysQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } rows := &sql.Rows{} - query, args := ks.sql.Query() - if err := ks.driver.Query(ctx, query, args, rows); err != nil { + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() diff --git a/storage/ent/db/keys_update.go b/storage/ent/db/keys_update.go index b5fbefff67..f45446f079 100644 --- a/storage/ent/db/keys_update.go +++ b/storage/ent/db/keys_update.go @@ -10,11 +10,12 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/dialect/sql/sqljson" "entgo.io/ent/schema/field" "github.com/dexidp/dex/storage" "github.com/dexidp/dex/storage/ent/db/keys" "github.com/dexidp/dex/storage/ent/db/predicate" - jose "gopkg.in/square/go-jose.v2" + jose "github.com/go-jose/go-jose/v4" ) // KeysUpdate is the builder for updating Keys entities. @@ -25,75 +26,78 @@ type KeysUpdate struct { } // Where appends a list predicates to the KeysUpdate builder. -func (ku *KeysUpdate) Where(ps ...predicate.Keys) *KeysUpdate { - ku.mutation.Where(ps...) - return ku +func (_u *KeysUpdate) Where(ps ...predicate.Keys) *KeysUpdate { + _u.mutation.Where(ps...) + return _u } // SetVerificationKeys sets the "verification_keys" field. -func (ku *KeysUpdate) SetVerificationKeys(sk []storage.VerificationKey) *KeysUpdate { - ku.mutation.SetVerificationKeys(sk) - return ku +func (_u *KeysUpdate) SetVerificationKeys(v []storage.VerificationKey) *KeysUpdate { + _u.mutation.SetVerificationKeys(v) + return _u +} + +// AppendVerificationKeys appends value to the "verification_keys" field. +func (_u *KeysUpdate) AppendVerificationKeys(v []storage.VerificationKey) *KeysUpdate { + _u.mutation.AppendVerificationKeys(v) + return _u } // SetSigningKey sets the "signing_key" field. -func (ku *KeysUpdate) SetSigningKey(jwk jose.JSONWebKey) *KeysUpdate { - ku.mutation.SetSigningKey(jwk) - return ku +func (_u *KeysUpdate) SetSigningKey(v jose.JSONWebKey) *KeysUpdate { + _u.mutation.SetSigningKey(v) + return _u +} + +// SetNillableSigningKey sets the "signing_key" field if the given value is not nil. +func (_u *KeysUpdate) SetNillableSigningKey(v *jose.JSONWebKey) *KeysUpdate { + if v != nil { + _u.SetSigningKey(*v) + } + return _u } // SetSigningKeyPub sets the "signing_key_pub" field. -func (ku *KeysUpdate) SetSigningKeyPub(jwk jose.JSONWebKey) *KeysUpdate { - ku.mutation.SetSigningKeyPub(jwk) - return ku +func (_u *KeysUpdate) SetSigningKeyPub(v jose.JSONWebKey) *KeysUpdate { + _u.mutation.SetSigningKeyPub(v) + return _u +} + +// SetNillableSigningKeyPub sets the "signing_key_pub" field if the given value is not nil. +func (_u *KeysUpdate) SetNillableSigningKeyPub(v *jose.JSONWebKey) *KeysUpdate { + if v != nil { + _u.SetSigningKeyPub(*v) + } + return _u } // SetNextRotation sets the "next_rotation" field. -func (ku *KeysUpdate) SetNextRotation(t time.Time) *KeysUpdate { - ku.mutation.SetNextRotation(t) - return ku +func (_u *KeysUpdate) SetNextRotation(v time.Time) *KeysUpdate { + _u.mutation.SetNextRotation(v) + return _u +} + +// SetNillableNextRotation sets the "next_rotation" field if the given value is not nil. +func (_u *KeysUpdate) SetNillableNextRotation(v *time.Time) *KeysUpdate { + if v != nil { + _u.SetNextRotation(*v) + } + return _u } // Mutation returns the KeysMutation object of the builder. -func (ku *KeysUpdate) Mutation() *KeysMutation { - return ku.mutation +func (_u *KeysUpdate) Mutation() *KeysMutation { + return _u.mutation } // Save executes the query and returns the number of nodes affected by the update operation. -func (ku *KeysUpdate) Save(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(ku.hooks) == 0 { - affected, err = ku.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*KeysMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - ku.mutation = mutation - affected, err = ku.sqlSave(ctx) - mutation.done = true - return affected, err - }) - for i := len(ku.hooks) - 1; i >= 0; i-- { - if ku.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = ku.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, ku.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_u *KeysUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (ku *KeysUpdate) SaveX(ctx context.Context) int { - affected, err := ku.Save(ctx) +func (_u *KeysUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) if err != nil { panic(err) } @@ -101,65 +105,45 @@ func (ku *KeysUpdate) SaveX(ctx context.Context) int { } // Exec executes the query. -func (ku *KeysUpdate) Exec(ctx context.Context) error { - _, err := ku.Save(ctx) +func (_u *KeysUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (ku *KeysUpdate) ExecX(ctx context.Context) { - if err := ku.Exec(ctx); err != nil { +func (_u *KeysUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } -func (ku *KeysUpdate) sqlSave(ctx context.Context) (n int, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: keys.Table, - Columns: keys.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: keys.FieldID, - }, - }, - } - if ps := ku.mutation.predicates; len(ps) > 0 { +func (_u *KeysUpdate) sqlSave(ctx context.Context) (_node int, err error) { + _spec := sqlgraph.NewUpdateSpec(keys.Table, keys.Columns, sqlgraph.NewFieldSpec(keys.FieldID, field.TypeString)) + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := ku.mutation.VerificationKeys(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: keys.FieldVerificationKeys, - }) + if value, ok := _u.mutation.VerificationKeys(); ok { + _spec.SetField(keys.FieldVerificationKeys, field.TypeJSON, value) } - if value, ok := ku.mutation.SigningKey(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: keys.FieldSigningKey, + if value, ok := _u.mutation.AppendedVerificationKeys(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, keys.FieldVerificationKeys, value) }) } - if value, ok := ku.mutation.SigningKeyPub(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: keys.FieldSigningKeyPub, - }) + if value, ok := _u.mutation.SigningKey(); ok { + _spec.SetField(keys.FieldSigningKey, field.TypeJSON, value) } - if value, ok := ku.mutation.NextRotation(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: keys.FieldNextRotation, - }) + if value, ok := _u.mutation.SigningKeyPub(); ok { + _spec.SetField(keys.FieldSigningKeyPub, field.TypeJSON, value) + } + if value, ok := _u.mutation.NextRotation(); ok { + _spec.SetField(keys.FieldNextRotation, field.TypeTime, value) } - if n, err = sqlgraph.UpdateNodes(ctx, ku.driver, _spec); err != nil { + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{keys.Label} } else if sqlgraph.IsConstraintError(err) { @@ -167,7 +151,8 @@ func (ku *KeysUpdate) sqlSave(ctx context.Context) (n int, err error) { } return 0, err } - return n, nil + _u.mutation.done = true + return _node, nil } // KeysUpdateOne is the builder for updating a single Keys entity. @@ -179,82 +164,85 @@ type KeysUpdateOne struct { } // SetVerificationKeys sets the "verification_keys" field. -func (kuo *KeysUpdateOne) SetVerificationKeys(sk []storage.VerificationKey) *KeysUpdateOne { - kuo.mutation.SetVerificationKeys(sk) - return kuo +func (_u *KeysUpdateOne) SetVerificationKeys(v []storage.VerificationKey) *KeysUpdateOne { + _u.mutation.SetVerificationKeys(v) + return _u +} + +// AppendVerificationKeys appends value to the "verification_keys" field. +func (_u *KeysUpdateOne) AppendVerificationKeys(v []storage.VerificationKey) *KeysUpdateOne { + _u.mutation.AppendVerificationKeys(v) + return _u } // SetSigningKey sets the "signing_key" field. -func (kuo *KeysUpdateOne) SetSigningKey(jwk jose.JSONWebKey) *KeysUpdateOne { - kuo.mutation.SetSigningKey(jwk) - return kuo +func (_u *KeysUpdateOne) SetSigningKey(v jose.JSONWebKey) *KeysUpdateOne { + _u.mutation.SetSigningKey(v) + return _u +} + +// SetNillableSigningKey sets the "signing_key" field if the given value is not nil. +func (_u *KeysUpdateOne) SetNillableSigningKey(v *jose.JSONWebKey) *KeysUpdateOne { + if v != nil { + _u.SetSigningKey(*v) + } + return _u } // SetSigningKeyPub sets the "signing_key_pub" field. -func (kuo *KeysUpdateOne) SetSigningKeyPub(jwk jose.JSONWebKey) *KeysUpdateOne { - kuo.mutation.SetSigningKeyPub(jwk) - return kuo +func (_u *KeysUpdateOne) SetSigningKeyPub(v jose.JSONWebKey) *KeysUpdateOne { + _u.mutation.SetSigningKeyPub(v) + return _u +} + +// SetNillableSigningKeyPub sets the "signing_key_pub" field if the given value is not nil. +func (_u *KeysUpdateOne) SetNillableSigningKeyPub(v *jose.JSONWebKey) *KeysUpdateOne { + if v != nil { + _u.SetSigningKeyPub(*v) + } + return _u } // SetNextRotation sets the "next_rotation" field. -func (kuo *KeysUpdateOne) SetNextRotation(t time.Time) *KeysUpdateOne { - kuo.mutation.SetNextRotation(t) - return kuo +func (_u *KeysUpdateOne) SetNextRotation(v time.Time) *KeysUpdateOne { + _u.mutation.SetNextRotation(v) + return _u +} + +// SetNillableNextRotation sets the "next_rotation" field if the given value is not nil. +func (_u *KeysUpdateOne) SetNillableNextRotation(v *time.Time) *KeysUpdateOne { + if v != nil { + _u.SetNextRotation(*v) + } + return _u } // Mutation returns the KeysMutation object of the builder. -func (kuo *KeysUpdateOne) Mutation() *KeysMutation { - return kuo.mutation +func (_u *KeysUpdateOne) Mutation() *KeysMutation { + return _u.mutation +} + +// Where appends a list predicates to the KeysUpdate builder. +func (_u *KeysUpdateOne) Where(ps ...predicate.Keys) *KeysUpdateOne { + _u.mutation.Where(ps...) + return _u } // Select allows selecting one or more fields (columns) of the returned entity. // The default is selecting all fields defined in the entity schema. -func (kuo *KeysUpdateOne) Select(field string, fields ...string) *KeysUpdateOne { - kuo.fields = append([]string{field}, fields...) - return kuo +func (_u *KeysUpdateOne) Select(field string, fields ...string) *KeysUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u } // Save executes the query and returns the updated Keys entity. -func (kuo *KeysUpdateOne) Save(ctx context.Context) (*Keys, error) { - var ( - err error - node *Keys - ) - if len(kuo.hooks) == 0 { - node, err = kuo.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*KeysMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - kuo.mutation = mutation - node, err = kuo.sqlSave(ctx) - mutation.done = true - return node, err - }) - for i := len(kuo.hooks) - 1; i >= 0; i-- { - if kuo.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = kuo.hooks[i](mut) - } - v, err := mut.Mutate(ctx, kuo.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*Keys) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from KeysMutation", v) - } - node = nv - } - return node, err +func (_u *KeysUpdateOne) Save(ctx context.Context) (*Keys, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (kuo *KeysUpdateOne) SaveX(ctx context.Context) *Keys { - node, err := kuo.Save(ctx) +func (_u *KeysUpdateOne) SaveX(ctx context.Context) *Keys { + node, err := _u.Save(ctx) if err != nil { panic(err) } @@ -262,35 +250,26 @@ func (kuo *KeysUpdateOne) SaveX(ctx context.Context) *Keys { } // Exec executes the query on the entity. -func (kuo *KeysUpdateOne) Exec(ctx context.Context) error { - _, err := kuo.Save(ctx) +func (_u *KeysUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (kuo *KeysUpdateOne) ExecX(ctx context.Context) { - if err := kuo.Exec(ctx); err != nil { +func (_u *KeysUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } -func (kuo *KeysUpdateOne) sqlSave(ctx context.Context) (_node *Keys, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: keys.Table, - Columns: keys.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: keys.FieldID, - }, - }, - } - id, ok := kuo.mutation.ID() +func (_u *KeysUpdateOne) sqlSave(ctx context.Context) (_node *Keys, err error) { + _spec := sqlgraph.NewUpdateSpec(keys.Table, keys.Columns, sqlgraph.NewFieldSpec(keys.FieldID, field.TypeString)) + id, ok := _u.mutation.ID() if !ok { return nil, &ValidationError{Name: "id", err: errors.New(`db: missing "Keys.id" for update`)} } _spec.Node.ID.Value = id - if fields := kuo.fields; len(fields) > 0 { + if fields := _u.fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, keys.FieldID) for _, f := range fields { @@ -302,45 +281,34 @@ func (kuo *KeysUpdateOne) sqlSave(ctx context.Context) (_node *Keys, err error) } } } - if ps := kuo.mutation.predicates; len(ps) > 0 { + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := kuo.mutation.VerificationKeys(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: keys.FieldVerificationKeys, - }) + if value, ok := _u.mutation.VerificationKeys(); ok { + _spec.SetField(keys.FieldVerificationKeys, field.TypeJSON, value) } - if value, ok := kuo.mutation.SigningKey(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: keys.FieldSigningKey, + if value, ok := _u.mutation.AppendedVerificationKeys(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, keys.FieldVerificationKeys, value) }) } - if value, ok := kuo.mutation.SigningKeyPub(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: keys.FieldSigningKeyPub, - }) + if value, ok := _u.mutation.SigningKey(); ok { + _spec.SetField(keys.FieldSigningKey, field.TypeJSON, value) } - if value, ok := kuo.mutation.NextRotation(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: keys.FieldNextRotation, - }) + if value, ok := _u.mutation.SigningKeyPub(); ok { + _spec.SetField(keys.FieldSigningKeyPub, field.TypeJSON, value) + } + if value, ok := _u.mutation.NextRotation(); ok { + _spec.SetField(keys.FieldNextRotation, field.TypeTime, value) } - _node = &Keys{config: kuo.config} + _node = &Keys{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues - if err = sqlgraph.UpdateNode(ctx, kuo.driver, _spec); err != nil { + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{keys.Label} } else if sqlgraph.IsConstraintError(err) { @@ -348,5 +316,6 @@ func (kuo *KeysUpdateOne) sqlSave(ctx context.Context) (_node *Keys, err error) } return nil, err } + _u.mutation.done = true return _node, nil } diff --git a/storage/ent/db/migrate/migrate.go b/storage/ent/db/migrate/migrate.go index 6bccf3918a..1956a6bf64 100644 --- a/storage/ent/db/migrate/migrate.go +++ b/storage/ent/db/migrate/migrate.go @@ -56,10 +56,9 @@ func Create(ctx context.Context, s *Schema, tables []*schema.Table, opts ...sche // WriteTo writes the schema changes to w instead of running them against the database. // -// if err := client.Schema.WriteTo(context.Background(), os.Stdout); err != nil { +// if err := client.Schema.WriteTo(context.Background(), os.Stdout); err != nil { // log.Fatal(err) -// } -// +// } func (s *Schema) WriteTo(ctx context.Context, w io.Writer, opts ...schema.MigrateOption) error { return Create(ctx, &Schema{drv: &schema.WriteDriver{Writer: w, Driver: s.drv}}, Tables, opts...) } diff --git a/storage/ent/db/migrate/schema.go b/storage/ent/db/migrate/schema.go index ced57b32d9..d3295a0c79 100644 --- a/storage/ent/db/migrate/schema.go +++ b/storage/ent/db/migrate/schema.go @@ -55,6 +55,7 @@ var ( {Name: "expiry", Type: field.TypeTime, SchemaType: map[string]string{"mysql": "datetime(3)", "postgres": "timestamptz", "sqlite3": "timestamp"}}, {Name: "code_challenge", Type: field.TypeString, Size: 2147483647, Default: "", SchemaType: map[string]string{"mysql": "varchar(384)", "postgres": "text", "sqlite3": "text"}}, {Name: "code_challenge_method", Type: field.TypeString, Size: 2147483647, Default: "", SchemaType: map[string]string{"mysql": "varchar(384)", "postgres": "text", "sqlite3": "text"}}, + {Name: "hmac_key", Type: field.TypeBytes}, } // AuthRequestsTable holds the schema information for the "auth_requests" table. AuthRequestsTable = &schema.Table{ diff --git a/storage/ent/db/mutation.go b/storage/ent/db/mutation.go index af12a242bc..71203574e6 100644 --- a/storage/ent/db/mutation.go +++ b/storage/ent/db/mutation.go @@ -9,6 +9,8 @@ import ( "sync" "time" + "entgo.io/ent" + "entgo.io/ent/dialect/sql" "github.com/dexidp/dex/storage" "github.com/dexidp/dex/storage/ent/db/authcode" "github.com/dexidp/dex/storage/ent/db/authrequest" @@ -21,9 +23,7 @@ import ( "github.com/dexidp/dex/storage/ent/db/password" "github.com/dexidp/dex/storage/ent/db/predicate" "github.com/dexidp/dex/storage/ent/db/refreshtoken" - jose "gopkg.in/square/go-jose.v2" - - "entgo.io/ent" + jose "github.com/go-jose/go-jose/v4" ) const ( @@ -55,6 +55,7 @@ type AuthCodeMutation struct { id *string client_id *string scopes *[]string + appendscopes []string nonce *string redirect_uri *string claims_user_id *string @@ -62,6 +63,7 @@ type AuthCodeMutation struct { claims_email *string claims_email_verified *bool claims_groups *[]string + appendclaims_groups []string claims_preferred_username *string connector_id *string connector_data *[]byte @@ -217,6 +219,7 @@ func (m *AuthCodeMutation) ResetClientID() { // SetScopes sets the "scopes" field. func (m *AuthCodeMutation) SetScopes(s []string) { m.scopes = &s + m.appendscopes = nil } // Scopes returns the value of the "scopes" field in the mutation. @@ -245,9 +248,23 @@ func (m *AuthCodeMutation) OldScopes(ctx context.Context) (v []string, err error return oldValue.Scopes, nil } +// AppendScopes adds s to the "scopes" field. +func (m *AuthCodeMutation) AppendScopes(s []string) { + m.appendscopes = append(m.appendscopes, s...) +} + +// AppendedScopes returns the list of values that were appended to the "scopes" field in this mutation. +func (m *AuthCodeMutation) AppendedScopes() ([]string, bool) { + if len(m.appendscopes) == 0 { + return nil, false + } + return m.appendscopes, true +} + // ClearScopes clears the value of the "scopes" field. func (m *AuthCodeMutation) ClearScopes() { m.scopes = nil + m.appendscopes = nil m.clearedFields[authcode.FieldScopes] = struct{}{} } @@ -260,6 +277,7 @@ func (m *AuthCodeMutation) ScopesCleared() bool { // ResetScopes resets all changes to the "scopes" field. func (m *AuthCodeMutation) ResetScopes() { m.scopes = nil + m.appendscopes = nil delete(m.clearedFields, authcode.FieldScopes) } @@ -482,6 +500,7 @@ func (m *AuthCodeMutation) ResetClaimsEmailVerified() { // SetClaimsGroups sets the "claims_groups" field. func (m *AuthCodeMutation) SetClaimsGroups(s []string) { m.claims_groups = &s + m.appendclaims_groups = nil } // ClaimsGroups returns the value of the "claims_groups" field in the mutation. @@ -510,9 +529,23 @@ func (m *AuthCodeMutation) OldClaimsGroups(ctx context.Context) (v []string, err return oldValue.ClaimsGroups, nil } +// AppendClaimsGroups adds s to the "claims_groups" field. +func (m *AuthCodeMutation) AppendClaimsGroups(s []string) { + m.appendclaims_groups = append(m.appendclaims_groups, s...) +} + +// AppendedClaimsGroups returns the list of values that were appended to the "claims_groups" field in this mutation. +func (m *AuthCodeMutation) AppendedClaimsGroups() ([]string, bool) { + if len(m.appendclaims_groups) == 0 { + return nil, false + } + return m.appendclaims_groups, true +} + // ClearClaimsGroups clears the value of the "claims_groups" field. func (m *AuthCodeMutation) ClearClaimsGroups() { m.claims_groups = nil + m.appendclaims_groups = nil m.clearedFields[authcode.FieldClaimsGroups] = struct{}{} } @@ -525,6 +558,7 @@ func (m *AuthCodeMutation) ClaimsGroupsCleared() bool { // ResetClaimsGroups resets all changes to the "claims_groups" field. func (m *AuthCodeMutation) ResetClaimsGroups() { m.claims_groups = nil + m.appendclaims_groups = nil delete(m.clearedFields, authcode.FieldClaimsGroups) } @@ -762,11 +796,26 @@ func (m *AuthCodeMutation) Where(ps ...predicate.AuthCode) { m.predicates = append(m.predicates, ps...) } +// WhereP appends storage-level predicates to the AuthCodeMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *AuthCodeMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.AuthCode, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + // Op returns the operation name. func (m *AuthCodeMutation) Op() Op { return m.op } +// SetOp allows setting the mutation operation. +func (m *AuthCodeMutation) SetOp(op Op) { + m.op = op +} + // Type returns the node type of this mutation (AuthCode). func (m *AuthCodeMutation) Type() string { return m.typ @@ -1188,7 +1237,9 @@ type AuthRequestMutation struct { id *string client_id *string scopes *[]string + appendscopes []string response_types *[]string + appendresponse_types []string redirect_uri *string nonce *string state *string @@ -1199,12 +1250,14 @@ type AuthRequestMutation struct { claims_email *string claims_email_verified *bool claims_groups *[]string + appendclaims_groups []string claims_preferred_username *string connector_id *string connector_data *[]byte expiry *time.Time code_challenge *string code_challenge_method *string + hmac_key *[]byte clearedFields map[string]struct{} done bool oldValue func(context.Context) (*AuthRequest, error) @@ -1354,6 +1407,7 @@ func (m *AuthRequestMutation) ResetClientID() { // SetScopes sets the "scopes" field. func (m *AuthRequestMutation) SetScopes(s []string) { m.scopes = &s + m.appendscopes = nil } // Scopes returns the value of the "scopes" field in the mutation. @@ -1382,9 +1436,23 @@ func (m *AuthRequestMutation) OldScopes(ctx context.Context) (v []string, err er return oldValue.Scopes, nil } +// AppendScopes adds s to the "scopes" field. +func (m *AuthRequestMutation) AppendScopes(s []string) { + m.appendscopes = append(m.appendscopes, s...) +} + +// AppendedScopes returns the list of values that were appended to the "scopes" field in this mutation. +func (m *AuthRequestMutation) AppendedScopes() ([]string, bool) { + if len(m.appendscopes) == 0 { + return nil, false + } + return m.appendscopes, true +} + // ClearScopes clears the value of the "scopes" field. func (m *AuthRequestMutation) ClearScopes() { m.scopes = nil + m.appendscopes = nil m.clearedFields[authrequest.FieldScopes] = struct{}{} } @@ -1397,12 +1465,14 @@ func (m *AuthRequestMutation) ScopesCleared() bool { // ResetScopes resets all changes to the "scopes" field. func (m *AuthRequestMutation) ResetScopes() { m.scopes = nil + m.appendscopes = nil delete(m.clearedFields, authrequest.FieldScopes) } // SetResponseTypes sets the "response_types" field. func (m *AuthRequestMutation) SetResponseTypes(s []string) { m.response_types = &s + m.appendresponse_types = nil } // ResponseTypes returns the value of the "response_types" field in the mutation. @@ -1431,9 +1501,23 @@ func (m *AuthRequestMutation) OldResponseTypes(ctx context.Context) (v []string, return oldValue.ResponseTypes, nil } +// AppendResponseTypes adds s to the "response_types" field. +func (m *AuthRequestMutation) AppendResponseTypes(s []string) { + m.appendresponse_types = append(m.appendresponse_types, s...) +} + +// AppendedResponseTypes returns the list of values that were appended to the "response_types" field in this mutation. +func (m *AuthRequestMutation) AppendedResponseTypes() ([]string, bool) { + if len(m.appendresponse_types) == 0 { + return nil, false + } + return m.appendresponse_types, true +} + // ClearResponseTypes clears the value of the "response_types" field. func (m *AuthRequestMutation) ClearResponseTypes() { m.response_types = nil + m.appendresponse_types = nil m.clearedFields[authrequest.FieldResponseTypes] = struct{}{} } @@ -1446,6 +1530,7 @@ func (m *AuthRequestMutation) ResponseTypesCleared() bool { // ResetResponseTypes resets all changes to the "response_types" field. func (m *AuthRequestMutation) ResetResponseTypes() { m.response_types = nil + m.appendresponse_types = nil delete(m.clearedFields, authrequest.FieldResponseTypes) } @@ -1776,6 +1861,7 @@ func (m *AuthRequestMutation) ResetClaimsEmailVerified() { // SetClaimsGroups sets the "claims_groups" field. func (m *AuthRequestMutation) SetClaimsGroups(s []string) { m.claims_groups = &s + m.appendclaims_groups = nil } // ClaimsGroups returns the value of the "claims_groups" field in the mutation. @@ -1804,9 +1890,23 @@ func (m *AuthRequestMutation) OldClaimsGroups(ctx context.Context) (v []string, return oldValue.ClaimsGroups, nil } +// AppendClaimsGroups adds s to the "claims_groups" field. +func (m *AuthRequestMutation) AppendClaimsGroups(s []string) { + m.appendclaims_groups = append(m.appendclaims_groups, s...) +} + +// AppendedClaimsGroups returns the list of values that were appended to the "claims_groups" field in this mutation. +func (m *AuthRequestMutation) AppendedClaimsGroups() ([]string, bool) { + if len(m.appendclaims_groups) == 0 { + return nil, false + } + return m.appendclaims_groups, true +} + // ClearClaimsGroups clears the value of the "claims_groups" field. func (m *AuthRequestMutation) ClearClaimsGroups() { m.claims_groups = nil + m.appendclaims_groups = nil m.clearedFields[authrequest.FieldClaimsGroups] = struct{}{} } @@ -1819,6 +1919,7 @@ func (m *AuthRequestMutation) ClaimsGroupsCleared() bool { // ResetClaimsGroups resets all changes to the "claims_groups" field. func (m *AuthRequestMutation) ResetClaimsGroups() { m.claims_groups = nil + m.appendclaims_groups = nil delete(m.clearedFields, authrequest.FieldClaimsGroups) } @@ -2051,16 +2152,67 @@ func (m *AuthRequestMutation) ResetCodeChallengeMethod() { m.code_challenge_method = nil } +// SetHmacKey sets the "hmac_key" field. +func (m *AuthRequestMutation) SetHmacKey(b []byte) { + m.hmac_key = &b +} + +// HmacKey returns the value of the "hmac_key" field in the mutation. +func (m *AuthRequestMutation) HmacKey() (r []byte, exists bool) { + v := m.hmac_key + if v == nil { + return + } + return *v, true +} + +// OldHmacKey returns the old "hmac_key" field's value of the AuthRequest entity. +// If the AuthRequest object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *AuthRequestMutation) OldHmacKey(ctx context.Context) (v []byte, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldHmacKey is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldHmacKey requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldHmacKey: %w", err) + } + return oldValue.HmacKey, nil +} + +// ResetHmacKey resets all changes to the "hmac_key" field. +func (m *AuthRequestMutation) ResetHmacKey() { + m.hmac_key = nil +} + // Where appends a list predicates to the AuthRequestMutation builder. func (m *AuthRequestMutation) Where(ps ...predicate.AuthRequest) { m.predicates = append(m.predicates, ps...) } +// WhereP appends storage-level predicates to the AuthRequestMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *AuthRequestMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.AuthRequest, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + // Op returns the operation name. func (m *AuthRequestMutation) Op() Op { return m.op } +// SetOp allows setting the mutation operation. +func (m *AuthRequestMutation) SetOp(op Op) { + m.op = op +} + // Type returns the node type of this mutation (AuthRequest). func (m *AuthRequestMutation) Type() string { return m.typ @@ -2070,7 +2222,7 @@ func (m *AuthRequestMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *AuthRequestMutation) Fields() []string { - fields := make([]string, 0, 19) + fields := make([]string, 0, 20) if m.client_id != nil { fields = append(fields, authrequest.FieldClientID) } @@ -2128,6 +2280,9 @@ func (m *AuthRequestMutation) Fields() []string { if m.code_challenge_method != nil { fields = append(fields, authrequest.FieldCodeChallengeMethod) } + if m.hmac_key != nil { + fields = append(fields, authrequest.FieldHmacKey) + } return fields } @@ -2174,6 +2329,8 @@ func (m *AuthRequestMutation) Field(name string) (ent.Value, bool) { return m.CodeChallenge() case authrequest.FieldCodeChallengeMethod: return m.CodeChallengeMethod() + case authrequest.FieldHmacKey: + return m.HmacKey() } return nil, false } @@ -2221,6 +2378,8 @@ func (m *AuthRequestMutation) OldField(ctx context.Context, name string) (ent.Va return m.OldCodeChallenge(ctx) case authrequest.FieldCodeChallengeMethod: return m.OldCodeChallengeMethod(ctx) + case authrequest.FieldHmacKey: + return m.OldHmacKey(ctx) } return nil, fmt.Errorf("unknown AuthRequest field %s", name) } @@ -2363,6 +2522,13 @@ func (m *AuthRequestMutation) SetField(name string, value ent.Value) error { } m.SetCodeChallengeMethod(v) return nil + case authrequest.FieldHmacKey: + v, ok := value.([]byte) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetHmacKey(v) + return nil } return fmt.Errorf("unknown AuthRequest field %s", name) } @@ -2496,6 +2662,9 @@ func (m *AuthRequestMutation) ResetField(name string) error { case authrequest.FieldCodeChallengeMethod: m.ResetCodeChallengeMethod() return nil + case authrequest.FieldHmacKey: + m.ResetHmacKey() + return nil } return fmt.Errorf("unknown AuthRequest field %s", name) } @@ -2817,11 +2986,26 @@ func (m *ConnectorMutation) Where(ps ...predicate.Connector) { m.predicates = append(m.predicates, ps...) } +// WhereP appends storage-level predicates to the ConnectorMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *ConnectorMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.Connector, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + // Op returns the operation name. func (m *ConnectorMutation) Op() Op { return m.op } +// SetOp allows setting the mutation operation. +func (m *ConnectorMutation) SetOp(op Op) { + m.op = op +} + // Type returns the node type of this mutation (Connector). func (m *ConnectorMutation) Type() string { return m.typ @@ -3038,6 +3222,7 @@ type DeviceRequestMutation struct { client_id *string client_secret *string scopes *[]string + appendscopes []string expiry *time.Time clearedFields map[string]struct{} done bool @@ -3290,6 +3475,7 @@ func (m *DeviceRequestMutation) ResetClientSecret() { // SetScopes sets the "scopes" field. func (m *DeviceRequestMutation) SetScopes(s []string) { m.scopes = &s + m.appendscopes = nil } // Scopes returns the value of the "scopes" field in the mutation. @@ -3318,9 +3504,23 @@ func (m *DeviceRequestMutation) OldScopes(ctx context.Context) (v []string, err return oldValue.Scopes, nil } +// AppendScopes adds s to the "scopes" field. +func (m *DeviceRequestMutation) AppendScopes(s []string) { + m.appendscopes = append(m.appendscopes, s...) +} + +// AppendedScopes returns the list of values that were appended to the "scopes" field in this mutation. +func (m *DeviceRequestMutation) AppendedScopes() ([]string, bool) { + if len(m.appendscopes) == 0 { + return nil, false + } + return m.appendscopes, true +} + // ClearScopes clears the value of the "scopes" field. func (m *DeviceRequestMutation) ClearScopes() { m.scopes = nil + m.appendscopes = nil m.clearedFields[devicerequest.FieldScopes] = struct{}{} } @@ -3333,6 +3533,7 @@ func (m *DeviceRequestMutation) ScopesCleared() bool { // ResetScopes resets all changes to the "scopes" field. func (m *DeviceRequestMutation) ResetScopes() { m.scopes = nil + m.appendscopes = nil delete(m.clearedFields, devicerequest.FieldScopes) } @@ -3377,11 +3578,26 @@ func (m *DeviceRequestMutation) Where(ps ...predicate.DeviceRequest) { m.predicates = append(m.predicates, ps...) } +// WhereP appends storage-level predicates to the DeviceRequestMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *DeviceRequestMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.DeviceRequest, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + // Op returns the operation name. func (m *DeviceRequestMutation) Op() Op { return m.op } +// SetOp allows setting the mutation operation. +func (m *DeviceRequestMutation) SetOp(op Op) { + m.op = op +} + // Type returns the node type of this mutation (DeviceRequest). func (m *DeviceRequestMutation) Type() string { return m.typ @@ -4075,11 +4291,26 @@ func (m *DeviceTokenMutation) Where(ps ...predicate.DeviceToken) { m.predicates = append(m.predicates, ps...) } +// WhereP appends storage-level predicates to the DeviceTokenMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *DeviceTokenMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.DeviceToken, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + // Op returns the operation name. func (m *DeviceTokenMutation) Op() Op { return m.op } +// SetOp allows setting the mutation operation. +func (m *DeviceTokenMutation) SetOp(op Op) { + m.op = op +} + // Type returns the node type of this mutation (DeviceToken). func (m *DeviceTokenMutation) Type() string { return m.typ @@ -4380,17 +4611,18 @@ func (m *DeviceTokenMutation) ResetEdge(name string) error { // KeysMutation represents an operation that mutates the Keys nodes in the graph. type KeysMutation struct { config - op Op - typ string - id *string - verification_keys *[]storage.VerificationKey - signing_key *jose.JSONWebKey - signing_key_pub *jose.JSONWebKey - next_rotation *time.Time - clearedFields map[string]struct{} - done bool - oldValue func(context.Context) (*Keys, error) - predicates []predicate.Keys + op Op + typ string + id *string + verification_keys *[]storage.VerificationKey + appendverification_keys []storage.VerificationKey + signing_key *jose.JSONWebKey + signing_key_pub *jose.JSONWebKey + next_rotation *time.Time + clearedFields map[string]struct{} + done bool + oldValue func(context.Context) (*Keys, error) + predicates []predicate.Keys } var _ ent.Mutation = (*KeysMutation)(nil) @@ -4500,6 +4732,7 @@ func (m *KeysMutation) IDs(ctx context.Context) ([]string, error) { // SetVerificationKeys sets the "verification_keys" field. func (m *KeysMutation) SetVerificationKeys(sk []storage.VerificationKey) { m.verification_keys = &sk + m.appendverification_keys = nil } // VerificationKeys returns the value of the "verification_keys" field in the mutation. @@ -4528,9 +4761,23 @@ func (m *KeysMutation) OldVerificationKeys(ctx context.Context) (v []storage.Ver return oldValue.VerificationKeys, nil } +// AppendVerificationKeys adds sk to the "verification_keys" field. +func (m *KeysMutation) AppendVerificationKeys(sk []storage.VerificationKey) { + m.appendverification_keys = append(m.appendverification_keys, sk...) +} + +// AppendedVerificationKeys returns the list of values that were appended to the "verification_keys" field in this mutation. +func (m *KeysMutation) AppendedVerificationKeys() ([]storage.VerificationKey, bool) { + if len(m.appendverification_keys) == 0 { + return nil, false + } + return m.appendverification_keys, true +} + // ResetVerificationKeys resets all changes to the "verification_keys" field. func (m *KeysMutation) ResetVerificationKeys() { m.verification_keys = nil + m.appendverification_keys = nil } // SetSigningKey sets the "signing_key" field. @@ -4646,11 +4893,26 @@ func (m *KeysMutation) Where(ps ...predicate.Keys) { m.predicates = append(m.predicates, ps...) } +// WhereP appends storage-level predicates to the KeysMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *KeysMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.Keys, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + // Op returns the operation name. func (m *KeysMutation) Op() Op { return m.op } +// SetOp allows setting the mutation operation. +func (m *KeysMutation) SetOp(op Op) { + m.op = op +} + // Type returns the node type of this mutation (Keys). func (m *KeysMutation) Type() string { return m.typ @@ -4859,19 +5121,21 @@ func (m *KeysMutation) ResetEdge(name string) error { // OAuth2ClientMutation represents an operation that mutates the OAuth2Client nodes in the graph. type OAuth2ClientMutation struct { config - op Op - typ string - id *string - secret *string - redirect_uris *[]string - trusted_peers *[]string - public *bool - name *string - logo_url *string - clearedFields map[string]struct{} - done bool - oldValue func(context.Context) (*OAuth2Client, error) - predicates []predicate.OAuth2Client + op Op + typ string + id *string + secret *string + redirect_uris *[]string + appendredirect_uris []string + trusted_peers *[]string + appendtrusted_peers []string + public *bool + name *string + logo_url *string + clearedFields map[string]struct{} + done bool + oldValue func(context.Context) (*OAuth2Client, error) + predicates []predicate.OAuth2Client } var _ ent.Mutation = (*OAuth2ClientMutation)(nil) @@ -5017,6 +5281,7 @@ func (m *OAuth2ClientMutation) ResetSecret() { // SetRedirectUris sets the "redirect_uris" field. func (m *OAuth2ClientMutation) SetRedirectUris(s []string) { m.redirect_uris = &s + m.appendredirect_uris = nil } // RedirectUris returns the value of the "redirect_uris" field in the mutation. @@ -5045,9 +5310,23 @@ func (m *OAuth2ClientMutation) OldRedirectUris(ctx context.Context) (v []string, return oldValue.RedirectUris, nil } +// AppendRedirectUris adds s to the "redirect_uris" field. +func (m *OAuth2ClientMutation) AppendRedirectUris(s []string) { + m.appendredirect_uris = append(m.appendredirect_uris, s...) +} + +// AppendedRedirectUris returns the list of values that were appended to the "redirect_uris" field in this mutation. +func (m *OAuth2ClientMutation) AppendedRedirectUris() ([]string, bool) { + if len(m.appendredirect_uris) == 0 { + return nil, false + } + return m.appendredirect_uris, true +} + // ClearRedirectUris clears the value of the "redirect_uris" field. func (m *OAuth2ClientMutation) ClearRedirectUris() { m.redirect_uris = nil + m.appendredirect_uris = nil m.clearedFields[oauth2client.FieldRedirectUris] = struct{}{} } @@ -5060,12 +5339,14 @@ func (m *OAuth2ClientMutation) RedirectUrisCleared() bool { // ResetRedirectUris resets all changes to the "redirect_uris" field. func (m *OAuth2ClientMutation) ResetRedirectUris() { m.redirect_uris = nil + m.appendredirect_uris = nil delete(m.clearedFields, oauth2client.FieldRedirectUris) } // SetTrustedPeers sets the "trusted_peers" field. func (m *OAuth2ClientMutation) SetTrustedPeers(s []string) { m.trusted_peers = &s + m.appendtrusted_peers = nil } // TrustedPeers returns the value of the "trusted_peers" field in the mutation. @@ -5094,9 +5375,23 @@ func (m *OAuth2ClientMutation) OldTrustedPeers(ctx context.Context) (v []string, return oldValue.TrustedPeers, nil } +// AppendTrustedPeers adds s to the "trusted_peers" field. +func (m *OAuth2ClientMutation) AppendTrustedPeers(s []string) { + m.appendtrusted_peers = append(m.appendtrusted_peers, s...) +} + +// AppendedTrustedPeers returns the list of values that were appended to the "trusted_peers" field in this mutation. +func (m *OAuth2ClientMutation) AppendedTrustedPeers() ([]string, bool) { + if len(m.appendtrusted_peers) == 0 { + return nil, false + } + return m.appendtrusted_peers, true +} + // ClearTrustedPeers clears the value of the "trusted_peers" field. func (m *OAuth2ClientMutation) ClearTrustedPeers() { m.trusted_peers = nil + m.appendtrusted_peers = nil m.clearedFields[oauth2client.FieldTrustedPeers] = struct{}{} } @@ -5109,6 +5404,7 @@ func (m *OAuth2ClientMutation) TrustedPeersCleared() bool { // ResetTrustedPeers resets all changes to the "trusted_peers" field. func (m *OAuth2ClientMutation) ResetTrustedPeers() { m.trusted_peers = nil + m.appendtrusted_peers = nil delete(m.clearedFields, oauth2client.FieldTrustedPeers) } @@ -5225,11 +5521,26 @@ func (m *OAuth2ClientMutation) Where(ps ...predicate.OAuth2Client) { m.predicates = append(m.predicates, ps...) } +// WhereP appends storage-level predicates to the OAuth2ClientMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *OAuth2ClientMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.OAuth2Client, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + // Op returns the operation name. func (m *OAuth2ClientMutation) Op() Op { return m.op } +// SetOp allows setting the mutation operation. +func (m *OAuth2ClientMutation) SetOp(op Op) { + m.op = op +} + // Type returns the node type of this mutation (OAuth2Client). func (m *OAuth2ClientMutation) Type() string { return m.typ @@ -5766,11 +6077,26 @@ func (m *OfflineSessionMutation) Where(ps ...predicate.OfflineSession) { m.predicates = append(m.predicates, ps...) } +// WhereP appends storage-level predicates to the OfflineSessionMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *OfflineSessionMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.OfflineSession, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + // Op returns the operation name. func (m *OfflineSessionMutation) Op() Op { return m.op } +// SetOp allows setting the mutation operation. +func (m *OfflineSessionMutation) SetOp(op Op) { + m.op = op +} + // Type returns the node type of this mutation (OfflineSession). func (m *OfflineSessionMutation) Type() string { return m.typ @@ -6248,11 +6574,26 @@ func (m *PasswordMutation) Where(ps ...predicate.Password) { m.predicates = append(m.predicates, ps...) } +// WhereP appends storage-level predicates to the PasswordMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *PasswordMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.Password, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + // Op returns the operation name. func (m *PasswordMutation) Op() Op { return m.op } +// SetOp allows setting the mutation operation. +func (m *PasswordMutation) SetOp(op Op) { + m.op = op +} + // Type returns the node type of this mutation (Password). func (m *PasswordMutation) Type() string { return m.typ @@ -6466,12 +6807,14 @@ type RefreshTokenMutation struct { id *string client_id *string scopes *[]string + appendscopes []string nonce *string claims_user_id *string claims_username *string claims_email *string claims_email_verified *bool claims_groups *[]string + appendclaims_groups []string claims_preferred_username *string connector_id *string connector_data *[]byte @@ -6628,6 +6971,7 @@ func (m *RefreshTokenMutation) ResetClientID() { // SetScopes sets the "scopes" field. func (m *RefreshTokenMutation) SetScopes(s []string) { m.scopes = &s + m.appendscopes = nil } // Scopes returns the value of the "scopes" field in the mutation. @@ -6656,9 +7000,23 @@ func (m *RefreshTokenMutation) OldScopes(ctx context.Context) (v []string, err e return oldValue.Scopes, nil } +// AppendScopes adds s to the "scopes" field. +func (m *RefreshTokenMutation) AppendScopes(s []string) { + m.appendscopes = append(m.appendscopes, s...) +} + +// AppendedScopes returns the list of values that were appended to the "scopes" field in this mutation. +func (m *RefreshTokenMutation) AppendedScopes() ([]string, bool) { + if len(m.appendscopes) == 0 { + return nil, false + } + return m.appendscopes, true +} + // ClearScopes clears the value of the "scopes" field. func (m *RefreshTokenMutation) ClearScopes() { m.scopes = nil + m.appendscopes = nil m.clearedFields[refreshtoken.FieldScopes] = struct{}{} } @@ -6671,6 +7029,7 @@ func (m *RefreshTokenMutation) ScopesCleared() bool { // ResetScopes resets all changes to the "scopes" field. func (m *RefreshTokenMutation) ResetScopes() { m.scopes = nil + m.appendscopes = nil delete(m.clearedFields, refreshtoken.FieldScopes) } @@ -6857,6 +7216,7 @@ func (m *RefreshTokenMutation) ResetClaimsEmailVerified() { // SetClaimsGroups sets the "claims_groups" field. func (m *RefreshTokenMutation) SetClaimsGroups(s []string) { m.claims_groups = &s + m.appendclaims_groups = nil } // ClaimsGroups returns the value of the "claims_groups" field in the mutation. @@ -6885,9 +7245,23 @@ func (m *RefreshTokenMutation) OldClaimsGroups(ctx context.Context) (v []string, return oldValue.ClaimsGroups, nil } +// AppendClaimsGroups adds s to the "claims_groups" field. +func (m *RefreshTokenMutation) AppendClaimsGroups(s []string) { + m.appendclaims_groups = append(m.appendclaims_groups, s...) +} + +// AppendedClaimsGroups returns the list of values that were appended to the "claims_groups" field in this mutation. +func (m *RefreshTokenMutation) AppendedClaimsGroups() ([]string, bool) { + if len(m.appendclaims_groups) == 0 { + return nil, false + } + return m.appendclaims_groups, true +} + // ClearClaimsGroups clears the value of the "claims_groups" field. func (m *RefreshTokenMutation) ClearClaimsGroups() { m.claims_groups = nil + m.appendclaims_groups = nil m.clearedFields[refreshtoken.FieldClaimsGroups] = struct{}{} } @@ -6900,6 +7274,7 @@ func (m *RefreshTokenMutation) ClaimsGroupsCleared() bool { // ResetClaimsGroups resets all changes to the "claims_groups" field. func (m *RefreshTokenMutation) ResetClaimsGroups() { m.claims_groups = nil + m.appendclaims_groups = nil delete(m.clearedFields, refreshtoken.FieldClaimsGroups) } @@ -7173,11 +7548,26 @@ func (m *RefreshTokenMutation) Where(ps ...predicate.RefreshToken) { m.predicates = append(m.predicates, ps...) } +// WhereP appends storage-level predicates to the RefreshTokenMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *RefreshTokenMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.RefreshToken, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + // Op returns the operation name. func (m *RefreshTokenMutation) Op() Op { return m.op } +// SetOp allows setting the mutation operation. +func (m *RefreshTokenMutation) SetOp(op Op) { + m.op = op +} + // Type returns the node type of this mutation (RefreshToken). func (m *RefreshTokenMutation) Type() string { return m.typ diff --git a/storage/ent/db/oauth2client.go b/storage/ent/db/oauth2client.go index f96ca218e1..f8491be21a 100644 --- a/storage/ent/db/oauth2client.go +++ b/storage/ent/db/oauth2client.go @@ -7,6 +7,7 @@ import ( "fmt" "strings" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/dexidp/dex/storage/ent/db/oauth2client" ) @@ -27,12 +28,13 @@ type OAuth2Client struct { // Name holds the value of the "name" field. Name string `json:"name,omitempty"` // LogoURL holds the value of the "logo_url" field. - LogoURL string `json:"logo_url,omitempty"` + LogoURL string `json:"logo_url,omitempty"` + selectValues sql.SelectValues } // scanValues returns the types for scanning values from sql.Rows. -func (*OAuth2Client) scanValues(columns []string) ([]interface{}, error) { - values := make([]interface{}, len(columns)) +func (*OAuth2Client) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) for i := range columns { switch columns[i] { case oauth2client.FieldRedirectUris, oauth2client.FieldTrustedPeers: @@ -42,7 +44,7 @@ func (*OAuth2Client) scanValues(columns []string) ([]interface{}, error) { case oauth2client.FieldID, oauth2client.FieldSecret, oauth2client.FieldName, oauth2client.FieldLogoURL: values[i] = new(sql.NullString) default: - return nil, fmt.Errorf("unexpected column %q for type OAuth2Client", columns[i]) + values[i] = new(sql.UnknownType) } } return values, nil @@ -50,7 +52,7 @@ func (*OAuth2Client) scanValues(columns []string) ([]interface{}, error) { // assignValues assigns the values that were returned from sql.Rows (after scanning) // to the OAuth2Client fields. -func (o *OAuth2Client) assignValues(columns []string, values []interface{}) error { +func (_m *OAuth2Client) assignValues(columns []string, values []any) error { if m, n := len(values), len(columns); m < n { return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) } @@ -60,19 +62,19 @@ func (o *OAuth2Client) assignValues(columns []string, values []interface{}) erro if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field id", values[i]) } else if value.Valid { - o.ID = value.String + _m.ID = value.String } case oauth2client.FieldSecret: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field secret", values[i]) } else if value.Valid { - o.Secret = value.String + _m.Secret = value.String } case oauth2client.FieldRedirectUris: if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field redirect_uris", values[i]) } else if value != nil && len(*value) > 0 { - if err := json.Unmarshal(*value, &o.RedirectUris); err != nil { + if err := json.Unmarshal(*value, &_m.RedirectUris); err != nil { return fmt.Errorf("unmarshal field redirect_uris: %w", err) } } @@ -80,7 +82,7 @@ func (o *OAuth2Client) assignValues(columns []string, values []interface{}) erro if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field trusted_peers", values[i]) } else if value != nil && len(*value) > 0 { - if err := json.Unmarshal(*value, &o.TrustedPeers); err != nil { + if err := json.Unmarshal(*value, &_m.TrustedPeers); err != nil { return fmt.Errorf("unmarshal field trusted_peers: %w", err) } } @@ -88,74 +90,76 @@ func (o *OAuth2Client) assignValues(columns []string, values []interface{}) erro if value, ok := values[i].(*sql.NullBool); !ok { return fmt.Errorf("unexpected type %T for field public", values[i]) } else if value.Valid { - o.Public = value.Bool + _m.Public = value.Bool } case oauth2client.FieldName: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field name", values[i]) } else if value.Valid { - o.Name = value.String + _m.Name = value.String } case oauth2client.FieldLogoURL: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field logo_url", values[i]) } else if value.Valid { - o.LogoURL = value.String + _m.LogoURL = value.String } + default: + _m.selectValues.Set(columns[i], values[i]) } } return nil } +// Value returns the ent.Value that was dynamically selected and assigned to the OAuth2Client. +// This includes values selected through modifiers, order, etc. +func (_m *OAuth2Client) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + // Update returns a builder for updating this OAuth2Client. // Note that you need to call OAuth2Client.Unwrap() before calling this method if this OAuth2Client // was returned from a transaction, and the transaction was committed or rolled back. -func (o *OAuth2Client) Update() *OAuth2ClientUpdateOne { - return (&OAuth2ClientClient{config: o.config}).UpdateOne(o) +func (_m *OAuth2Client) Update() *OAuth2ClientUpdateOne { + return NewOAuth2ClientClient(_m.config).UpdateOne(_m) } // Unwrap unwraps the OAuth2Client entity that was returned from a transaction after it was closed, // so that all future queries will be executed through the driver which created the transaction. -func (o *OAuth2Client) Unwrap() *OAuth2Client { - _tx, ok := o.config.driver.(*txDriver) +func (_m *OAuth2Client) Unwrap() *OAuth2Client { + _tx, ok := _m.config.driver.(*txDriver) if !ok { panic("db: OAuth2Client is not a transactional entity") } - o.config.driver = _tx.drv - return o + _m.config.driver = _tx.drv + return _m } // String implements the fmt.Stringer. -func (o *OAuth2Client) String() string { +func (_m *OAuth2Client) String() string { var builder strings.Builder builder.WriteString("OAuth2Client(") - builder.WriteString(fmt.Sprintf("id=%v, ", o.ID)) + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) builder.WriteString("secret=") - builder.WriteString(o.Secret) + builder.WriteString(_m.Secret) builder.WriteString(", ") builder.WriteString("redirect_uris=") - builder.WriteString(fmt.Sprintf("%v", o.RedirectUris)) + builder.WriteString(fmt.Sprintf("%v", _m.RedirectUris)) builder.WriteString(", ") builder.WriteString("trusted_peers=") - builder.WriteString(fmt.Sprintf("%v", o.TrustedPeers)) + builder.WriteString(fmt.Sprintf("%v", _m.TrustedPeers)) builder.WriteString(", ") builder.WriteString("public=") - builder.WriteString(fmt.Sprintf("%v", o.Public)) + builder.WriteString(fmt.Sprintf("%v", _m.Public)) builder.WriteString(", ") builder.WriteString("name=") - builder.WriteString(o.Name) + builder.WriteString(_m.Name) builder.WriteString(", ") builder.WriteString("logo_url=") - builder.WriteString(o.LogoURL) + builder.WriteString(_m.LogoURL) builder.WriteByte(')') return builder.String() } // OAuth2Clients is a parsable slice of OAuth2Client. type OAuth2Clients []*OAuth2Client - -func (o OAuth2Clients) config(cfg config) { - for _i := range o { - o[_i].config = cfg - } -} diff --git a/storage/ent/db/oauth2client/oauth2client.go b/storage/ent/db/oauth2client/oauth2client.go index 55b00c166b..08df76be9c 100644 --- a/storage/ent/db/oauth2client/oauth2client.go +++ b/storage/ent/db/oauth2client/oauth2client.go @@ -2,6 +2,10 @@ package oauth2client +import ( + "entgo.io/ent/dialect/sql" +) + const ( // Label holds the string label denoting the oauth2client type in the database. Label = "oauth2client" @@ -54,3 +58,31 @@ var ( // IDValidator is a validator for the "id" field. It is called by the builders before save. IDValidator func(string) error ) + +// OrderOption defines the ordering options for the OAuth2Client queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// BySecret orders the results by the secret field. +func BySecret(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldSecret, opts...).ToFunc() +} + +// ByPublic orders the results by the public field. +func ByPublic(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldPublic, opts...).ToFunc() +} + +// ByName orders the results by the name field. +func ByName(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldName, opts...).ToFunc() +} + +// ByLogoURL orders the results by the logo_url field. +func ByLogoURL(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldLogoURL, opts...).ToFunc() +} diff --git a/storage/ent/db/oauth2client/where.go b/storage/ent/db/oauth2client/where.go index d74a6ab78e..55aee79b1a 100644 --- a/storage/ent/db/oauth2client/where.go +++ b/storage/ent/db/oauth2client/where.go @@ -9,470 +9,315 @@ import ( // ID filters vertices based on their ID field. func ID(id string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.OAuth2Client(sql.FieldEQ(FieldID, id)) } // IDEQ applies the EQ predicate on the ID field. func IDEQ(id string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.OAuth2Client(sql.FieldEQ(FieldID, id)) } // IDNEQ applies the NEQ predicate on the ID field. func IDNEQ(id string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldID), id)) - }) + return predicate.OAuth2Client(sql.FieldNEQ(FieldID, id)) } // IDIn applies the In predicate on the ID field. func IDIn(ids ...string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.In(s.C(FieldID), v...)) - }) + return predicate.OAuth2Client(sql.FieldIn(FieldID, ids...)) } // IDNotIn applies the NotIn predicate on the ID field. func IDNotIn(ids ...string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.NotIn(s.C(FieldID), v...)) - }) + return predicate.OAuth2Client(sql.FieldNotIn(FieldID, ids...)) } // IDGT applies the GT predicate on the ID field. func IDGT(id string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldID), id)) - }) + return predicate.OAuth2Client(sql.FieldGT(FieldID, id)) } // IDGTE applies the GTE predicate on the ID field. func IDGTE(id string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldID), id)) - }) + return predicate.OAuth2Client(sql.FieldGTE(FieldID, id)) } // IDLT applies the LT predicate on the ID field. func IDLT(id string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldID), id)) - }) + return predicate.OAuth2Client(sql.FieldLT(FieldID, id)) } // IDLTE applies the LTE predicate on the ID field. func IDLTE(id string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldID), id)) - }) + return predicate.OAuth2Client(sql.FieldLTE(FieldID, id)) +} + +// IDEqualFold applies the EqualFold predicate on the ID field. +func IDEqualFold(id string) predicate.OAuth2Client { + return predicate.OAuth2Client(sql.FieldEqualFold(FieldID, id)) +} + +// IDContainsFold applies the ContainsFold predicate on the ID field. +func IDContainsFold(id string) predicate.OAuth2Client { + return predicate.OAuth2Client(sql.FieldContainsFold(FieldID, id)) } // Secret applies equality check predicate on the "secret" field. It's identical to SecretEQ. func Secret(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldSecret), v)) - }) + return predicate.OAuth2Client(sql.FieldEQ(FieldSecret, v)) } // Public applies equality check predicate on the "public" field. It's identical to PublicEQ. func Public(v bool) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldPublic), v)) - }) + return predicate.OAuth2Client(sql.FieldEQ(FieldPublic, v)) } // Name applies equality check predicate on the "name" field. It's identical to NameEQ. func Name(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldName), v)) - }) + return predicate.OAuth2Client(sql.FieldEQ(FieldName, v)) } // LogoURL applies equality check predicate on the "logo_url" field. It's identical to LogoURLEQ. func LogoURL(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldLogoURL), v)) - }) + return predicate.OAuth2Client(sql.FieldEQ(FieldLogoURL, v)) } // SecretEQ applies the EQ predicate on the "secret" field. func SecretEQ(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldSecret), v)) - }) + return predicate.OAuth2Client(sql.FieldEQ(FieldSecret, v)) } // SecretNEQ applies the NEQ predicate on the "secret" field. func SecretNEQ(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldSecret), v)) - }) + return predicate.OAuth2Client(sql.FieldNEQ(FieldSecret, v)) } // SecretIn applies the In predicate on the "secret" field. func SecretIn(vs ...string) predicate.OAuth2Client { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldSecret), v...)) - }) + return predicate.OAuth2Client(sql.FieldIn(FieldSecret, vs...)) } // SecretNotIn applies the NotIn predicate on the "secret" field. func SecretNotIn(vs ...string) predicate.OAuth2Client { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldSecret), v...)) - }) + return predicate.OAuth2Client(sql.FieldNotIn(FieldSecret, vs...)) } // SecretGT applies the GT predicate on the "secret" field. func SecretGT(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldSecret), v)) - }) + return predicate.OAuth2Client(sql.FieldGT(FieldSecret, v)) } // SecretGTE applies the GTE predicate on the "secret" field. func SecretGTE(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldSecret), v)) - }) + return predicate.OAuth2Client(sql.FieldGTE(FieldSecret, v)) } // SecretLT applies the LT predicate on the "secret" field. func SecretLT(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldSecret), v)) - }) + return predicate.OAuth2Client(sql.FieldLT(FieldSecret, v)) } // SecretLTE applies the LTE predicate on the "secret" field. func SecretLTE(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldSecret), v)) - }) + return predicate.OAuth2Client(sql.FieldLTE(FieldSecret, v)) } // SecretContains applies the Contains predicate on the "secret" field. func SecretContains(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldSecret), v)) - }) + return predicate.OAuth2Client(sql.FieldContains(FieldSecret, v)) } // SecretHasPrefix applies the HasPrefix predicate on the "secret" field. func SecretHasPrefix(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldSecret), v)) - }) + return predicate.OAuth2Client(sql.FieldHasPrefix(FieldSecret, v)) } // SecretHasSuffix applies the HasSuffix predicate on the "secret" field. func SecretHasSuffix(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldSecret), v)) - }) + return predicate.OAuth2Client(sql.FieldHasSuffix(FieldSecret, v)) } // SecretEqualFold applies the EqualFold predicate on the "secret" field. func SecretEqualFold(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldSecret), v)) - }) + return predicate.OAuth2Client(sql.FieldEqualFold(FieldSecret, v)) } // SecretContainsFold applies the ContainsFold predicate on the "secret" field. func SecretContainsFold(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldSecret), v)) - }) + return predicate.OAuth2Client(sql.FieldContainsFold(FieldSecret, v)) } // RedirectUrisIsNil applies the IsNil predicate on the "redirect_uris" field. func RedirectUrisIsNil() predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.IsNull(s.C(FieldRedirectUris))) - }) + return predicate.OAuth2Client(sql.FieldIsNull(FieldRedirectUris)) } // RedirectUrisNotNil applies the NotNil predicate on the "redirect_uris" field. func RedirectUrisNotNil() predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.NotNull(s.C(FieldRedirectUris))) - }) + return predicate.OAuth2Client(sql.FieldNotNull(FieldRedirectUris)) } // TrustedPeersIsNil applies the IsNil predicate on the "trusted_peers" field. func TrustedPeersIsNil() predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.IsNull(s.C(FieldTrustedPeers))) - }) + return predicate.OAuth2Client(sql.FieldIsNull(FieldTrustedPeers)) } // TrustedPeersNotNil applies the NotNil predicate on the "trusted_peers" field. func TrustedPeersNotNil() predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.NotNull(s.C(FieldTrustedPeers))) - }) + return predicate.OAuth2Client(sql.FieldNotNull(FieldTrustedPeers)) } // PublicEQ applies the EQ predicate on the "public" field. func PublicEQ(v bool) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldPublic), v)) - }) + return predicate.OAuth2Client(sql.FieldEQ(FieldPublic, v)) } // PublicNEQ applies the NEQ predicate on the "public" field. func PublicNEQ(v bool) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldPublic), v)) - }) + return predicate.OAuth2Client(sql.FieldNEQ(FieldPublic, v)) } // NameEQ applies the EQ predicate on the "name" field. func NameEQ(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldName), v)) - }) + return predicate.OAuth2Client(sql.FieldEQ(FieldName, v)) } // NameNEQ applies the NEQ predicate on the "name" field. func NameNEQ(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldName), v)) - }) + return predicate.OAuth2Client(sql.FieldNEQ(FieldName, v)) } // NameIn applies the In predicate on the "name" field. func NameIn(vs ...string) predicate.OAuth2Client { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldName), v...)) - }) + return predicate.OAuth2Client(sql.FieldIn(FieldName, vs...)) } // NameNotIn applies the NotIn predicate on the "name" field. func NameNotIn(vs ...string) predicate.OAuth2Client { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldName), v...)) - }) + return predicate.OAuth2Client(sql.FieldNotIn(FieldName, vs...)) } // NameGT applies the GT predicate on the "name" field. func NameGT(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldName), v)) - }) + return predicate.OAuth2Client(sql.FieldGT(FieldName, v)) } // NameGTE applies the GTE predicate on the "name" field. func NameGTE(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldName), v)) - }) + return predicate.OAuth2Client(sql.FieldGTE(FieldName, v)) } // NameLT applies the LT predicate on the "name" field. func NameLT(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldName), v)) - }) + return predicate.OAuth2Client(sql.FieldLT(FieldName, v)) } // NameLTE applies the LTE predicate on the "name" field. func NameLTE(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldName), v)) - }) + return predicate.OAuth2Client(sql.FieldLTE(FieldName, v)) } // NameContains applies the Contains predicate on the "name" field. func NameContains(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldName), v)) - }) + return predicate.OAuth2Client(sql.FieldContains(FieldName, v)) } // NameHasPrefix applies the HasPrefix predicate on the "name" field. func NameHasPrefix(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldName), v)) - }) + return predicate.OAuth2Client(sql.FieldHasPrefix(FieldName, v)) } // NameHasSuffix applies the HasSuffix predicate on the "name" field. func NameHasSuffix(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldName), v)) - }) + return predicate.OAuth2Client(sql.FieldHasSuffix(FieldName, v)) } // NameEqualFold applies the EqualFold predicate on the "name" field. func NameEqualFold(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldName), v)) - }) + return predicate.OAuth2Client(sql.FieldEqualFold(FieldName, v)) } // NameContainsFold applies the ContainsFold predicate on the "name" field. func NameContainsFold(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldName), v)) - }) + return predicate.OAuth2Client(sql.FieldContainsFold(FieldName, v)) } // LogoURLEQ applies the EQ predicate on the "logo_url" field. func LogoURLEQ(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldLogoURL), v)) - }) + return predicate.OAuth2Client(sql.FieldEQ(FieldLogoURL, v)) } // LogoURLNEQ applies the NEQ predicate on the "logo_url" field. func LogoURLNEQ(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldLogoURL), v)) - }) + return predicate.OAuth2Client(sql.FieldNEQ(FieldLogoURL, v)) } // LogoURLIn applies the In predicate on the "logo_url" field. func LogoURLIn(vs ...string) predicate.OAuth2Client { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldLogoURL), v...)) - }) + return predicate.OAuth2Client(sql.FieldIn(FieldLogoURL, vs...)) } // LogoURLNotIn applies the NotIn predicate on the "logo_url" field. func LogoURLNotIn(vs ...string) predicate.OAuth2Client { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldLogoURL), v...)) - }) + return predicate.OAuth2Client(sql.FieldNotIn(FieldLogoURL, vs...)) } // LogoURLGT applies the GT predicate on the "logo_url" field. func LogoURLGT(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldLogoURL), v)) - }) + return predicate.OAuth2Client(sql.FieldGT(FieldLogoURL, v)) } // LogoURLGTE applies the GTE predicate on the "logo_url" field. func LogoURLGTE(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldLogoURL), v)) - }) + return predicate.OAuth2Client(sql.FieldGTE(FieldLogoURL, v)) } // LogoURLLT applies the LT predicate on the "logo_url" field. func LogoURLLT(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldLogoURL), v)) - }) + return predicate.OAuth2Client(sql.FieldLT(FieldLogoURL, v)) } // LogoURLLTE applies the LTE predicate on the "logo_url" field. func LogoURLLTE(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldLogoURL), v)) - }) + return predicate.OAuth2Client(sql.FieldLTE(FieldLogoURL, v)) } // LogoURLContains applies the Contains predicate on the "logo_url" field. func LogoURLContains(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldLogoURL), v)) - }) + return predicate.OAuth2Client(sql.FieldContains(FieldLogoURL, v)) } // LogoURLHasPrefix applies the HasPrefix predicate on the "logo_url" field. func LogoURLHasPrefix(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldLogoURL), v)) - }) + return predicate.OAuth2Client(sql.FieldHasPrefix(FieldLogoURL, v)) } // LogoURLHasSuffix applies the HasSuffix predicate on the "logo_url" field. func LogoURLHasSuffix(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldLogoURL), v)) - }) + return predicate.OAuth2Client(sql.FieldHasSuffix(FieldLogoURL, v)) } // LogoURLEqualFold applies the EqualFold predicate on the "logo_url" field. func LogoURLEqualFold(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldLogoURL), v)) - }) + return predicate.OAuth2Client(sql.FieldEqualFold(FieldLogoURL, v)) } // LogoURLContainsFold applies the ContainsFold predicate on the "logo_url" field. func LogoURLContainsFold(v string) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldLogoURL), v)) - }) + return predicate.OAuth2Client(sql.FieldContainsFold(FieldLogoURL, v)) } // And groups predicates with the AND operator between them. func And(predicates ...predicate.OAuth2Client) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for _, p := range predicates { - p(s1) - } - s.Where(s1.P()) - }) + return predicate.OAuth2Client(sql.AndPredicates(predicates...)) } // Or groups predicates with the OR operator between them. func Or(predicates ...predicate.OAuth2Client) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for i, p := range predicates { - if i > 0 { - s1.Or() - } - p(s1) - } - s.Where(s1.P()) - }) + return predicate.OAuth2Client(sql.OrPredicates(predicates...)) } // Not applies the not operator on the given predicate. func Not(p predicate.OAuth2Client) predicate.OAuth2Client { - return predicate.OAuth2Client(func(s *sql.Selector) { - p(s.Not()) - }) + return predicate.OAuth2Client(sql.NotPredicates(p)) } diff --git a/storage/ent/db/oauth2client_create.go b/storage/ent/db/oauth2client_create.go index 02c41a8377..2bbf1f5033 100644 --- a/storage/ent/db/oauth2client_create.go +++ b/storage/ent/db/oauth2client_create.go @@ -20,102 +20,60 @@ type OAuth2ClientCreate struct { } // SetSecret sets the "secret" field. -func (oc *OAuth2ClientCreate) SetSecret(s string) *OAuth2ClientCreate { - oc.mutation.SetSecret(s) - return oc +func (_c *OAuth2ClientCreate) SetSecret(v string) *OAuth2ClientCreate { + _c.mutation.SetSecret(v) + return _c } // SetRedirectUris sets the "redirect_uris" field. -func (oc *OAuth2ClientCreate) SetRedirectUris(s []string) *OAuth2ClientCreate { - oc.mutation.SetRedirectUris(s) - return oc +func (_c *OAuth2ClientCreate) SetRedirectUris(v []string) *OAuth2ClientCreate { + _c.mutation.SetRedirectUris(v) + return _c } // SetTrustedPeers sets the "trusted_peers" field. -func (oc *OAuth2ClientCreate) SetTrustedPeers(s []string) *OAuth2ClientCreate { - oc.mutation.SetTrustedPeers(s) - return oc +func (_c *OAuth2ClientCreate) SetTrustedPeers(v []string) *OAuth2ClientCreate { + _c.mutation.SetTrustedPeers(v) + return _c } // SetPublic sets the "public" field. -func (oc *OAuth2ClientCreate) SetPublic(b bool) *OAuth2ClientCreate { - oc.mutation.SetPublic(b) - return oc +func (_c *OAuth2ClientCreate) SetPublic(v bool) *OAuth2ClientCreate { + _c.mutation.SetPublic(v) + return _c } // SetName sets the "name" field. -func (oc *OAuth2ClientCreate) SetName(s string) *OAuth2ClientCreate { - oc.mutation.SetName(s) - return oc +func (_c *OAuth2ClientCreate) SetName(v string) *OAuth2ClientCreate { + _c.mutation.SetName(v) + return _c } // SetLogoURL sets the "logo_url" field. -func (oc *OAuth2ClientCreate) SetLogoURL(s string) *OAuth2ClientCreate { - oc.mutation.SetLogoURL(s) - return oc +func (_c *OAuth2ClientCreate) SetLogoURL(v string) *OAuth2ClientCreate { + _c.mutation.SetLogoURL(v) + return _c } // SetID sets the "id" field. -func (oc *OAuth2ClientCreate) SetID(s string) *OAuth2ClientCreate { - oc.mutation.SetID(s) - return oc +func (_c *OAuth2ClientCreate) SetID(v string) *OAuth2ClientCreate { + _c.mutation.SetID(v) + return _c } // Mutation returns the OAuth2ClientMutation object of the builder. -func (oc *OAuth2ClientCreate) Mutation() *OAuth2ClientMutation { - return oc.mutation +func (_c *OAuth2ClientCreate) Mutation() *OAuth2ClientMutation { + return _c.mutation } // Save creates the OAuth2Client in the database. -func (oc *OAuth2ClientCreate) Save(ctx context.Context) (*OAuth2Client, error) { - var ( - err error - node *OAuth2Client - ) - if len(oc.hooks) == 0 { - if err = oc.check(); err != nil { - return nil, err - } - node, err = oc.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*OAuth2ClientMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = oc.check(); err != nil { - return nil, err - } - oc.mutation = mutation - if node, err = oc.sqlSave(ctx); err != nil { - return nil, err - } - mutation.id = &node.ID - mutation.done = true - return node, err - }) - for i := len(oc.hooks) - 1; i >= 0; i-- { - if oc.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = oc.hooks[i](mut) - } - v, err := mut.Mutate(ctx, oc.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*OAuth2Client) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from OAuth2ClientMutation", v) - } - node = nv - } - return node, err +func (_c *OAuth2ClientCreate) Save(ctx context.Context) (*OAuth2Client, error) { + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) } // SaveX calls Save and panics if Save returns an error. -func (oc *OAuth2ClientCreate) SaveX(ctx context.Context) *OAuth2Client { - v, err := oc.Save(ctx) +func (_c *OAuth2ClientCreate) SaveX(ctx context.Context) *OAuth2Client { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -123,48 +81,48 @@ func (oc *OAuth2ClientCreate) SaveX(ctx context.Context) *OAuth2Client { } // Exec executes the query. -func (oc *OAuth2ClientCreate) Exec(ctx context.Context) error { - _, err := oc.Save(ctx) +func (_c *OAuth2ClientCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (oc *OAuth2ClientCreate) ExecX(ctx context.Context) { - if err := oc.Exec(ctx); err != nil { +func (_c *OAuth2ClientCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (oc *OAuth2ClientCreate) check() error { - if _, ok := oc.mutation.Secret(); !ok { +func (_c *OAuth2ClientCreate) check() error { + if _, ok := _c.mutation.Secret(); !ok { return &ValidationError{Name: "secret", err: errors.New(`db: missing required field "OAuth2Client.secret"`)} } - if v, ok := oc.mutation.Secret(); ok { + if v, ok := _c.mutation.Secret(); ok { if err := oauth2client.SecretValidator(v); err != nil { return &ValidationError{Name: "secret", err: fmt.Errorf(`db: validator failed for field "OAuth2Client.secret": %w`, err)} } } - if _, ok := oc.mutation.Public(); !ok { + if _, ok := _c.mutation.Public(); !ok { return &ValidationError{Name: "public", err: errors.New(`db: missing required field "OAuth2Client.public"`)} } - if _, ok := oc.mutation.Name(); !ok { + if _, ok := _c.mutation.Name(); !ok { return &ValidationError{Name: "name", err: errors.New(`db: missing required field "OAuth2Client.name"`)} } - if v, ok := oc.mutation.Name(); ok { + if v, ok := _c.mutation.Name(); ok { if err := oauth2client.NameValidator(v); err != nil { return &ValidationError{Name: "name", err: fmt.Errorf(`db: validator failed for field "OAuth2Client.name": %w`, err)} } } - if _, ok := oc.mutation.LogoURL(); !ok { + if _, ok := _c.mutation.LogoURL(); !ok { return &ValidationError{Name: "logo_url", err: errors.New(`db: missing required field "OAuth2Client.logo_url"`)} } - if v, ok := oc.mutation.LogoURL(); ok { + if v, ok := _c.mutation.LogoURL(); ok { if err := oauth2client.LogoURLValidator(v); err != nil { return &ValidationError{Name: "logo_url", err: fmt.Errorf(`db: validator failed for field "OAuth2Client.logo_url": %w`, err)} } } - if v, ok := oc.mutation.ID(); ok { + if v, ok := _c.mutation.ID(); ok { if err := oauth2client.IDValidator(v); err != nil { return &ValidationError{Name: "id", err: fmt.Errorf(`db: validator failed for field "OAuth2Client.id": %w`, err)} } @@ -172,9 +130,12 @@ func (oc *OAuth2ClientCreate) check() error { return nil } -func (oc *OAuth2ClientCreate) sqlSave(ctx context.Context) (*OAuth2Client, error) { - _node, _spec := oc.createSpec() - if err := sqlgraph.CreateNode(ctx, oc.driver, _spec); err != nil { +func (_c *OAuth2ClientCreate) sqlSave(ctx context.Context) (*OAuth2Client, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -187,70 +148,42 @@ func (oc *OAuth2ClientCreate) sqlSave(ctx context.Context) (*OAuth2Client, error return nil, fmt.Errorf("unexpected OAuth2Client.ID type: %T", _spec.ID.Value) } } + _c.mutation.id = &_node.ID + _c.mutation.done = true return _node, nil } -func (oc *OAuth2ClientCreate) createSpec() (*OAuth2Client, *sqlgraph.CreateSpec) { +func (_c *OAuth2ClientCreate) createSpec() (*OAuth2Client, *sqlgraph.CreateSpec) { var ( - _node = &OAuth2Client{config: oc.config} - _spec = &sqlgraph.CreateSpec{ - Table: oauth2client.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: oauth2client.FieldID, - }, - } + _node = &OAuth2Client{config: _c.config} + _spec = sqlgraph.NewCreateSpec(oauth2client.Table, sqlgraph.NewFieldSpec(oauth2client.FieldID, field.TypeString)) ) - if id, ok := oc.mutation.ID(); ok { + if id, ok := _c.mutation.ID(); ok { _node.ID = id _spec.ID.Value = id } - if value, ok := oc.mutation.Secret(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: oauth2client.FieldSecret, - }) + if value, ok := _c.mutation.Secret(); ok { + _spec.SetField(oauth2client.FieldSecret, field.TypeString, value) _node.Secret = value } - if value, ok := oc.mutation.RedirectUris(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: oauth2client.FieldRedirectUris, - }) + if value, ok := _c.mutation.RedirectUris(); ok { + _spec.SetField(oauth2client.FieldRedirectUris, field.TypeJSON, value) _node.RedirectUris = value } - if value, ok := oc.mutation.TrustedPeers(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: oauth2client.FieldTrustedPeers, - }) + if value, ok := _c.mutation.TrustedPeers(); ok { + _spec.SetField(oauth2client.FieldTrustedPeers, field.TypeJSON, value) _node.TrustedPeers = value } - if value, ok := oc.mutation.Public(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeBool, - Value: value, - Column: oauth2client.FieldPublic, - }) + if value, ok := _c.mutation.Public(); ok { + _spec.SetField(oauth2client.FieldPublic, field.TypeBool, value) _node.Public = value } - if value, ok := oc.mutation.Name(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: oauth2client.FieldName, - }) + if value, ok := _c.mutation.Name(); ok { + _spec.SetField(oauth2client.FieldName, field.TypeString, value) _node.Name = value } - if value, ok := oc.mutation.LogoURL(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: oauth2client.FieldLogoURL, - }) + if value, ok := _c.mutation.LogoURL(); ok { + _spec.SetField(oauth2client.FieldLogoURL, field.TypeString, value) _node.LogoURL = value } return _node, _spec @@ -259,17 +192,21 @@ func (oc *OAuth2ClientCreate) createSpec() (*OAuth2Client, *sqlgraph.CreateSpec) // OAuth2ClientCreateBulk is the builder for creating many OAuth2Client entities in bulk. type OAuth2ClientCreateBulk struct { config + err error builders []*OAuth2ClientCreate } // Save creates the OAuth2Client entities in the database. -func (ocb *OAuth2ClientCreateBulk) Save(ctx context.Context) ([]*OAuth2Client, error) { - specs := make([]*sqlgraph.CreateSpec, len(ocb.builders)) - nodes := make([]*OAuth2Client, len(ocb.builders)) - mutators := make([]Mutator, len(ocb.builders)) - for i := range ocb.builders { +func (_c *OAuth2ClientCreateBulk) Save(ctx context.Context) ([]*OAuth2Client, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*OAuth2Client, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { func(i int, root context.Context) { - builder := ocb.builders[i] + builder := _c.builders[i] var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { mutation, ok := m.(*OAuth2ClientMutation) if !ok { @@ -279,14 +216,14 @@ func (ocb *OAuth2ClientCreateBulk) Save(ctx context.Context) ([]*OAuth2Client, e return nil, err } builder.mutation = mutation - nodes[i], specs[i] = builder.createSpec() var err error + nodes[i], specs[i] = builder.createSpec() if i < len(mutators)-1 { - _, err = mutators[i+1].Mutate(root, ocb.builders[i+1].mutation) + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} // Invoke the actual operation on the latest mutation in the chain. - if err = sqlgraph.BatchCreate(ctx, ocb.driver, spec); err != nil { + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -306,7 +243,7 @@ func (ocb *OAuth2ClientCreateBulk) Save(ctx context.Context) ([]*OAuth2Client, e }(i, ctx) } if len(mutators) > 0 { - if _, err := mutators[0].Mutate(ctx, ocb.builders[0].mutation); err != nil { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { return nil, err } } @@ -314,8 +251,8 @@ func (ocb *OAuth2ClientCreateBulk) Save(ctx context.Context) ([]*OAuth2Client, e } // SaveX is like Save, but panics if an error occurs. -func (ocb *OAuth2ClientCreateBulk) SaveX(ctx context.Context) []*OAuth2Client { - v, err := ocb.Save(ctx) +func (_c *OAuth2ClientCreateBulk) SaveX(ctx context.Context) []*OAuth2Client { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -323,14 +260,14 @@ func (ocb *OAuth2ClientCreateBulk) SaveX(ctx context.Context) []*OAuth2Client { } // Exec executes the query. -func (ocb *OAuth2ClientCreateBulk) Exec(ctx context.Context) error { - _, err := ocb.Save(ctx) +func (_c *OAuth2ClientCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (ocb *OAuth2ClientCreateBulk) ExecX(ctx context.Context) { - if err := ocb.Exec(ctx); err != nil { +func (_c *OAuth2ClientCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } diff --git a/storage/ent/db/oauth2client_delete.go b/storage/ent/db/oauth2client_delete.go index 239d904dc2..d8c340aedc 100644 --- a/storage/ent/db/oauth2client_delete.go +++ b/storage/ent/db/oauth2client_delete.go @@ -4,7 +4,6 @@ package db import ( "context" - "fmt" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" @@ -21,84 +20,56 @@ type OAuth2ClientDelete struct { } // Where appends a list predicates to the OAuth2ClientDelete builder. -func (od *OAuth2ClientDelete) Where(ps ...predicate.OAuth2Client) *OAuth2ClientDelete { - od.mutation.Where(ps...) - return od +func (_d *OAuth2ClientDelete) Where(ps ...predicate.OAuth2Client) *OAuth2ClientDelete { + _d.mutation.Where(ps...) + return _d } // Exec executes the deletion query and returns how many vertices were deleted. -func (od *OAuth2ClientDelete) Exec(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(od.hooks) == 0 { - affected, err = od.sqlExec(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*OAuth2ClientMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - od.mutation = mutation - affected, err = od.sqlExec(ctx) - mutation.done = true - return affected, err - }) - for i := len(od.hooks) - 1; i >= 0; i-- { - if od.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = od.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, od.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_d *OAuth2ClientDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) } // ExecX is like Exec, but panics if an error occurs. -func (od *OAuth2ClientDelete) ExecX(ctx context.Context) int { - n, err := od.Exec(ctx) +func (_d *OAuth2ClientDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) if err != nil { panic(err) } return n } -func (od *OAuth2ClientDelete) sqlExec(ctx context.Context) (int, error) { - _spec := &sqlgraph.DeleteSpec{ - Node: &sqlgraph.NodeSpec{ - Table: oauth2client.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: oauth2client.FieldID, - }, - }, - } - if ps := od.mutation.predicates; len(ps) > 0 { +func (_d *OAuth2ClientDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(oauth2client.Table, sqlgraph.NewFieldSpec(oauth2client.FieldID, field.TypeString)) + if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - affected, err := sqlgraph.DeleteNodes(ctx, od.driver, _spec) + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) if err != nil && sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } + _d.mutation.done = true return affected, err } // OAuth2ClientDeleteOne is the builder for deleting a single OAuth2Client entity. type OAuth2ClientDeleteOne struct { - od *OAuth2ClientDelete + _d *OAuth2ClientDelete +} + +// Where appends a list predicates to the OAuth2ClientDelete builder. +func (_d *OAuth2ClientDeleteOne) Where(ps ...predicate.OAuth2Client) *OAuth2ClientDeleteOne { + _d._d.mutation.Where(ps...) + return _d } // Exec executes the deletion query. -func (odo *OAuth2ClientDeleteOne) Exec(ctx context.Context) error { - n, err := odo.od.Exec(ctx) +func (_d *OAuth2ClientDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) switch { case err != nil: return err @@ -110,6 +81,8 @@ func (odo *OAuth2ClientDeleteOne) Exec(ctx context.Context) error { } // ExecX is like Exec, but panics if an error occurs. -func (odo *OAuth2ClientDeleteOne) ExecX(ctx context.Context) { - odo.od.ExecX(ctx) +func (_d *OAuth2ClientDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } } diff --git a/storage/ent/db/oauth2client_query.go b/storage/ent/db/oauth2client_query.go index 1776c943d2..21e2b114dd 100644 --- a/storage/ent/db/oauth2client_query.go +++ b/storage/ent/db/oauth2client_query.go @@ -7,6 +7,7 @@ import ( "fmt" "math" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" @@ -17,11 +18,9 @@ import ( // OAuth2ClientQuery is the builder for querying OAuth2Client entities. type OAuth2ClientQuery struct { config - limit *int - offset *int - unique *bool - order []OrderFunc - fields []string + ctx *QueryContext + order []oauth2client.OrderOption + inters []Interceptor predicates []predicate.OAuth2Client // intermediate query (i.e. traversal path). sql *sql.Selector @@ -29,40 +28,40 @@ type OAuth2ClientQuery struct { } // Where adds a new predicate for the OAuth2ClientQuery builder. -func (oq *OAuth2ClientQuery) Where(ps ...predicate.OAuth2Client) *OAuth2ClientQuery { - oq.predicates = append(oq.predicates, ps...) - return oq +func (_q *OAuth2ClientQuery) Where(ps ...predicate.OAuth2Client) *OAuth2ClientQuery { + _q.predicates = append(_q.predicates, ps...) + return _q } -// Limit adds a limit step to the query. -func (oq *OAuth2ClientQuery) Limit(limit int) *OAuth2ClientQuery { - oq.limit = &limit - return oq +// Limit the number of records to be returned by this query. +func (_q *OAuth2ClientQuery) Limit(limit int) *OAuth2ClientQuery { + _q.ctx.Limit = &limit + return _q } -// Offset adds an offset step to the query. -func (oq *OAuth2ClientQuery) Offset(offset int) *OAuth2ClientQuery { - oq.offset = &offset - return oq +// Offset to start from. +func (_q *OAuth2ClientQuery) Offset(offset int) *OAuth2ClientQuery { + _q.ctx.Offset = &offset + return _q } // Unique configures the query builder to filter duplicate records on query. // By default, unique is set to true, and can be disabled using this method. -func (oq *OAuth2ClientQuery) Unique(unique bool) *OAuth2ClientQuery { - oq.unique = &unique - return oq +func (_q *OAuth2ClientQuery) Unique(unique bool) *OAuth2ClientQuery { + _q.ctx.Unique = &unique + return _q } -// Order adds an order step to the query. -func (oq *OAuth2ClientQuery) Order(o ...OrderFunc) *OAuth2ClientQuery { - oq.order = append(oq.order, o...) - return oq +// Order specifies how the records should be ordered. +func (_q *OAuth2ClientQuery) Order(o ...oauth2client.OrderOption) *OAuth2ClientQuery { + _q.order = append(_q.order, o...) + return _q } // First returns the first OAuth2Client entity from the query. // Returns a *NotFoundError when no OAuth2Client was found. -func (oq *OAuth2ClientQuery) First(ctx context.Context) (*OAuth2Client, error) { - nodes, err := oq.Limit(1).All(ctx) +func (_q *OAuth2ClientQuery) First(ctx context.Context) (*OAuth2Client, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) if err != nil { return nil, err } @@ -73,8 +72,8 @@ func (oq *OAuth2ClientQuery) First(ctx context.Context) (*OAuth2Client, error) { } // FirstX is like First, but panics if an error occurs. -func (oq *OAuth2ClientQuery) FirstX(ctx context.Context) *OAuth2Client { - node, err := oq.First(ctx) +func (_q *OAuth2ClientQuery) FirstX(ctx context.Context) *OAuth2Client { + node, err := _q.First(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -83,9 +82,9 @@ func (oq *OAuth2ClientQuery) FirstX(ctx context.Context) *OAuth2Client { // FirstID returns the first OAuth2Client ID from the query. // Returns a *NotFoundError when no OAuth2Client ID was found. -func (oq *OAuth2ClientQuery) FirstID(ctx context.Context) (id string, err error) { +func (_q *OAuth2ClientQuery) FirstID(ctx context.Context) (id string, err error) { var ids []string - if ids, err = oq.Limit(1).IDs(ctx); err != nil { + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { return } if len(ids) == 0 { @@ -96,8 +95,8 @@ func (oq *OAuth2ClientQuery) FirstID(ctx context.Context) (id string, err error) } // FirstIDX is like FirstID, but panics if an error occurs. -func (oq *OAuth2ClientQuery) FirstIDX(ctx context.Context) string { - id, err := oq.FirstID(ctx) +func (_q *OAuth2ClientQuery) FirstIDX(ctx context.Context) string { + id, err := _q.FirstID(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -107,8 +106,8 @@ func (oq *OAuth2ClientQuery) FirstIDX(ctx context.Context) string { // Only returns a single OAuth2Client entity found by the query, ensuring it only returns one. // Returns a *NotSingularError when more than one OAuth2Client entity is found. // Returns a *NotFoundError when no OAuth2Client entities are found. -func (oq *OAuth2ClientQuery) Only(ctx context.Context) (*OAuth2Client, error) { - nodes, err := oq.Limit(2).All(ctx) +func (_q *OAuth2ClientQuery) Only(ctx context.Context) (*OAuth2Client, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) if err != nil { return nil, err } @@ -123,8 +122,8 @@ func (oq *OAuth2ClientQuery) Only(ctx context.Context) (*OAuth2Client, error) { } // OnlyX is like Only, but panics if an error occurs. -func (oq *OAuth2ClientQuery) OnlyX(ctx context.Context) *OAuth2Client { - node, err := oq.Only(ctx) +func (_q *OAuth2ClientQuery) OnlyX(ctx context.Context) *OAuth2Client { + node, err := _q.Only(ctx) if err != nil { panic(err) } @@ -134,9 +133,9 @@ func (oq *OAuth2ClientQuery) OnlyX(ctx context.Context) *OAuth2Client { // OnlyID is like Only, but returns the only OAuth2Client ID in the query. // Returns a *NotSingularError when more than one OAuth2Client ID is found. // Returns a *NotFoundError when no entities are found. -func (oq *OAuth2ClientQuery) OnlyID(ctx context.Context) (id string, err error) { +func (_q *OAuth2ClientQuery) OnlyID(ctx context.Context) (id string, err error) { var ids []string - if ids, err = oq.Limit(2).IDs(ctx); err != nil { + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { return } switch len(ids) { @@ -151,8 +150,8 @@ func (oq *OAuth2ClientQuery) OnlyID(ctx context.Context) (id string, err error) } // OnlyIDX is like OnlyID, but panics if an error occurs. -func (oq *OAuth2ClientQuery) OnlyIDX(ctx context.Context) string { - id, err := oq.OnlyID(ctx) +func (_q *OAuth2ClientQuery) OnlyIDX(ctx context.Context) string { + id, err := _q.OnlyID(ctx) if err != nil { panic(err) } @@ -160,16 +159,18 @@ func (oq *OAuth2ClientQuery) OnlyIDX(ctx context.Context) string { } // All executes the query and returns a list of OAuth2Clients. -func (oq *OAuth2ClientQuery) All(ctx context.Context) ([]*OAuth2Client, error) { - if err := oq.prepareQuery(ctx); err != nil { +func (_q *OAuth2ClientQuery) All(ctx context.Context) ([]*OAuth2Client, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { return nil, err } - return oq.sqlAll(ctx) + qr := querierAll[[]*OAuth2Client, *OAuth2ClientQuery]() + return withInterceptors[[]*OAuth2Client](ctx, _q, qr, _q.inters) } // AllX is like All, but panics if an error occurs. -func (oq *OAuth2ClientQuery) AllX(ctx context.Context) []*OAuth2Client { - nodes, err := oq.All(ctx) +func (_q *OAuth2ClientQuery) AllX(ctx context.Context) []*OAuth2Client { + nodes, err := _q.All(ctx) if err != nil { panic(err) } @@ -177,17 +178,20 @@ func (oq *OAuth2ClientQuery) AllX(ctx context.Context) []*OAuth2Client { } // IDs executes the query and returns a list of OAuth2Client IDs. -func (oq *OAuth2ClientQuery) IDs(ctx context.Context) ([]string, error) { - var ids []string - if err := oq.Select(oauth2client.FieldID).Scan(ctx, &ids); err != nil { +func (_q *OAuth2ClientQuery) IDs(ctx context.Context) (ids []string, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(oauth2client.FieldID).Scan(ctx, &ids); err != nil { return nil, err } return ids, nil } // IDsX is like IDs, but panics if an error occurs. -func (oq *OAuth2ClientQuery) IDsX(ctx context.Context) []string { - ids, err := oq.IDs(ctx) +func (_q *OAuth2ClientQuery) IDsX(ctx context.Context) []string { + ids, err := _q.IDs(ctx) if err != nil { panic(err) } @@ -195,16 +199,17 @@ func (oq *OAuth2ClientQuery) IDsX(ctx context.Context) []string { } // Count returns the count of the given query. -func (oq *OAuth2ClientQuery) Count(ctx context.Context) (int, error) { - if err := oq.prepareQuery(ctx); err != nil { +func (_q *OAuth2ClientQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { return 0, err } - return oq.sqlCount(ctx) + return withInterceptors[int](ctx, _q, querierCount[*OAuth2ClientQuery](), _q.inters) } // CountX is like Count, but panics if an error occurs. -func (oq *OAuth2ClientQuery) CountX(ctx context.Context) int { - count, err := oq.Count(ctx) +func (_q *OAuth2ClientQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) if err != nil { panic(err) } @@ -212,16 +217,21 @@ func (oq *OAuth2ClientQuery) CountX(ctx context.Context) int { } // Exist returns true if the query has elements in the graph. -func (oq *OAuth2ClientQuery) Exist(ctx context.Context) (bool, error) { - if err := oq.prepareQuery(ctx); err != nil { - return false, err +func (_q *OAuth2ClientQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("db: check existence: %w", err) + default: + return true, nil } - return oq.sqlExist(ctx) } // ExistX is like Exist, but panics if an error occurs. -func (oq *OAuth2ClientQuery) ExistX(ctx context.Context) bool { - exist, err := oq.Exist(ctx) +func (_q *OAuth2ClientQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) if err != nil { panic(err) } @@ -230,20 +240,19 @@ func (oq *OAuth2ClientQuery) ExistX(ctx context.Context) bool { // Clone returns a duplicate of the OAuth2ClientQuery builder, including all associated steps. It can be // used to prepare common query builders and use them differently after the clone is made. -func (oq *OAuth2ClientQuery) Clone() *OAuth2ClientQuery { - if oq == nil { +func (_q *OAuth2ClientQuery) Clone() *OAuth2ClientQuery { + if _q == nil { return nil } return &OAuth2ClientQuery{ - config: oq.config, - limit: oq.limit, - offset: oq.offset, - order: append([]OrderFunc{}, oq.order...), - predicates: append([]predicate.OAuth2Client{}, oq.predicates...), + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]oauth2client.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.OAuth2Client{}, _q.predicates...), // clone intermediate query. - sql: oq.sql.Clone(), - path: oq.path, - unique: oq.unique, + sql: _q.sql.Clone(), + path: _q.path, } } @@ -261,18 +270,12 @@ func (oq *OAuth2ClientQuery) Clone() *OAuth2ClientQuery { // GroupBy(oauth2client.FieldSecret). // Aggregate(db.Count()). // Scan(ctx, &v) -// -func (oq *OAuth2ClientQuery) GroupBy(field string, fields ...string) *OAuth2ClientGroupBy { - grbuild := &OAuth2ClientGroupBy{config: oq.config} - grbuild.fields = append([]string{field}, fields...) - grbuild.path = func(ctx context.Context) (prev *sql.Selector, err error) { - if err := oq.prepareQuery(ctx); err != nil { - return nil, err - } - return oq.sqlQuery(ctx), nil - } +func (_q *OAuth2ClientQuery) GroupBy(field string, fields ...string) *OAuth2ClientGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &OAuth2ClientGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields grbuild.label = oauth2client.Label - grbuild.flds, grbuild.scan = &grbuild.fields, grbuild.Scan + grbuild.scan = grbuild.Scan return grbuild } @@ -288,48 +291,62 @@ func (oq *OAuth2ClientQuery) GroupBy(field string, fields ...string) *OAuth2Clie // client.OAuth2Client.Query(). // Select(oauth2client.FieldSecret). // Scan(ctx, &v) -// -func (oq *OAuth2ClientQuery) Select(fields ...string) *OAuth2ClientSelect { - oq.fields = append(oq.fields, fields...) - selbuild := &OAuth2ClientSelect{OAuth2ClientQuery: oq} - selbuild.label = oauth2client.Label - selbuild.flds, selbuild.scan = &oq.fields, selbuild.Scan - return selbuild +func (_q *OAuth2ClientQuery) Select(fields ...string) *OAuth2ClientSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &OAuth2ClientSelect{OAuth2ClientQuery: _q} + sbuild.label = oauth2client.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a OAuth2ClientSelect configured with the given aggregations. +func (_q *OAuth2ClientQuery) Aggregate(fns ...AggregateFunc) *OAuth2ClientSelect { + return _q.Select().Aggregate(fns...) } -func (oq *OAuth2ClientQuery) prepareQuery(ctx context.Context) error { - for _, f := range oq.fields { +func (_q *OAuth2ClientQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("db: uninitialized interceptor (forgotten import db/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { if !oauth2client.ValidColumn(f) { return &ValidationError{Name: f, err: fmt.Errorf("db: invalid field %q for query", f)} } } - if oq.path != nil { - prev, err := oq.path(ctx) + if _q.path != nil { + prev, err := _q.path(ctx) if err != nil { return err } - oq.sql = prev + _q.sql = prev } return nil } -func (oq *OAuth2ClientQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*OAuth2Client, error) { +func (_q *OAuth2ClientQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*OAuth2Client, error) { var ( nodes = []*OAuth2Client{} - _spec = oq.querySpec() + _spec = _q.querySpec() ) - _spec.ScanValues = func(columns []string) ([]interface{}, error) { + _spec.ScanValues = func(columns []string) ([]any, error) { return (*OAuth2Client).scanValues(nil, columns) } - _spec.Assign = func(columns []string, values []interface{}) error { - node := &OAuth2Client{config: oq.config} + _spec.Assign = func(columns []string, values []any) error { + node := &OAuth2Client{config: _q.config} nodes = append(nodes, node) return node.assignValues(columns, values) } for i := range hooks { hooks[i](ctx, _spec) } - if err := sqlgraph.QueryNodes(ctx, oq.driver, _spec); err != nil { + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { return nil, err } if len(nodes) == 0 { @@ -338,40 +355,24 @@ func (oq *OAuth2ClientQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([] return nodes, nil } -func (oq *OAuth2ClientQuery) sqlCount(ctx context.Context) (int, error) { - _spec := oq.querySpec() - _spec.Node.Columns = oq.fields - if len(oq.fields) > 0 { - _spec.Unique = oq.unique != nil && *oq.unique - } - return sqlgraph.CountNodes(ctx, oq.driver, _spec) -} - -func (oq *OAuth2ClientQuery) sqlExist(ctx context.Context) (bool, error) { - n, err := oq.sqlCount(ctx) - if err != nil { - return false, fmt.Errorf("db: check existence: %w", err) +func (_q *OAuth2ClientQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique } - return n > 0, nil + return sqlgraph.CountNodes(ctx, _q.driver, _spec) } -func (oq *OAuth2ClientQuery) querySpec() *sqlgraph.QuerySpec { - _spec := &sqlgraph.QuerySpec{ - Node: &sqlgraph.NodeSpec{ - Table: oauth2client.Table, - Columns: oauth2client.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: oauth2client.FieldID, - }, - }, - From: oq.sql, - Unique: true, - } - if unique := oq.unique; unique != nil { +func (_q *OAuth2ClientQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(oauth2client.Table, oauth2client.Columns, sqlgraph.NewFieldSpec(oauth2client.FieldID, field.TypeString)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true } - if fields := oq.fields; len(fields) > 0 { + if fields := _q.ctx.Fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, oauth2client.FieldID) for i := range fields { @@ -380,20 +381,20 @@ func (oq *OAuth2ClientQuery) querySpec() *sqlgraph.QuerySpec { } } } - if ps := oq.predicates; len(ps) > 0 { + if ps := _q.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if limit := oq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { _spec.Limit = *limit } - if offset := oq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { _spec.Offset = *offset } - if ps := oq.order; len(ps) > 0 { + if ps := _q.order; len(ps) > 0 { _spec.Order = func(selector *sql.Selector) { for i := range ps { ps[i](selector) @@ -403,33 +404,33 @@ func (oq *OAuth2ClientQuery) querySpec() *sqlgraph.QuerySpec { return _spec } -func (oq *OAuth2ClientQuery) sqlQuery(ctx context.Context) *sql.Selector { - builder := sql.Dialect(oq.driver.Dialect()) +func (_q *OAuth2ClientQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) t1 := builder.Table(oauth2client.Table) - columns := oq.fields + columns := _q.ctx.Fields if len(columns) == 0 { columns = oauth2client.Columns } selector := builder.Select(t1.Columns(columns...)...).From(t1) - if oq.sql != nil { - selector = oq.sql + if _q.sql != nil { + selector = _q.sql selector.Select(selector.Columns(columns...)...) } - if oq.unique != nil && *oq.unique { + if _q.ctx.Unique != nil && *_q.ctx.Unique { selector.Distinct() } - for _, p := range oq.predicates { + for _, p := range _q.predicates { p(selector) } - for _, p := range oq.order { + for _, p := range _q.order { p(selector) } - if offset := oq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { // limit is mandatory for offset clause. We start // with default value, and override it below if needed. selector.Offset(*offset).Limit(math.MaxInt32) } - if limit := oq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { selector.Limit(*limit) } return selector @@ -437,90 +438,88 @@ func (oq *OAuth2ClientQuery) sqlQuery(ctx context.Context) *sql.Selector { // OAuth2ClientGroupBy is the group-by builder for OAuth2Client entities. type OAuth2ClientGroupBy struct { - config selector - fields []string - fns []AggregateFunc - // intermediate query (i.e. traversal path). - sql *sql.Selector - path func(context.Context) (*sql.Selector, error) + build *OAuth2ClientQuery } // Aggregate adds the given aggregation functions to the group-by query. -func (ogb *OAuth2ClientGroupBy) Aggregate(fns ...AggregateFunc) *OAuth2ClientGroupBy { - ogb.fns = append(ogb.fns, fns...) - return ogb +func (_g *OAuth2ClientGroupBy) Aggregate(fns ...AggregateFunc) *OAuth2ClientGroupBy { + _g.fns = append(_g.fns, fns...) + return _g } -// Scan applies the group-by query and scans the result into the given value. -func (ogb *OAuth2ClientGroupBy) Scan(ctx context.Context, v interface{}) error { - query, err := ogb.path(ctx) - if err != nil { +// Scan applies the selector query and scans the result into the given value. +func (_g *OAuth2ClientGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { return err } - ogb.sql = query - return ogb.sqlScan(ctx, v) + return scanWithInterceptors[*OAuth2ClientQuery, *OAuth2ClientGroupBy](ctx, _g.build, _g, _g.build.inters, v) } -func (ogb *OAuth2ClientGroupBy) sqlScan(ctx context.Context, v interface{}) error { - for _, f := range ogb.fields { - if !oauth2client.ValidColumn(f) { - return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)} +func (_g *OAuth2ClientGroupBy) sqlScan(ctx context.Context, root *OAuth2ClientQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) } + columns = append(columns, aggregation...) + selector.Select(columns...) } - selector := ogb.sqlQuery() + selector.GroupBy(selector.Columns(*_g.flds...)...) if err := selector.Err(); err != nil { return err } rows := &sql.Rows{} query, args := selector.Query() - if err := ogb.driver.Query(ctx, query, args, rows); err != nil { + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() return sql.ScanSlice(rows, v) } -func (ogb *OAuth2ClientGroupBy) sqlQuery() *sql.Selector { - selector := ogb.sql.Select() - aggregation := make([]string, 0, len(ogb.fns)) - for _, fn := range ogb.fns { - aggregation = append(aggregation, fn(selector)) - } - // If no columns were selected in a custom aggregation function, the default - // selection is the fields used for "group-by", and the aggregation functions. - if len(selector.SelectedColumns()) == 0 { - columns := make([]string, 0, len(ogb.fields)+len(ogb.fns)) - for _, f := range ogb.fields { - columns = append(columns, selector.C(f)) - } - columns = append(columns, aggregation...) - selector.Select(columns...) - } - return selector.GroupBy(selector.Columns(ogb.fields...)...) -} - // OAuth2ClientSelect is the builder for selecting fields of OAuth2Client entities. type OAuth2ClientSelect struct { *OAuth2ClientQuery selector - // intermediate query (i.e. traversal path). - sql *sql.Selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *OAuth2ClientSelect) Aggregate(fns ...AggregateFunc) *OAuth2ClientSelect { + _s.fns = append(_s.fns, fns...) + return _s } // Scan applies the selector query and scans the result into the given value. -func (os *OAuth2ClientSelect) Scan(ctx context.Context, v interface{}) error { - if err := os.prepareQuery(ctx); err != nil { +func (_s *OAuth2ClientSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { return err } - os.sql = os.OAuth2ClientQuery.sqlQuery(ctx) - return os.sqlScan(ctx, v) + return scanWithInterceptors[*OAuth2ClientQuery, *OAuth2ClientSelect](ctx, _s.OAuth2ClientQuery, _s, _s.inters, v) } -func (os *OAuth2ClientSelect) sqlScan(ctx context.Context, v interface{}) error { +func (_s *OAuth2ClientSelect) sqlScan(ctx context.Context, root *OAuth2ClientQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } rows := &sql.Rows{} - query, args := os.sql.Query() - if err := os.driver.Query(ctx, query, args, rows); err != nil { + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() diff --git a/storage/ent/db/oauth2client_update.go b/storage/ent/db/oauth2client_update.go index aeddbba63c..69f2c0440e 100644 --- a/storage/ent/db/oauth2client_update.go +++ b/storage/ent/db/oauth2client_update.go @@ -9,6 +9,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/dialect/sql/sqljson" "entgo.io/ent/schema/field" "github.com/dexidp/dex/storage/ent/db/oauth2client" "github.com/dexidp/dex/storage/ent/db/predicate" @@ -22,105 +23,116 @@ type OAuth2ClientUpdate struct { } // Where appends a list predicates to the OAuth2ClientUpdate builder. -func (ou *OAuth2ClientUpdate) Where(ps ...predicate.OAuth2Client) *OAuth2ClientUpdate { - ou.mutation.Where(ps...) - return ou +func (_u *OAuth2ClientUpdate) Where(ps ...predicate.OAuth2Client) *OAuth2ClientUpdate { + _u.mutation.Where(ps...) + return _u } // SetSecret sets the "secret" field. -func (ou *OAuth2ClientUpdate) SetSecret(s string) *OAuth2ClientUpdate { - ou.mutation.SetSecret(s) - return ou +func (_u *OAuth2ClientUpdate) SetSecret(v string) *OAuth2ClientUpdate { + _u.mutation.SetSecret(v) + return _u +} + +// SetNillableSecret sets the "secret" field if the given value is not nil. +func (_u *OAuth2ClientUpdate) SetNillableSecret(v *string) *OAuth2ClientUpdate { + if v != nil { + _u.SetSecret(*v) + } + return _u } // SetRedirectUris sets the "redirect_uris" field. -func (ou *OAuth2ClientUpdate) SetRedirectUris(s []string) *OAuth2ClientUpdate { - ou.mutation.SetRedirectUris(s) - return ou +func (_u *OAuth2ClientUpdate) SetRedirectUris(v []string) *OAuth2ClientUpdate { + _u.mutation.SetRedirectUris(v) + return _u +} + +// AppendRedirectUris appends value to the "redirect_uris" field. +func (_u *OAuth2ClientUpdate) AppendRedirectUris(v []string) *OAuth2ClientUpdate { + _u.mutation.AppendRedirectUris(v) + return _u } // ClearRedirectUris clears the value of the "redirect_uris" field. -func (ou *OAuth2ClientUpdate) ClearRedirectUris() *OAuth2ClientUpdate { - ou.mutation.ClearRedirectUris() - return ou +func (_u *OAuth2ClientUpdate) ClearRedirectUris() *OAuth2ClientUpdate { + _u.mutation.ClearRedirectUris() + return _u } // SetTrustedPeers sets the "trusted_peers" field. -func (ou *OAuth2ClientUpdate) SetTrustedPeers(s []string) *OAuth2ClientUpdate { - ou.mutation.SetTrustedPeers(s) - return ou +func (_u *OAuth2ClientUpdate) SetTrustedPeers(v []string) *OAuth2ClientUpdate { + _u.mutation.SetTrustedPeers(v) + return _u +} + +// AppendTrustedPeers appends value to the "trusted_peers" field. +func (_u *OAuth2ClientUpdate) AppendTrustedPeers(v []string) *OAuth2ClientUpdate { + _u.mutation.AppendTrustedPeers(v) + return _u } // ClearTrustedPeers clears the value of the "trusted_peers" field. -func (ou *OAuth2ClientUpdate) ClearTrustedPeers() *OAuth2ClientUpdate { - ou.mutation.ClearTrustedPeers() - return ou +func (_u *OAuth2ClientUpdate) ClearTrustedPeers() *OAuth2ClientUpdate { + _u.mutation.ClearTrustedPeers() + return _u } // SetPublic sets the "public" field. -func (ou *OAuth2ClientUpdate) SetPublic(b bool) *OAuth2ClientUpdate { - ou.mutation.SetPublic(b) - return ou +func (_u *OAuth2ClientUpdate) SetPublic(v bool) *OAuth2ClientUpdate { + _u.mutation.SetPublic(v) + return _u +} + +// SetNillablePublic sets the "public" field if the given value is not nil. +func (_u *OAuth2ClientUpdate) SetNillablePublic(v *bool) *OAuth2ClientUpdate { + if v != nil { + _u.SetPublic(*v) + } + return _u } // SetName sets the "name" field. -func (ou *OAuth2ClientUpdate) SetName(s string) *OAuth2ClientUpdate { - ou.mutation.SetName(s) - return ou +func (_u *OAuth2ClientUpdate) SetName(v string) *OAuth2ClientUpdate { + _u.mutation.SetName(v) + return _u +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (_u *OAuth2ClientUpdate) SetNillableName(v *string) *OAuth2ClientUpdate { + if v != nil { + _u.SetName(*v) + } + return _u } // SetLogoURL sets the "logo_url" field. -func (ou *OAuth2ClientUpdate) SetLogoURL(s string) *OAuth2ClientUpdate { - ou.mutation.SetLogoURL(s) - return ou +func (_u *OAuth2ClientUpdate) SetLogoURL(v string) *OAuth2ClientUpdate { + _u.mutation.SetLogoURL(v) + return _u +} + +// SetNillableLogoURL sets the "logo_url" field if the given value is not nil. +func (_u *OAuth2ClientUpdate) SetNillableLogoURL(v *string) *OAuth2ClientUpdate { + if v != nil { + _u.SetLogoURL(*v) + } + return _u } // Mutation returns the OAuth2ClientMutation object of the builder. -func (ou *OAuth2ClientUpdate) Mutation() *OAuth2ClientMutation { - return ou.mutation +func (_u *OAuth2ClientUpdate) Mutation() *OAuth2ClientMutation { + return _u.mutation } // Save executes the query and returns the number of nodes affected by the update operation. -func (ou *OAuth2ClientUpdate) Save(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(ou.hooks) == 0 { - if err = ou.check(); err != nil { - return 0, err - } - affected, err = ou.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*OAuth2ClientMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = ou.check(); err != nil { - return 0, err - } - ou.mutation = mutation - affected, err = ou.sqlSave(ctx) - mutation.done = true - return affected, err - }) - for i := len(ou.hooks) - 1; i >= 0; i-- { - if ou.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = ou.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, ou.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_u *OAuth2ClientUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (ou *OAuth2ClientUpdate) SaveX(ctx context.Context) int { - affected, err := ou.Save(ctx) +func (_u *OAuth2ClientUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) if err != nil { panic(err) } @@ -128,31 +140,31 @@ func (ou *OAuth2ClientUpdate) SaveX(ctx context.Context) int { } // Exec executes the query. -func (ou *OAuth2ClientUpdate) Exec(ctx context.Context) error { - _, err := ou.Save(ctx) +func (_u *OAuth2ClientUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (ou *OAuth2ClientUpdate) ExecX(ctx context.Context) { - if err := ou.Exec(ctx); err != nil { +func (_u *OAuth2ClientUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (ou *OAuth2ClientUpdate) check() error { - if v, ok := ou.mutation.Secret(); ok { +func (_u *OAuth2ClientUpdate) check() error { + if v, ok := _u.mutation.Secret(); ok { if err := oauth2client.SecretValidator(v); err != nil { return &ValidationError{Name: "secret", err: fmt.Errorf(`db: validator failed for field "OAuth2Client.secret": %w`, err)} } } - if v, ok := ou.mutation.Name(); ok { + if v, ok := _u.mutation.Name(); ok { if err := oauth2client.NameValidator(v); err != nil { return &ValidationError{Name: "name", err: fmt.Errorf(`db: validator failed for field "OAuth2Client.name": %w`, err)} } } - if v, ok := ou.mutation.LogoURL(); ok { + if v, ok := _u.mutation.LogoURL(); ok { if err := oauth2client.LogoURLValidator(v); err != nil { return &ValidationError{Name: "logo_url", err: fmt.Errorf(`db: validator failed for field "OAuth2Client.logo_url": %w`, err)} } @@ -160,79 +172,53 @@ func (ou *OAuth2ClientUpdate) check() error { return nil } -func (ou *OAuth2ClientUpdate) sqlSave(ctx context.Context) (n int, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: oauth2client.Table, - Columns: oauth2client.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: oauth2client.FieldID, - }, - }, +func (_u *OAuth2ClientUpdate) sqlSave(ctx context.Context) (_node int, err error) { + if err := _u.check(); err != nil { + return _node, err } - if ps := ou.mutation.predicates; len(ps) > 0 { + _spec := sqlgraph.NewUpdateSpec(oauth2client.Table, oauth2client.Columns, sqlgraph.NewFieldSpec(oauth2client.FieldID, field.TypeString)) + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := ou.mutation.Secret(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: oauth2client.FieldSecret, - }) + if value, ok := _u.mutation.Secret(); ok { + _spec.SetField(oauth2client.FieldSecret, field.TypeString, value) } - if value, ok := ou.mutation.RedirectUris(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: oauth2client.FieldRedirectUris, - }) + if value, ok := _u.mutation.RedirectUris(); ok { + _spec.SetField(oauth2client.FieldRedirectUris, field.TypeJSON, value) } - if ou.mutation.RedirectUrisCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: oauth2client.FieldRedirectUris, + if value, ok := _u.mutation.AppendedRedirectUris(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, oauth2client.FieldRedirectUris, value) }) } - if value, ok := ou.mutation.TrustedPeers(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: oauth2client.FieldTrustedPeers, - }) + if _u.mutation.RedirectUrisCleared() { + _spec.ClearField(oauth2client.FieldRedirectUris, field.TypeJSON) } - if ou.mutation.TrustedPeersCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: oauth2client.FieldTrustedPeers, - }) + if value, ok := _u.mutation.TrustedPeers(); ok { + _spec.SetField(oauth2client.FieldTrustedPeers, field.TypeJSON, value) } - if value, ok := ou.mutation.Public(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBool, - Value: value, - Column: oauth2client.FieldPublic, + if value, ok := _u.mutation.AppendedTrustedPeers(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, oauth2client.FieldTrustedPeers, value) }) } - if value, ok := ou.mutation.Name(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: oauth2client.FieldName, - }) + if _u.mutation.TrustedPeersCleared() { + _spec.ClearField(oauth2client.FieldTrustedPeers, field.TypeJSON) } - if value, ok := ou.mutation.LogoURL(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: oauth2client.FieldLogoURL, - }) + if value, ok := _u.mutation.Public(); ok { + _spec.SetField(oauth2client.FieldPublic, field.TypeBool, value) + } + if value, ok := _u.mutation.Name(); ok { + _spec.SetField(oauth2client.FieldName, field.TypeString, value) } - if n, err = sqlgraph.UpdateNodes(ctx, ou.driver, _spec); err != nil { + if value, ok := _u.mutation.LogoURL(); ok { + _spec.SetField(oauth2client.FieldLogoURL, field.TypeString, value) + } + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{oauth2client.Label} } else if sqlgraph.IsConstraintError(err) { @@ -240,7 +226,8 @@ func (ou *OAuth2ClientUpdate) sqlSave(ctx context.Context) (n int, err error) { } return 0, err } - return n, nil + _u.mutation.done = true + return _node, nil } // OAuth2ClientUpdateOne is the builder for updating a single OAuth2Client entity. @@ -252,112 +239,123 @@ type OAuth2ClientUpdateOne struct { } // SetSecret sets the "secret" field. -func (ouo *OAuth2ClientUpdateOne) SetSecret(s string) *OAuth2ClientUpdateOne { - ouo.mutation.SetSecret(s) - return ouo +func (_u *OAuth2ClientUpdateOne) SetSecret(v string) *OAuth2ClientUpdateOne { + _u.mutation.SetSecret(v) + return _u +} + +// SetNillableSecret sets the "secret" field if the given value is not nil. +func (_u *OAuth2ClientUpdateOne) SetNillableSecret(v *string) *OAuth2ClientUpdateOne { + if v != nil { + _u.SetSecret(*v) + } + return _u } // SetRedirectUris sets the "redirect_uris" field. -func (ouo *OAuth2ClientUpdateOne) SetRedirectUris(s []string) *OAuth2ClientUpdateOne { - ouo.mutation.SetRedirectUris(s) - return ouo +func (_u *OAuth2ClientUpdateOne) SetRedirectUris(v []string) *OAuth2ClientUpdateOne { + _u.mutation.SetRedirectUris(v) + return _u +} + +// AppendRedirectUris appends value to the "redirect_uris" field. +func (_u *OAuth2ClientUpdateOne) AppendRedirectUris(v []string) *OAuth2ClientUpdateOne { + _u.mutation.AppendRedirectUris(v) + return _u } // ClearRedirectUris clears the value of the "redirect_uris" field. -func (ouo *OAuth2ClientUpdateOne) ClearRedirectUris() *OAuth2ClientUpdateOne { - ouo.mutation.ClearRedirectUris() - return ouo +func (_u *OAuth2ClientUpdateOne) ClearRedirectUris() *OAuth2ClientUpdateOne { + _u.mutation.ClearRedirectUris() + return _u } // SetTrustedPeers sets the "trusted_peers" field. -func (ouo *OAuth2ClientUpdateOne) SetTrustedPeers(s []string) *OAuth2ClientUpdateOne { - ouo.mutation.SetTrustedPeers(s) - return ouo +func (_u *OAuth2ClientUpdateOne) SetTrustedPeers(v []string) *OAuth2ClientUpdateOne { + _u.mutation.SetTrustedPeers(v) + return _u +} + +// AppendTrustedPeers appends value to the "trusted_peers" field. +func (_u *OAuth2ClientUpdateOne) AppendTrustedPeers(v []string) *OAuth2ClientUpdateOne { + _u.mutation.AppendTrustedPeers(v) + return _u } // ClearTrustedPeers clears the value of the "trusted_peers" field. -func (ouo *OAuth2ClientUpdateOne) ClearTrustedPeers() *OAuth2ClientUpdateOne { - ouo.mutation.ClearTrustedPeers() - return ouo +func (_u *OAuth2ClientUpdateOne) ClearTrustedPeers() *OAuth2ClientUpdateOne { + _u.mutation.ClearTrustedPeers() + return _u } // SetPublic sets the "public" field. -func (ouo *OAuth2ClientUpdateOne) SetPublic(b bool) *OAuth2ClientUpdateOne { - ouo.mutation.SetPublic(b) - return ouo +func (_u *OAuth2ClientUpdateOne) SetPublic(v bool) *OAuth2ClientUpdateOne { + _u.mutation.SetPublic(v) + return _u +} + +// SetNillablePublic sets the "public" field if the given value is not nil. +func (_u *OAuth2ClientUpdateOne) SetNillablePublic(v *bool) *OAuth2ClientUpdateOne { + if v != nil { + _u.SetPublic(*v) + } + return _u } // SetName sets the "name" field. -func (ouo *OAuth2ClientUpdateOne) SetName(s string) *OAuth2ClientUpdateOne { - ouo.mutation.SetName(s) - return ouo +func (_u *OAuth2ClientUpdateOne) SetName(v string) *OAuth2ClientUpdateOne { + _u.mutation.SetName(v) + return _u +} + +// SetNillableName sets the "name" field if the given value is not nil. +func (_u *OAuth2ClientUpdateOne) SetNillableName(v *string) *OAuth2ClientUpdateOne { + if v != nil { + _u.SetName(*v) + } + return _u } // SetLogoURL sets the "logo_url" field. -func (ouo *OAuth2ClientUpdateOne) SetLogoURL(s string) *OAuth2ClientUpdateOne { - ouo.mutation.SetLogoURL(s) - return ouo +func (_u *OAuth2ClientUpdateOne) SetLogoURL(v string) *OAuth2ClientUpdateOne { + _u.mutation.SetLogoURL(v) + return _u +} + +// SetNillableLogoURL sets the "logo_url" field if the given value is not nil. +func (_u *OAuth2ClientUpdateOne) SetNillableLogoURL(v *string) *OAuth2ClientUpdateOne { + if v != nil { + _u.SetLogoURL(*v) + } + return _u } // Mutation returns the OAuth2ClientMutation object of the builder. -func (ouo *OAuth2ClientUpdateOne) Mutation() *OAuth2ClientMutation { - return ouo.mutation +func (_u *OAuth2ClientUpdateOne) Mutation() *OAuth2ClientMutation { + return _u.mutation +} + +// Where appends a list predicates to the OAuth2ClientUpdate builder. +func (_u *OAuth2ClientUpdateOne) Where(ps ...predicate.OAuth2Client) *OAuth2ClientUpdateOne { + _u.mutation.Where(ps...) + return _u } // Select allows selecting one or more fields (columns) of the returned entity. // The default is selecting all fields defined in the entity schema. -func (ouo *OAuth2ClientUpdateOne) Select(field string, fields ...string) *OAuth2ClientUpdateOne { - ouo.fields = append([]string{field}, fields...) - return ouo +func (_u *OAuth2ClientUpdateOne) Select(field string, fields ...string) *OAuth2ClientUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u } // Save executes the query and returns the updated OAuth2Client entity. -func (ouo *OAuth2ClientUpdateOne) Save(ctx context.Context) (*OAuth2Client, error) { - var ( - err error - node *OAuth2Client - ) - if len(ouo.hooks) == 0 { - if err = ouo.check(); err != nil { - return nil, err - } - node, err = ouo.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*OAuth2ClientMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = ouo.check(); err != nil { - return nil, err - } - ouo.mutation = mutation - node, err = ouo.sqlSave(ctx) - mutation.done = true - return node, err - }) - for i := len(ouo.hooks) - 1; i >= 0; i-- { - if ouo.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = ouo.hooks[i](mut) - } - v, err := mut.Mutate(ctx, ouo.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*OAuth2Client) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from OAuth2ClientMutation", v) - } - node = nv - } - return node, err +func (_u *OAuth2ClientUpdateOne) Save(ctx context.Context) (*OAuth2Client, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (ouo *OAuth2ClientUpdateOne) SaveX(ctx context.Context) *OAuth2Client { - node, err := ouo.Save(ctx) +func (_u *OAuth2ClientUpdateOne) SaveX(ctx context.Context) *OAuth2Client { + node, err := _u.Save(ctx) if err != nil { panic(err) } @@ -365,31 +363,31 @@ func (ouo *OAuth2ClientUpdateOne) SaveX(ctx context.Context) *OAuth2Client { } // Exec executes the query on the entity. -func (ouo *OAuth2ClientUpdateOne) Exec(ctx context.Context) error { - _, err := ouo.Save(ctx) +func (_u *OAuth2ClientUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (ouo *OAuth2ClientUpdateOne) ExecX(ctx context.Context) { - if err := ouo.Exec(ctx); err != nil { +func (_u *OAuth2ClientUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (ouo *OAuth2ClientUpdateOne) check() error { - if v, ok := ouo.mutation.Secret(); ok { +func (_u *OAuth2ClientUpdateOne) check() error { + if v, ok := _u.mutation.Secret(); ok { if err := oauth2client.SecretValidator(v); err != nil { return &ValidationError{Name: "secret", err: fmt.Errorf(`db: validator failed for field "OAuth2Client.secret": %w`, err)} } } - if v, ok := ouo.mutation.Name(); ok { + if v, ok := _u.mutation.Name(); ok { if err := oauth2client.NameValidator(v); err != nil { return &ValidationError{Name: "name", err: fmt.Errorf(`db: validator failed for field "OAuth2Client.name": %w`, err)} } } - if v, ok := ouo.mutation.LogoURL(); ok { + if v, ok := _u.mutation.LogoURL(); ok { if err := oauth2client.LogoURLValidator(v); err != nil { return &ValidationError{Name: "logo_url", err: fmt.Errorf(`db: validator failed for field "OAuth2Client.logo_url": %w`, err)} } @@ -397,23 +395,17 @@ func (ouo *OAuth2ClientUpdateOne) check() error { return nil } -func (ouo *OAuth2ClientUpdateOne) sqlSave(ctx context.Context) (_node *OAuth2Client, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: oauth2client.Table, - Columns: oauth2client.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: oauth2client.FieldID, - }, - }, +func (_u *OAuth2ClientUpdateOne) sqlSave(ctx context.Context) (_node *OAuth2Client, err error) { + if err := _u.check(); err != nil { + return _node, err } - id, ok := ouo.mutation.ID() + _spec := sqlgraph.NewUpdateSpec(oauth2client.Table, oauth2client.Columns, sqlgraph.NewFieldSpec(oauth2client.FieldID, field.TypeString)) + id, ok := _u.mutation.ID() if !ok { return nil, &ValidationError{Name: "id", err: errors.New(`db: missing "OAuth2Client.id" for update`)} } _spec.Node.ID.Value = id - if fields := ouo.fields; len(fields) > 0 { + if fields := _u.fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, oauth2client.FieldID) for _, f := range fields { @@ -425,71 +417,51 @@ func (ouo *OAuth2ClientUpdateOne) sqlSave(ctx context.Context) (_node *OAuth2Cli } } } - if ps := ouo.mutation.predicates; len(ps) > 0 { + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := ouo.mutation.Secret(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: oauth2client.FieldSecret, - }) + if value, ok := _u.mutation.Secret(); ok { + _spec.SetField(oauth2client.FieldSecret, field.TypeString, value) } - if value, ok := ouo.mutation.RedirectUris(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: oauth2client.FieldRedirectUris, - }) + if value, ok := _u.mutation.RedirectUris(); ok { + _spec.SetField(oauth2client.FieldRedirectUris, field.TypeJSON, value) } - if ouo.mutation.RedirectUrisCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: oauth2client.FieldRedirectUris, + if value, ok := _u.mutation.AppendedRedirectUris(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, oauth2client.FieldRedirectUris, value) }) } - if value, ok := ouo.mutation.TrustedPeers(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: oauth2client.FieldTrustedPeers, - }) + if _u.mutation.RedirectUrisCleared() { + _spec.ClearField(oauth2client.FieldRedirectUris, field.TypeJSON) } - if ouo.mutation.TrustedPeersCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: oauth2client.FieldTrustedPeers, - }) + if value, ok := _u.mutation.TrustedPeers(); ok { + _spec.SetField(oauth2client.FieldTrustedPeers, field.TypeJSON, value) } - if value, ok := ouo.mutation.Public(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBool, - Value: value, - Column: oauth2client.FieldPublic, + if value, ok := _u.mutation.AppendedTrustedPeers(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, oauth2client.FieldTrustedPeers, value) }) } - if value, ok := ouo.mutation.Name(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: oauth2client.FieldName, - }) + if _u.mutation.TrustedPeersCleared() { + _spec.ClearField(oauth2client.FieldTrustedPeers, field.TypeJSON) } - if value, ok := ouo.mutation.LogoURL(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: oauth2client.FieldLogoURL, - }) + if value, ok := _u.mutation.Public(); ok { + _spec.SetField(oauth2client.FieldPublic, field.TypeBool, value) + } + if value, ok := _u.mutation.Name(); ok { + _spec.SetField(oauth2client.FieldName, field.TypeString, value) + } + if value, ok := _u.mutation.LogoURL(); ok { + _spec.SetField(oauth2client.FieldLogoURL, field.TypeString, value) } - _node = &OAuth2Client{config: ouo.config} + _node = &OAuth2Client{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues - if err = sqlgraph.UpdateNode(ctx, ouo.driver, _spec); err != nil { + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{oauth2client.Label} } else if sqlgraph.IsConstraintError(err) { @@ -497,5 +469,6 @@ func (ouo *OAuth2ClientUpdateOne) sqlSave(ctx context.Context) (_node *OAuth2Cli } return nil, err } + _u.mutation.done = true return _node, nil } diff --git a/storage/ent/db/offlinesession.go b/storage/ent/db/offlinesession.go index 4b797e2672..b19fd9c6d2 100644 --- a/storage/ent/db/offlinesession.go +++ b/storage/ent/db/offlinesession.go @@ -6,6 +6,7 @@ import ( "fmt" "strings" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/dexidp/dex/storage/ent/db/offlinesession" ) @@ -23,11 +24,12 @@ type OfflineSession struct { Refresh []byte `json:"refresh,omitempty"` // ConnectorData holds the value of the "connector_data" field. ConnectorData *[]byte `json:"connector_data,omitempty"` + selectValues sql.SelectValues } // scanValues returns the types for scanning values from sql.Rows. -func (*OfflineSession) scanValues(columns []string) ([]interface{}, error) { - values := make([]interface{}, len(columns)) +func (*OfflineSession) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) for i := range columns { switch columns[i] { case offlinesession.FieldRefresh, offlinesession.FieldConnectorData: @@ -35,7 +37,7 @@ func (*OfflineSession) scanValues(columns []string) ([]interface{}, error) { case offlinesession.FieldID, offlinesession.FieldUserID, offlinesession.FieldConnID: values[i] = new(sql.NullString) default: - return nil, fmt.Errorf("unexpected column %q for type OfflineSession", columns[i]) + values[i] = new(sql.UnknownType) } } return values, nil @@ -43,7 +45,7 @@ func (*OfflineSession) scanValues(columns []string) ([]interface{}, error) { // assignValues assigns the values that were returned from sql.Rows (after scanning) // to the OfflineSession fields. -func (os *OfflineSession) assignValues(columns []string, values []interface{}) error { +func (_m *OfflineSession) assignValues(columns []string, values []any) error { if m, n := len(values), len(columns); m < n { return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) } @@ -53,70 +55,78 @@ func (os *OfflineSession) assignValues(columns []string, values []interface{}) e if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field id", values[i]) } else if value.Valid { - os.ID = value.String + _m.ID = value.String } case offlinesession.FieldUserID: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field user_id", values[i]) } else if value.Valid { - os.UserID = value.String + _m.UserID = value.String } case offlinesession.FieldConnID: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field conn_id", values[i]) } else if value.Valid { - os.ConnID = value.String + _m.ConnID = value.String } case offlinesession.FieldRefresh: if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field refresh", values[i]) } else if value != nil { - os.Refresh = *value + _m.Refresh = *value } case offlinesession.FieldConnectorData: if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field connector_data", values[i]) } else if value != nil { - os.ConnectorData = value + _m.ConnectorData = value } + default: + _m.selectValues.Set(columns[i], values[i]) } } return nil } +// Value returns the ent.Value that was dynamically selected and assigned to the OfflineSession. +// This includes values selected through modifiers, order, etc. +func (_m *OfflineSession) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + // Update returns a builder for updating this OfflineSession. // Note that you need to call OfflineSession.Unwrap() before calling this method if this OfflineSession // was returned from a transaction, and the transaction was committed or rolled back. -func (os *OfflineSession) Update() *OfflineSessionUpdateOne { - return (&OfflineSessionClient{config: os.config}).UpdateOne(os) +func (_m *OfflineSession) Update() *OfflineSessionUpdateOne { + return NewOfflineSessionClient(_m.config).UpdateOne(_m) } // Unwrap unwraps the OfflineSession entity that was returned from a transaction after it was closed, // so that all future queries will be executed through the driver which created the transaction. -func (os *OfflineSession) Unwrap() *OfflineSession { - _tx, ok := os.config.driver.(*txDriver) +func (_m *OfflineSession) Unwrap() *OfflineSession { + _tx, ok := _m.config.driver.(*txDriver) if !ok { panic("db: OfflineSession is not a transactional entity") } - os.config.driver = _tx.drv - return os + _m.config.driver = _tx.drv + return _m } // String implements the fmt.Stringer. -func (os *OfflineSession) String() string { +func (_m *OfflineSession) String() string { var builder strings.Builder builder.WriteString("OfflineSession(") - builder.WriteString(fmt.Sprintf("id=%v, ", os.ID)) + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) builder.WriteString("user_id=") - builder.WriteString(os.UserID) + builder.WriteString(_m.UserID) builder.WriteString(", ") builder.WriteString("conn_id=") - builder.WriteString(os.ConnID) + builder.WriteString(_m.ConnID) builder.WriteString(", ") builder.WriteString("refresh=") - builder.WriteString(fmt.Sprintf("%v", os.Refresh)) + builder.WriteString(fmt.Sprintf("%v", _m.Refresh)) builder.WriteString(", ") - if v := os.ConnectorData; v != nil { + if v := _m.ConnectorData; v != nil { builder.WriteString("connector_data=") builder.WriteString(fmt.Sprintf("%v", *v)) } @@ -126,9 +136,3 @@ func (os *OfflineSession) String() string { // OfflineSessions is a parsable slice of OfflineSession. type OfflineSessions []*OfflineSession - -func (os OfflineSessions) config(cfg config) { - for _i := range os { - os[_i].config = cfg - } -} diff --git a/storage/ent/db/offlinesession/offlinesession.go b/storage/ent/db/offlinesession/offlinesession.go index f996fe18d7..e7dbc446b7 100644 --- a/storage/ent/db/offlinesession/offlinesession.go +++ b/storage/ent/db/offlinesession/offlinesession.go @@ -2,6 +2,10 @@ package offlinesession +import ( + "entgo.io/ent/dialect/sql" +) + const ( // Label holds the string label denoting the offlinesession type in the database. Label = "offline_session" @@ -46,3 +50,21 @@ var ( // IDValidator is a validator for the "id" field. It is called by the builders before save. IDValidator func(string) error ) + +// OrderOption defines the ordering options for the OfflineSession queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByUserID orders the results by the user_id field. +func ByUserID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUserID, opts...).ToFunc() +} + +// ByConnID orders the results by the conn_id field. +func ByConnID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldConnID, opts...).ToFunc() +} diff --git a/storage/ent/db/offlinesession/where.go b/storage/ent/db/offlinesession/where.go index 2dbab2537e..e0f19ab2ce 100644 --- a/storage/ent/db/offlinesession/where.go +++ b/storage/ent/db/offlinesession/where.go @@ -9,471 +9,310 @@ import ( // ID filters vertices based on their ID field. func ID(id string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.OfflineSession(sql.FieldEQ(FieldID, id)) } // IDEQ applies the EQ predicate on the ID field. func IDEQ(id string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.OfflineSession(sql.FieldEQ(FieldID, id)) } // IDNEQ applies the NEQ predicate on the ID field. func IDNEQ(id string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldID), id)) - }) + return predicate.OfflineSession(sql.FieldNEQ(FieldID, id)) } // IDIn applies the In predicate on the ID field. func IDIn(ids ...string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.In(s.C(FieldID), v...)) - }) + return predicate.OfflineSession(sql.FieldIn(FieldID, ids...)) } // IDNotIn applies the NotIn predicate on the ID field. func IDNotIn(ids ...string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.NotIn(s.C(FieldID), v...)) - }) + return predicate.OfflineSession(sql.FieldNotIn(FieldID, ids...)) } // IDGT applies the GT predicate on the ID field. func IDGT(id string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldID), id)) - }) + return predicate.OfflineSession(sql.FieldGT(FieldID, id)) } // IDGTE applies the GTE predicate on the ID field. func IDGTE(id string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldID), id)) - }) + return predicate.OfflineSession(sql.FieldGTE(FieldID, id)) } // IDLT applies the LT predicate on the ID field. func IDLT(id string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldID), id)) - }) + return predicate.OfflineSession(sql.FieldLT(FieldID, id)) } // IDLTE applies the LTE predicate on the ID field. func IDLTE(id string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldID), id)) - }) + return predicate.OfflineSession(sql.FieldLTE(FieldID, id)) +} + +// IDEqualFold applies the EqualFold predicate on the ID field. +func IDEqualFold(id string) predicate.OfflineSession { + return predicate.OfflineSession(sql.FieldEqualFold(FieldID, id)) +} + +// IDContainsFold applies the ContainsFold predicate on the ID field. +func IDContainsFold(id string) predicate.OfflineSession { + return predicate.OfflineSession(sql.FieldContainsFold(FieldID, id)) } // UserID applies equality check predicate on the "user_id" field. It's identical to UserIDEQ. func UserID(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldUserID), v)) - }) + return predicate.OfflineSession(sql.FieldEQ(FieldUserID, v)) } // ConnID applies equality check predicate on the "conn_id" field. It's identical to ConnIDEQ. func ConnID(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldConnID), v)) - }) + return predicate.OfflineSession(sql.FieldEQ(FieldConnID, v)) } // Refresh applies equality check predicate on the "refresh" field. It's identical to RefreshEQ. func Refresh(v []byte) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldRefresh), v)) - }) + return predicate.OfflineSession(sql.FieldEQ(FieldRefresh, v)) } // ConnectorData applies equality check predicate on the "connector_data" field. It's identical to ConnectorDataEQ. func ConnectorData(v []byte) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldConnectorData), v)) - }) + return predicate.OfflineSession(sql.FieldEQ(FieldConnectorData, v)) } // UserIDEQ applies the EQ predicate on the "user_id" field. func UserIDEQ(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldUserID), v)) - }) + return predicate.OfflineSession(sql.FieldEQ(FieldUserID, v)) } // UserIDNEQ applies the NEQ predicate on the "user_id" field. func UserIDNEQ(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldUserID), v)) - }) + return predicate.OfflineSession(sql.FieldNEQ(FieldUserID, v)) } // UserIDIn applies the In predicate on the "user_id" field. func UserIDIn(vs ...string) predicate.OfflineSession { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldUserID), v...)) - }) + return predicate.OfflineSession(sql.FieldIn(FieldUserID, vs...)) } // UserIDNotIn applies the NotIn predicate on the "user_id" field. func UserIDNotIn(vs ...string) predicate.OfflineSession { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldUserID), v...)) - }) + return predicate.OfflineSession(sql.FieldNotIn(FieldUserID, vs...)) } // UserIDGT applies the GT predicate on the "user_id" field. func UserIDGT(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldUserID), v)) - }) + return predicate.OfflineSession(sql.FieldGT(FieldUserID, v)) } // UserIDGTE applies the GTE predicate on the "user_id" field. func UserIDGTE(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldUserID), v)) - }) + return predicate.OfflineSession(sql.FieldGTE(FieldUserID, v)) } // UserIDLT applies the LT predicate on the "user_id" field. func UserIDLT(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldUserID), v)) - }) + return predicate.OfflineSession(sql.FieldLT(FieldUserID, v)) } // UserIDLTE applies the LTE predicate on the "user_id" field. func UserIDLTE(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldUserID), v)) - }) + return predicate.OfflineSession(sql.FieldLTE(FieldUserID, v)) } // UserIDContains applies the Contains predicate on the "user_id" field. func UserIDContains(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldUserID), v)) - }) + return predicate.OfflineSession(sql.FieldContains(FieldUserID, v)) } // UserIDHasPrefix applies the HasPrefix predicate on the "user_id" field. func UserIDHasPrefix(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldUserID), v)) - }) + return predicate.OfflineSession(sql.FieldHasPrefix(FieldUserID, v)) } // UserIDHasSuffix applies the HasSuffix predicate on the "user_id" field. func UserIDHasSuffix(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldUserID), v)) - }) + return predicate.OfflineSession(sql.FieldHasSuffix(FieldUserID, v)) } // UserIDEqualFold applies the EqualFold predicate on the "user_id" field. func UserIDEqualFold(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldUserID), v)) - }) + return predicate.OfflineSession(sql.FieldEqualFold(FieldUserID, v)) } // UserIDContainsFold applies the ContainsFold predicate on the "user_id" field. func UserIDContainsFold(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldUserID), v)) - }) + return predicate.OfflineSession(sql.FieldContainsFold(FieldUserID, v)) } // ConnIDEQ applies the EQ predicate on the "conn_id" field. func ConnIDEQ(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldConnID), v)) - }) + return predicate.OfflineSession(sql.FieldEQ(FieldConnID, v)) } // ConnIDNEQ applies the NEQ predicate on the "conn_id" field. func ConnIDNEQ(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldConnID), v)) - }) + return predicate.OfflineSession(sql.FieldNEQ(FieldConnID, v)) } // ConnIDIn applies the In predicate on the "conn_id" field. func ConnIDIn(vs ...string) predicate.OfflineSession { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldConnID), v...)) - }) + return predicate.OfflineSession(sql.FieldIn(FieldConnID, vs...)) } // ConnIDNotIn applies the NotIn predicate on the "conn_id" field. func ConnIDNotIn(vs ...string) predicate.OfflineSession { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldConnID), v...)) - }) + return predicate.OfflineSession(sql.FieldNotIn(FieldConnID, vs...)) } // ConnIDGT applies the GT predicate on the "conn_id" field. func ConnIDGT(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldConnID), v)) - }) + return predicate.OfflineSession(sql.FieldGT(FieldConnID, v)) } // ConnIDGTE applies the GTE predicate on the "conn_id" field. func ConnIDGTE(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldConnID), v)) - }) + return predicate.OfflineSession(sql.FieldGTE(FieldConnID, v)) } // ConnIDLT applies the LT predicate on the "conn_id" field. func ConnIDLT(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldConnID), v)) - }) + return predicate.OfflineSession(sql.FieldLT(FieldConnID, v)) } // ConnIDLTE applies the LTE predicate on the "conn_id" field. func ConnIDLTE(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldConnID), v)) - }) + return predicate.OfflineSession(sql.FieldLTE(FieldConnID, v)) } // ConnIDContains applies the Contains predicate on the "conn_id" field. func ConnIDContains(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldConnID), v)) - }) + return predicate.OfflineSession(sql.FieldContains(FieldConnID, v)) } // ConnIDHasPrefix applies the HasPrefix predicate on the "conn_id" field. func ConnIDHasPrefix(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldConnID), v)) - }) + return predicate.OfflineSession(sql.FieldHasPrefix(FieldConnID, v)) } // ConnIDHasSuffix applies the HasSuffix predicate on the "conn_id" field. func ConnIDHasSuffix(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldConnID), v)) - }) + return predicate.OfflineSession(sql.FieldHasSuffix(FieldConnID, v)) } // ConnIDEqualFold applies the EqualFold predicate on the "conn_id" field. func ConnIDEqualFold(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldConnID), v)) - }) + return predicate.OfflineSession(sql.FieldEqualFold(FieldConnID, v)) } // ConnIDContainsFold applies the ContainsFold predicate on the "conn_id" field. func ConnIDContainsFold(v string) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldConnID), v)) - }) + return predicate.OfflineSession(sql.FieldContainsFold(FieldConnID, v)) } // RefreshEQ applies the EQ predicate on the "refresh" field. func RefreshEQ(v []byte) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldRefresh), v)) - }) + return predicate.OfflineSession(sql.FieldEQ(FieldRefresh, v)) } // RefreshNEQ applies the NEQ predicate on the "refresh" field. func RefreshNEQ(v []byte) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldRefresh), v)) - }) + return predicate.OfflineSession(sql.FieldNEQ(FieldRefresh, v)) } // RefreshIn applies the In predicate on the "refresh" field. func RefreshIn(vs ...[]byte) predicate.OfflineSession { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldRefresh), v...)) - }) + return predicate.OfflineSession(sql.FieldIn(FieldRefresh, vs...)) } // RefreshNotIn applies the NotIn predicate on the "refresh" field. func RefreshNotIn(vs ...[]byte) predicate.OfflineSession { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldRefresh), v...)) - }) + return predicate.OfflineSession(sql.FieldNotIn(FieldRefresh, vs...)) } // RefreshGT applies the GT predicate on the "refresh" field. func RefreshGT(v []byte) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldRefresh), v)) - }) + return predicate.OfflineSession(sql.FieldGT(FieldRefresh, v)) } // RefreshGTE applies the GTE predicate on the "refresh" field. func RefreshGTE(v []byte) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldRefresh), v)) - }) + return predicate.OfflineSession(sql.FieldGTE(FieldRefresh, v)) } // RefreshLT applies the LT predicate on the "refresh" field. func RefreshLT(v []byte) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldRefresh), v)) - }) + return predicate.OfflineSession(sql.FieldLT(FieldRefresh, v)) } // RefreshLTE applies the LTE predicate on the "refresh" field. func RefreshLTE(v []byte) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldRefresh), v)) - }) + return predicate.OfflineSession(sql.FieldLTE(FieldRefresh, v)) } // ConnectorDataEQ applies the EQ predicate on the "connector_data" field. func ConnectorDataEQ(v []byte) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldConnectorData), v)) - }) + return predicate.OfflineSession(sql.FieldEQ(FieldConnectorData, v)) } // ConnectorDataNEQ applies the NEQ predicate on the "connector_data" field. func ConnectorDataNEQ(v []byte) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldConnectorData), v)) - }) + return predicate.OfflineSession(sql.FieldNEQ(FieldConnectorData, v)) } // ConnectorDataIn applies the In predicate on the "connector_data" field. func ConnectorDataIn(vs ...[]byte) predicate.OfflineSession { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldConnectorData), v...)) - }) + return predicate.OfflineSession(sql.FieldIn(FieldConnectorData, vs...)) } // ConnectorDataNotIn applies the NotIn predicate on the "connector_data" field. func ConnectorDataNotIn(vs ...[]byte) predicate.OfflineSession { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldConnectorData), v...)) - }) + return predicate.OfflineSession(sql.FieldNotIn(FieldConnectorData, vs...)) } // ConnectorDataGT applies the GT predicate on the "connector_data" field. func ConnectorDataGT(v []byte) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldConnectorData), v)) - }) + return predicate.OfflineSession(sql.FieldGT(FieldConnectorData, v)) } // ConnectorDataGTE applies the GTE predicate on the "connector_data" field. func ConnectorDataGTE(v []byte) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldConnectorData), v)) - }) + return predicate.OfflineSession(sql.FieldGTE(FieldConnectorData, v)) } // ConnectorDataLT applies the LT predicate on the "connector_data" field. func ConnectorDataLT(v []byte) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldConnectorData), v)) - }) + return predicate.OfflineSession(sql.FieldLT(FieldConnectorData, v)) } // ConnectorDataLTE applies the LTE predicate on the "connector_data" field. func ConnectorDataLTE(v []byte) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldConnectorData), v)) - }) + return predicate.OfflineSession(sql.FieldLTE(FieldConnectorData, v)) } // ConnectorDataIsNil applies the IsNil predicate on the "connector_data" field. func ConnectorDataIsNil() predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.IsNull(s.C(FieldConnectorData))) - }) + return predicate.OfflineSession(sql.FieldIsNull(FieldConnectorData)) } // ConnectorDataNotNil applies the NotNil predicate on the "connector_data" field. func ConnectorDataNotNil() predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s.Where(sql.NotNull(s.C(FieldConnectorData))) - }) + return predicate.OfflineSession(sql.FieldNotNull(FieldConnectorData)) } // And groups predicates with the AND operator between them. func And(predicates ...predicate.OfflineSession) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for _, p := range predicates { - p(s1) - } - s.Where(s1.P()) - }) + return predicate.OfflineSession(sql.AndPredicates(predicates...)) } // Or groups predicates with the OR operator between them. func Or(predicates ...predicate.OfflineSession) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for i, p := range predicates { - if i > 0 { - s1.Or() - } - p(s1) - } - s.Where(s1.P()) - }) + return predicate.OfflineSession(sql.OrPredicates(predicates...)) } // Not applies the not operator on the given predicate. func Not(p predicate.OfflineSession) predicate.OfflineSession { - return predicate.OfflineSession(func(s *sql.Selector) { - p(s.Not()) - }) + return predicate.OfflineSession(sql.NotPredicates(p)) } diff --git a/storage/ent/db/offlinesession_create.go b/storage/ent/db/offlinesession_create.go index 82b8014f1b..a3ccbbf390 100644 --- a/storage/ent/db/offlinesession_create.go +++ b/storage/ent/db/offlinesession_create.go @@ -20,90 +20,48 @@ type OfflineSessionCreate struct { } // SetUserID sets the "user_id" field. -func (osc *OfflineSessionCreate) SetUserID(s string) *OfflineSessionCreate { - osc.mutation.SetUserID(s) - return osc +func (_c *OfflineSessionCreate) SetUserID(v string) *OfflineSessionCreate { + _c.mutation.SetUserID(v) + return _c } // SetConnID sets the "conn_id" field. -func (osc *OfflineSessionCreate) SetConnID(s string) *OfflineSessionCreate { - osc.mutation.SetConnID(s) - return osc +func (_c *OfflineSessionCreate) SetConnID(v string) *OfflineSessionCreate { + _c.mutation.SetConnID(v) + return _c } // SetRefresh sets the "refresh" field. -func (osc *OfflineSessionCreate) SetRefresh(b []byte) *OfflineSessionCreate { - osc.mutation.SetRefresh(b) - return osc +func (_c *OfflineSessionCreate) SetRefresh(v []byte) *OfflineSessionCreate { + _c.mutation.SetRefresh(v) + return _c } // SetConnectorData sets the "connector_data" field. -func (osc *OfflineSessionCreate) SetConnectorData(b []byte) *OfflineSessionCreate { - osc.mutation.SetConnectorData(b) - return osc +func (_c *OfflineSessionCreate) SetConnectorData(v []byte) *OfflineSessionCreate { + _c.mutation.SetConnectorData(v) + return _c } // SetID sets the "id" field. -func (osc *OfflineSessionCreate) SetID(s string) *OfflineSessionCreate { - osc.mutation.SetID(s) - return osc +func (_c *OfflineSessionCreate) SetID(v string) *OfflineSessionCreate { + _c.mutation.SetID(v) + return _c } // Mutation returns the OfflineSessionMutation object of the builder. -func (osc *OfflineSessionCreate) Mutation() *OfflineSessionMutation { - return osc.mutation +func (_c *OfflineSessionCreate) Mutation() *OfflineSessionMutation { + return _c.mutation } // Save creates the OfflineSession in the database. -func (osc *OfflineSessionCreate) Save(ctx context.Context) (*OfflineSession, error) { - var ( - err error - node *OfflineSession - ) - if len(osc.hooks) == 0 { - if err = osc.check(); err != nil { - return nil, err - } - node, err = osc.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*OfflineSessionMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = osc.check(); err != nil { - return nil, err - } - osc.mutation = mutation - if node, err = osc.sqlSave(ctx); err != nil { - return nil, err - } - mutation.id = &node.ID - mutation.done = true - return node, err - }) - for i := len(osc.hooks) - 1; i >= 0; i-- { - if osc.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = osc.hooks[i](mut) - } - v, err := mut.Mutate(ctx, osc.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*OfflineSession) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from OfflineSessionMutation", v) - } - node = nv - } - return node, err +func (_c *OfflineSessionCreate) Save(ctx context.Context) (*OfflineSession, error) { + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) } // SaveX calls Save and panics if Save returns an error. -func (osc *OfflineSessionCreate) SaveX(ctx context.Context) *OfflineSession { - v, err := osc.Save(ctx) +func (_c *OfflineSessionCreate) SaveX(ctx context.Context) *OfflineSession { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -111,40 +69,40 @@ func (osc *OfflineSessionCreate) SaveX(ctx context.Context) *OfflineSession { } // Exec executes the query. -func (osc *OfflineSessionCreate) Exec(ctx context.Context) error { - _, err := osc.Save(ctx) +func (_c *OfflineSessionCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (osc *OfflineSessionCreate) ExecX(ctx context.Context) { - if err := osc.Exec(ctx); err != nil { +func (_c *OfflineSessionCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (osc *OfflineSessionCreate) check() error { - if _, ok := osc.mutation.UserID(); !ok { +func (_c *OfflineSessionCreate) check() error { + if _, ok := _c.mutation.UserID(); !ok { return &ValidationError{Name: "user_id", err: errors.New(`db: missing required field "OfflineSession.user_id"`)} } - if v, ok := osc.mutation.UserID(); ok { + if v, ok := _c.mutation.UserID(); ok { if err := offlinesession.UserIDValidator(v); err != nil { return &ValidationError{Name: "user_id", err: fmt.Errorf(`db: validator failed for field "OfflineSession.user_id": %w`, err)} } } - if _, ok := osc.mutation.ConnID(); !ok { + if _, ok := _c.mutation.ConnID(); !ok { return &ValidationError{Name: "conn_id", err: errors.New(`db: missing required field "OfflineSession.conn_id"`)} } - if v, ok := osc.mutation.ConnID(); ok { + if v, ok := _c.mutation.ConnID(); ok { if err := offlinesession.ConnIDValidator(v); err != nil { return &ValidationError{Name: "conn_id", err: fmt.Errorf(`db: validator failed for field "OfflineSession.conn_id": %w`, err)} } } - if _, ok := osc.mutation.Refresh(); !ok { + if _, ok := _c.mutation.Refresh(); !ok { return &ValidationError{Name: "refresh", err: errors.New(`db: missing required field "OfflineSession.refresh"`)} } - if v, ok := osc.mutation.ID(); ok { + if v, ok := _c.mutation.ID(); ok { if err := offlinesession.IDValidator(v); err != nil { return &ValidationError{Name: "id", err: fmt.Errorf(`db: validator failed for field "OfflineSession.id": %w`, err)} } @@ -152,9 +110,12 @@ func (osc *OfflineSessionCreate) check() error { return nil } -func (osc *OfflineSessionCreate) sqlSave(ctx context.Context) (*OfflineSession, error) { - _node, _spec := osc.createSpec() - if err := sqlgraph.CreateNode(ctx, osc.driver, _spec); err != nil { +func (_c *OfflineSessionCreate) sqlSave(ctx context.Context) (*OfflineSession, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -167,54 +128,34 @@ func (osc *OfflineSessionCreate) sqlSave(ctx context.Context) (*OfflineSession, return nil, fmt.Errorf("unexpected OfflineSession.ID type: %T", _spec.ID.Value) } } + _c.mutation.id = &_node.ID + _c.mutation.done = true return _node, nil } -func (osc *OfflineSessionCreate) createSpec() (*OfflineSession, *sqlgraph.CreateSpec) { +func (_c *OfflineSessionCreate) createSpec() (*OfflineSession, *sqlgraph.CreateSpec) { var ( - _node = &OfflineSession{config: osc.config} - _spec = &sqlgraph.CreateSpec{ - Table: offlinesession.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: offlinesession.FieldID, - }, - } + _node = &OfflineSession{config: _c.config} + _spec = sqlgraph.NewCreateSpec(offlinesession.Table, sqlgraph.NewFieldSpec(offlinesession.FieldID, field.TypeString)) ) - if id, ok := osc.mutation.ID(); ok { + if id, ok := _c.mutation.ID(); ok { _node.ID = id _spec.ID.Value = id } - if value, ok := osc.mutation.UserID(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: offlinesession.FieldUserID, - }) + if value, ok := _c.mutation.UserID(); ok { + _spec.SetField(offlinesession.FieldUserID, field.TypeString, value) _node.UserID = value } - if value, ok := osc.mutation.ConnID(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: offlinesession.FieldConnID, - }) + if value, ok := _c.mutation.ConnID(); ok { + _spec.SetField(offlinesession.FieldConnID, field.TypeString, value) _node.ConnID = value } - if value, ok := osc.mutation.Refresh(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: offlinesession.FieldRefresh, - }) + if value, ok := _c.mutation.Refresh(); ok { + _spec.SetField(offlinesession.FieldRefresh, field.TypeBytes, value) _node.Refresh = value } - if value, ok := osc.mutation.ConnectorData(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: offlinesession.FieldConnectorData, - }) + if value, ok := _c.mutation.ConnectorData(); ok { + _spec.SetField(offlinesession.FieldConnectorData, field.TypeBytes, value) _node.ConnectorData = &value } return _node, _spec @@ -223,17 +164,21 @@ func (osc *OfflineSessionCreate) createSpec() (*OfflineSession, *sqlgraph.Create // OfflineSessionCreateBulk is the builder for creating many OfflineSession entities in bulk. type OfflineSessionCreateBulk struct { config + err error builders []*OfflineSessionCreate } // Save creates the OfflineSession entities in the database. -func (oscb *OfflineSessionCreateBulk) Save(ctx context.Context) ([]*OfflineSession, error) { - specs := make([]*sqlgraph.CreateSpec, len(oscb.builders)) - nodes := make([]*OfflineSession, len(oscb.builders)) - mutators := make([]Mutator, len(oscb.builders)) - for i := range oscb.builders { +func (_c *OfflineSessionCreateBulk) Save(ctx context.Context) ([]*OfflineSession, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*OfflineSession, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { func(i int, root context.Context) { - builder := oscb.builders[i] + builder := _c.builders[i] var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { mutation, ok := m.(*OfflineSessionMutation) if !ok { @@ -243,14 +188,14 @@ func (oscb *OfflineSessionCreateBulk) Save(ctx context.Context) ([]*OfflineSessi return nil, err } builder.mutation = mutation - nodes[i], specs[i] = builder.createSpec() var err error + nodes[i], specs[i] = builder.createSpec() if i < len(mutators)-1 { - _, err = mutators[i+1].Mutate(root, oscb.builders[i+1].mutation) + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} // Invoke the actual operation on the latest mutation in the chain. - if err = sqlgraph.BatchCreate(ctx, oscb.driver, spec); err != nil { + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -270,7 +215,7 @@ func (oscb *OfflineSessionCreateBulk) Save(ctx context.Context) ([]*OfflineSessi }(i, ctx) } if len(mutators) > 0 { - if _, err := mutators[0].Mutate(ctx, oscb.builders[0].mutation); err != nil { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { return nil, err } } @@ -278,8 +223,8 @@ func (oscb *OfflineSessionCreateBulk) Save(ctx context.Context) ([]*OfflineSessi } // SaveX is like Save, but panics if an error occurs. -func (oscb *OfflineSessionCreateBulk) SaveX(ctx context.Context) []*OfflineSession { - v, err := oscb.Save(ctx) +func (_c *OfflineSessionCreateBulk) SaveX(ctx context.Context) []*OfflineSession { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -287,14 +232,14 @@ func (oscb *OfflineSessionCreateBulk) SaveX(ctx context.Context) []*OfflineSessi } // Exec executes the query. -func (oscb *OfflineSessionCreateBulk) Exec(ctx context.Context) error { - _, err := oscb.Save(ctx) +func (_c *OfflineSessionCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (oscb *OfflineSessionCreateBulk) ExecX(ctx context.Context) { - if err := oscb.Exec(ctx); err != nil { +func (_c *OfflineSessionCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } diff --git a/storage/ent/db/offlinesession_delete.go b/storage/ent/db/offlinesession_delete.go index b9c60ba9a3..ea03cd507e 100644 --- a/storage/ent/db/offlinesession_delete.go +++ b/storage/ent/db/offlinesession_delete.go @@ -4,7 +4,6 @@ package db import ( "context" - "fmt" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" @@ -21,84 +20,56 @@ type OfflineSessionDelete struct { } // Where appends a list predicates to the OfflineSessionDelete builder. -func (osd *OfflineSessionDelete) Where(ps ...predicate.OfflineSession) *OfflineSessionDelete { - osd.mutation.Where(ps...) - return osd +func (_d *OfflineSessionDelete) Where(ps ...predicate.OfflineSession) *OfflineSessionDelete { + _d.mutation.Where(ps...) + return _d } // Exec executes the deletion query and returns how many vertices were deleted. -func (osd *OfflineSessionDelete) Exec(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(osd.hooks) == 0 { - affected, err = osd.sqlExec(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*OfflineSessionMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - osd.mutation = mutation - affected, err = osd.sqlExec(ctx) - mutation.done = true - return affected, err - }) - for i := len(osd.hooks) - 1; i >= 0; i-- { - if osd.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = osd.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, osd.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_d *OfflineSessionDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) } // ExecX is like Exec, but panics if an error occurs. -func (osd *OfflineSessionDelete) ExecX(ctx context.Context) int { - n, err := osd.Exec(ctx) +func (_d *OfflineSessionDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) if err != nil { panic(err) } return n } -func (osd *OfflineSessionDelete) sqlExec(ctx context.Context) (int, error) { - _spec := &sqlgraph.DeleteSpec{ - Node: &sqlgraph.NodeSpec{ - Table: offlinesession.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: offlinesession.FieldID, - }, - }, - } - if ps := osd.mutation.predicates; len(ps) > 0 { +func (_d *OfflineSessionDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(offlinesession.Table, sqlgraph.NewFieldSpec(offlinesession.FieldID, field.TypeString)) + if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - affected, err := sqlgraph.DeleteNodes(ctx, osd.driver, _spec) + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) if err != nil && sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } + _d.mutation.done = true return affected, err } // OfflineSessionDeleteOne is the builder for deleting a single OfflineSession entity. type OfflineSessionDeleteOne struct { - osd *OfflineSessionDelete + _d *OfflineSessionDelete +} + +// Where appends a list predicates to the OfflineSessionDelete builder. +func (_d *OfflineSessionDeleteOne) Where(ps ...predicate.OfflineSession) *OfflineSessionDeleteOne { + _d._d.mutation.Where(ps...) + return _d } // Exec executes the deletion query. -func (osdo *OfflineSessionDeleteOne) Exec(ctx context.Context) error { - n, err := osdo.osd.Exec(ctx) +func (_d *OfflineSessionDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) switch { case err != nil: return err @@ -110,6 +81,8 @@ func (osdo *OfflineSessionDeleteOne) Exec(ctx context.Context) error { } // ExecX is like Exec, but panics if an error occurs. -func (osdo *OfflineSessionDeleteOne) ExecX(ctx context.Context) { - osdo.osd.ExecX(ctx) +func (_d *OfflineSessionDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } } diff --git a/storage/ent/db/offlinesession_query.go b/storage/ent/db/offlinesession_query.go index e5e09cf16d..22723620d4 100644 --- a/storage/ent/db/offlinesession_query.go +++ b/storage/ent/db/offlinesession_query.go @@ -7,6 +7,7 @@ import ( "fmt" "math" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" @@ -17,11 +18,9 @@ import ( // OfflineSessionQuery is the builder for querying OfflineSession entities. type OfflineSessionQuery struct { config - limit *int - offset *int - unique *bool - order []OrderFunc - fields []string + ctx *QueryContext + order []offlinesession.OrderOption + inters []Interceptor predicates []predicate.OfflineSession // intermediate query (i.e. traversal path). sql *sql.Selector @@ -29,40 +28,40 @@ type OfflineSessionQuery struct { } // Where adds a new predicate for the OfflineSessionQuery builder. -func (osq *OfflineSessionQuery) Where(ps ...predicate.OfflineSession) *OfflineSessionQuery { - osq.predicates = append(osq.predicates, ps...) - return osq +func (_q *OfflineSessionQuery) Where(ps ...predicate.OfflineSession) *OfflineSessionQuery { + _q.predicates = append(_q.predicates, ps...) + return _q } -// Limit adds a limit step to the query. -func (osq *OfflineSessionQuery) Limit(limit int) *OfflineSessionQuery { - osq.limit = &limit - return osq +// Limit the number of records to be returned by this query. +func (_q *OfflineSessionQuery) Limit(limit int) *OfflineSessionQuery { + _q.ctx.Limit = &limit + return _q } -// Offset adds an offset step to the query. -func (osq *OfflineSessionQuery) Offset(offset int) *OfflineSessionQuery { - osq.offset = &offset - return osq +// Offset to start from. +func (_q *OfflineSessionQuery) Offset(offset int) *OfflineSessionQuery { + _q.ctx.Offset = &offset + return _q } // Unique configures the query builder to filter duplicate records on query. // By default, unique is set to true, and can be disabled using this method. -func (osq *OfflineSessionQuery) Unique(unique bool) *OfflineSessionQuery { - osq.unique = &unique - return osq +func (_q *OfflineSessionQuery) Unique(unique bool) *OfflineSessionQuery { + _q.ctx.Unique = &unique + return _q } -// Order adds an order step to the query. -func (osq *OfflineSessionQuery) Order(o ...OrderFunc) *OfflineSessionQuery { - osq.order = append(osq.order, o...) - return osq +// Order specifies how the records should be ordered. +func (_q *OfflineSessionQuery) Order(o ...offlinesession.OrderOption) *OfflineSessionQuery { + _q.order = append(_q.order, o...) + return _q } // First returns the first OfflineSession entity from the query. // Returns a *NotFoundError when no OfflineSession was found. -func (osq *OfflineSessionQuery) First(ctx context.Context) (*OfflineSession, error) { - nodes, err := osq.Limit(1).All(ctx) +func (_q *OfflineSessionQuery) First(ctx context.Context) (*OfflineSession, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) if err != nil { return nil, err } @@ -73,8 +72,8 @@ func (osq *OfflineSessionQuery) First(ctx context.Context) (*OfflineSession, err } // FirstX is like First, but panics if an error occurs. -func (osq *OfflineSessionQuery) FirstX(ctx context.Context) *OfflineSession { - node, err := osq.First(ctx) +func (_q *OfflineSessionQuery) FirstX(ctx context.Context) *OfflineSession { + node, err := _q.First(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -83,9 +82,9 @@ func (osq *OfflineSessionQuery) FirstX(ctx context.Context) *OfflineSession { // FirstID returns the first OfflineSession ID from the query. // Returns a *NotFoundError when no OfflineSession ID was found. -func (osq *OfflineSessionQuery) FirstID(ctx context.Context) (id string, err error) { +func (_q *OfflineSessionQuery) FirstID(ctx context.Context) (id string, err error) { var ids []string - if ids, err = osq.Limit(1).IDs(ctx); err != nil { + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { return } if len(ids) == 0 { @@ -96,8 +95,8 @@ func (osq *OfflineSessionQuery) FirstID(ctx context.Context) (id string, err err } // FirstIDX is like FirstID, but panics if an error occurs. -func (osq *OfflineSessionQuery) FirstIDX(ctx context.Context) string { - id, err := osq.FirstID(ctx) +func (_q *OfflineSessionQuery) FirstIDX(ctx context.Context) string { + id, err := _q.FirstID(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -107,8 +106,8 @@ func (osq *OfflineSessionQuery) FirstIDX(ctx context.Context) string { // Only returns a single OfflineSession entity found by the query, ensuring it only returns one. // Returns a *NotSingularError when more than one OfflineSession entity is found. // Returns a *NotFoundError when no OfflineSession entities are found. -func (osq *OfflineSessionQuery) Only(ctx context.Context) (*OfflineSession, error) { - nodes, err := osq.Limit(2).All(ctx) +func (_q *OfflineSessionQuery) Only(ctx context.Context) (*OfflineSession, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) if err != nil { return nil, err } @@ -123,8 +122,8 @@ func (osq *OfflineSessionQuery) Only(ctx context.Context) (*OfflineSession, erro } // OnlyX is like Only, but panics if an error occurs. -func (osq *OfflineSessionQuery) OnlyX(ctx context.Context) *OfflineSession { - node, err := osq.Only(ctx) +func (_q *OfflineSessionQuery) OnlyX(ctx context.Context) *OfflineSession { + node, err := _q.Only(ctx) if err != nil { panic(err) } @@ -134,9 +133,9 @@ func (osq *OfflineSessionQuery) OnlyX(ctx context.Context) *OfflineSession { // OnlyID is like Only, but returns the only OfflineSession ID in the query. // Returns a *NotSingularError when more than one OfflineSession ID is found. // Returns a *NotFoundError when no entities are found. -func (osq *OfflineSessionQuery) OnlyID(ctx context.Context) (id string, err error) { +func (_q *OfflineSessionQuery) OnlyID(ctx context.Context) (id string, err error) { var ids []string - if ids, err = osq.Limit(2).IDs(ctx); err != nil { + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { return } switch len(ids) { @@ -151,8 +150,8 @@ func (osq *OfflineSessionQuery) OnlyID(ctx context.Context) (id string, err erro } // OnlyIDX is like OnlyID, but panics if an error occurs. -func (osq *OfflineSessionQuery) OnlyIDX(ctx context.Context) string { - id, err := osq.OnlyID(ctx) +func (_q *OfflineSessionQuery) OnlyIDX(ctx context.Context) string { + id, err := _q.OnlyID(ctx) if err != nil { panic(err) } @@ -160,16 +159,18 @@ func (osq *OfflineSessionQuery) OnlyIDX(ctx context.Context) string { } // All executes the query and returns a list of OfflineSessions. -func (osq *OfflineSessionQuery) All(ctx context.Context) ([]*OfflineSession, error) { - if err := osq.prepareQuery(ctx); err != nil { +func (_q *OfflineSessionQuery) All(ctx context.Context) ([]*OfflineSession, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { return nil, err } - return osq.sqlAll(ctx) + qr := querierAll[[]*OfflineSession, *OfflineSessionQuery]() + return withInterceptors[[]*OfflineSession](ctx, _q, qr, _q.inters) } // AllX is like All, but panics if an error occurs. -func (osq *OfflineSessionQuery) AllX(ctx context.Context) []*OfflineSession { - nodes, err := osq.All(ctx) +func (_q *OfflineSessionQuery) AllX(ctx context.Context) []*OfflineSession { + nodes, err := _q.All(ctx) if err != nil { panic(err) } @@ -177,17 +178,20 @@ func (osq *OfflineSessionQuery) AllX(ctx context.Context) []*OfflineSession { } // IDs executes the query and returns a list of OfflineSession IDs. -func (osq *OfflineSessionQuery) IDs(ctx context.Context) ([]string, error) { - var ids []string - if err := osq.Select(offlinesession.FieldID).Scan(ctx, &ids); err != nil { +func (_q *OfflineSessionQuery) IDs(ctx context.Context) (ids []string, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(offlinesession.FieldID).Scan(ctx, &ids); err != nil { return nil, err } return ids, nil } // IDsX is like IDs, but panics if an error occurs. -func (osq *OfflineSessionQuery) IDsX(ctx context.Context) []string { - ids, err := osq.IDs(ctx) +func (_q *OfflineSessionQuery) IDsX(ctx context.Context) []string { + ids, err := _q.IDs(ctx) if err != nil { panic(err) } @@ -195,16 +199,17 @@ func (osq *OfflineSessionQuery) IDsX(ctx context.Context) []string { } // Count returns the count of the given query. -func (osq *OfflineSessionQuery) Count(ctx context.Context) (int, error) { - if err := osq.prepareQuery(ctx); err != nil { +func (_q *OfflineSessionQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { return 0, err } - return osq.sqlCount(ctx) + return withInterceptors[int](ctx, _q, querierCount[*OfflineSessionQuery](), _q.inters) } // CountX is like Count, but panics if an error occurs. -func (osq *OfflineSessionQuery) CountX(ctx context.Context) int { - count, err := osq.Count(ctx) +func (_q *OfflineSessionQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) if err != nil { panic(err) } @@ -212,16 +217,21 @@ func (osq *OfflineSessionQuery) CountX(ctx context.Context) int { } // Exist returns true if the query has elements in the graph. -func (osq *OfflineSessionQuery) Exist(ctx context.Context) (bool, error) { - if err := osq.prepareQuery(ctx); err != nil { - return false, err +func (_q *OfflineSessionQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("db: check existence: %w", err) + default: + return true, nil } - return osq.sqlExist(ctx) } // ExistX is like Exist, but panics if an error occurs. -func (osq *OfflineSessionQuery) ExistX(ctx context.Context) bool { - exist, err := osq.Exist(ctx) +func (_q *OfflineSessionQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) if err != nil { panic(err) } @@ -230,20 +240,19 @@ func (osq *OfflineSessionQuery) ExistX(ctx context.Context) bool { // Clone returns a duplicate of the OfflineSessionQuery builder, including all associated steps. It can be // used to prepare common query builders and use them differently after the clone is made. -func (osq *OfflineSessionQuery) Clone() *OfflineSessionQuery { - if osq == nil { +func (_q *OfflineSessionQuery) Clone() *OfflineSessionQuery { + if _q == nil { return nil } return &OfflineSessionQuery{ - config: osq.config, - limit: osq.limit, - offset: osq.offset, - order: append([]OrderFunc{}, osq.order...), - predicates: append([]predicate.OfflineSession{}, osq.predicates...), + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]offlinesession.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.OfflineSession{}, _q.predicates...), // clone intermediate query. - sql: osq.sql.Clone(), - path: osq.path, - unique: osq.unique, + sql: _q.sql.Clone(), + path: _q.path, } } @@ -261,18 +270,12 @@ func (osq *OfflineSessionQuery) Clone() *OfflineSessionQuery { // GroupBy(offlinesession.FieldUserID). // Aggregate(db.Count()). // Scan(ctx, &v) -// -func (osq *OfflineSessionQuery) GroupBy(field string, fields ...string) *OfflineSessionGroupBy { - grbuild := &OfflineSessionGroupBy{config: osq.config} - grbuild.fields = append([]string{field}, fields...) - grbuild.path = func(ctx context.Context) (prev *sql.Selector, err error) { - if err := osq.prepareQuery(ctx); err != nil { - return nil, err - } - return osq.sqlQuery(ctx), nil - } +func (_q *OfflineSessionQuery) GroupBy(field string, fields ...string) *OfflineSessionGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &OfflineSessionGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields grbuild.label = offlinesession.Label - grbuild.flds, grbuild.scan = &grbuild.fields, grbuild.Scan + grbuild.scan = grbuild.Scan return grbuild } @@ -288,48 +291,62 @@ func (osq *OfflineSessionQuery) GroupBy(field string, fields ...string) *Offline // client.OfflineSession.Query(). // Select(offlinesession.FieldUserID). // Scan(ctx, &v) -// -func (osq *OfflineSessionQuery) Select(fields ...string) *OfflineSessionSelect { - osq.fields = append(osq.fields, fields...) - selbuild := &OfflineSessionSelect{OfflineSessionQuery: osq} - selbuild.label = offlinesession.Label - selbuild.flds, selbuild.scan = &osq.fields, selbuild.Scan - return selbuild +func (_q *OfflineSessionQuery) Select(fields ...string) *OfflineSessionSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &OfflineSessionSelect{OfflineSessionQuery: _q} + sbuild.label = offlinesession.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a OfflineSessionSelect configured with the given aggregations. +func (_q *OfflineSessionQuery) Aggregate(fns ...AggregateFunc) *OfflineSessionSelect { + return _q.Select().Aggregate(fns...) } -func (osq *OfflineSessionQuery) prepareQuery(ctx context.Context) error { - for _, f := range osq.fields { +func (_q *OfflineSessionQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("db: uninitialized interceptor (forgotten import db/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { if !offlinesession.ValidColumn(f) { return &ValidationError{Name: f, err: fmt.Errorf("db: invalid field %q for query", f)} } } - if osq.path != nil { - prev, err := osq.path(ctx) + if _q.path != nil { + prev, err := _q.path(ctx) if err != nil { return err } - osq.sql = prev + _q.sql = prev } return nil } -func (osq *OfflineSessionQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*OfflineSession, error) { +func (_q *OfflineSessionQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*OfflineSession, error) { var ( nodes = []*OfflineSession{} - _spec = osq.querySpec() + _spec = _q.querySpec() ) - _spec.ScanValues = func(columns []string) ([]interface{}, error) { + _spec.ScanValues = func(columns []string) ([]any, error) { return (*OfflineSession).scanValues(nil, columns) } - _spec.Assign = func(columns []string, values []interface{}) error { - node := &OfflineSession{config: osq.config} + _spec.Assign = func(columns []string, values []any) error { + node := &OfflineSession{config: _q.config} nodes = append(nodes, node) return node.assignValues(columns, values) } for i := range hooks { hooks[i](ctx, _spec) } - if err := sqlgraph.QueryNodes(ctx, osq.driver, _spec); err != nil { + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { return nil, err } if len(nodes) == 0 { @@ -338,40 +355,24 @@ func (osq *OfflineSessionQuery) sqlAll(ctx context.Context, hooks ...queryHook) return nodes, nil } -func (osq *OfflineSessionQuery) sqlCount(ctx context.Context) (int, error) { - _spec := osq.querySpec() - _spec.Node.Columns = osq.fields - if len(osq.fields) > 0 { - _spec.Unique = osq.unique != nil && *osq.unique - } - return sqlgraph.CountNodes(ctx, osq.driver, _spec) -} - -func (osq *OfflineSessionQuery) sqlExist(ctx context.Context) (bool, error) { - n, err := osq.sqlCount(ctx) - if err != nil { - return false, fmt.Errorf("db: check existence: %w", err) +func (_q *OfflineSessionQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique } - return n > 0, nil + return sqlgraph.CountNodes(ctx, _q.driver, _spec) } -func (osq *OfflineSessionQuery) querySpec() *sqlgraph.QuerySpec { - _spec := &sqlgraph.QuerySpec{ - Node: &sqlgraph.NodeSpec{ - Table: offlinesession.Table, - Columns: offlinesession.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: offlinesession.FieldID, - }, - }, - From: osq.sql, - Unique: true, - } - if unique := osq.unique; unique != nil { +func (_q *OfflineSessionQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(offlinesession.Table, offlinesession.Columns, sqlgraph.NewFieldSpec(offlinesession.FieldID, field.TypeString)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true } - if fields := osq.fields; len(fields) > 0 { + if fields := _q.ctx.Fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, offlinesession.FieldID) for i := range fields { @@ -380,20 +381,20 @@ func (osq *OfflineSessionQuery) querySpec() *sqlgraph.QuerySpec { } } } - if ps := osq.predicates; len(ps) > 0 { + if ps := _q.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if limit := osq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { _spec.Limit = *limit } - if offset := osq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { _spec.Offset = *offset } - if ps := osq.order; len(ps) > 0 { + if ps := _q.order; len(ps) > 0 { _spec.Order = func(selector *sql.Selector) { for i := range ps { ps[i](selector) @@ -403,33 +404,33 @@ func (osq *OfflineSessionQuery) querySpec() *sqlgraph.QuerySpec { return _spec } -func (osq *OfflineSessionQuery) sqlQuery(ctx context.Context) *sql.Selector { - builder := sql.Dialect(osq.driver.Dialect()) +func (_q *OfflineSessionQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) t1 := builder.Table(offlinesession.Table) - columns := osq.fields + columns := _q.ctx.Fields if len(columns) == 0 { columns = offlinesession.Columns } selector := builder.Select(t1.Columns(columns...)...).From(t1) - if osq.sql != nil { - selector = osq.sql + if _q.sql != nil { + selector = _q.sql selector.Select(selector.Columns(columns...)...) } - if osq.unique != nil && *osq.unique { + if _q.ctx.Unique != nil && *_q.ctx.Unique { selector.Distinct() } - for _, p := range osq.predicates { + for _, p := range _q.predicates { p(selector) } - for _, p := range osq.order { + for _, p := range _q.order { p(selector) } - if offset := osq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { // limit is mandatory for offset clause. We start // with default value, and override it below if needed. selector.Offset(*offset).Limit(math.MaxInt32) } - if limit := osq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { selector.Limit(*limit) } return selector @@ -437,90 +438,88 @@ func (osq *OfflineSessionQuery) sqlQuery(ctx context.Context) *sql.Selector { // OfflineSessionGroupBy is the group-by builder for OfflineSession entities. type OfflineSessionGroupBy struct { - config selector - fields []string - fns []AggregateFunc - // intermediate query (i.e. traversal path). - sql *sql.Selector - path func(context.Context) (*sql.Selector, error) + build *OfflineSessionQuery } // Aggregate adds the given aggregation functions to the group-by query. -func (osgb *OfflineSessionGroupBy) Aggregate(fns ...AggregateFunc) *OfflineSessionGroupBy { - osgb.fns = append(osgb.fns, fns...) - return osgb +func (_g *OfflineSessionGroupBy) Aggregate(fns ...AggregateFunc) *OfflineSessionGroupBy { + _g.fns = append(_g.fns, fns...) + return _g } -// Scan applies the group-by query and scans the result into the given value. -func (osgb *OfflineSessionGroupBy) Scan(ctx context.Context, v interface{}) error { - query, err := osgb.path(ctx) - if err != nil { +// Scan applies the selector query and scans the result into the given value. +func (_g *OfflineSessionGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { return err } - osgb.sql = query - return osgb.sqlScan(ctx, v) + return scanWithInterceptors[*OfflineSessionQuery, *OfflineSessionGroupBy](ctx, _g.build, _g, _g.build.inters, v) } -func (osgb *OfflineSessionGroupBy) sqlScan(ctx context.Context, v interface{}) error { - for _, f := range osgb.fields { - if !offlinesession.ValidColumn(f) { - return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)} +func (_g *OfflineSessionGroupBy) sqlScan(ctx context.Context, root *OfflineSessionQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) } + columns = append(columns, aggregation...) + selector.Select(columns...) } - selector := osgb.sqlQuery() + selector.GroupBy(selector.Columns(*_g.flds...)...) if err := selector.Err(); err != nil { return err } rows := &sql.Rows{} query, args := selector.Query() - if err := osgb.driver.Query(ctx, query, args, rows); err != nil { + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() return sql.ScanSlice(rows, v) } -func (osgb *OfflineSessionGroupBy) sqlQuery() *sql.Selector { - selector := osgb.sql.Select() - aggregation := make([]string, 0, len(osgb.fns)) - for _, fn := range osgb.fns { - aggregation = append(aggregation, fn(selector)) - } - // If no columns were selected in a custom aggregation function, the default - // selection is the fields used for "group-by", and the aggregation functions. - if len(selector.SelectedColumns()) == 0 { - columns := make([]string, 0, len(osgb.fields)+len(osgb.fns)) - for _, f := range osgb.fields { - columns = append(columns, selector.C(f)) - } - columns = append(columns, aggregation...) - selector.Select(columns...) - } - return selector.GroupBy(selector.Columns(osgb.fields...)...) -} - // OfflineSessionSelect is the builder for selecting fields of OfflineSession entities. type OfflineSessionSelect struct { *OfflineSessionQuery selector - // intermediate query (i.e. traversal path). - sql *sql.Selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *OfflineSessionSelect) Aggregate(fns ...AggregateFunc) *OfflineSessionSelect { + _s.fns = append(_s.fns, fns...) + return _s } // Scan applies the selector query and scans the result into the given value. -func (oss *OfflineSessionSelect) Scan(ctx context.Context, v interface{}) error { - if err := oss.prepareQuery(ctx); err != nil { +func (_s *OfflineSessionSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { return err } - oss.sql = oss.OfflineSessionQuery.sqlQuery(ctx) - return oss.sqlScan(ctx, v) + return scanWithInterceptors[*OfflineSessionQuery, *OfflineSessionSelect](ctx, _s.OfflineSessionQuery, _s, _s.inters, v) } -func (oss *OfflineSessionSelect) sqlScan(ctx context.Context, v interface{}) error { +func (_s *OfflineSessionSelect) sqlScan(ctx context.Context, root *OfflineSessionQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } rows := &sql.Rows{} - query, args := oss.sql.Query() - if err := oss.driver.Query(ctx, query, args, rows); err != nil { + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() diff --git a/storage/ent/db/offlinesession_update.go b/storage/ent/db/offlinesession_update.go index f9f1d9cbf1..8eca1b76f0 100644 --- a/storage/ent/db/offlinesession_update.go +++ b/storage/ent/db/offlinesession_update.go @@ -22,87 +22,70 @@ type OfflineSessionUpdate struct { } // Where appends a list predicates to the OfflineSessionUpdate builder. -func (osu *OfflineSessionUpdate) Where(ps ...predicate.OfflineSession) *OfflineSessionUpdate { - osu.mutation.Where(ps...) - return osu +func (_u *OfflineSessionUpdate) Where(ps ...predicate.OfflineSession) *OfflineSessionUpdate { + _u.mutation.Where(ps...) + return _u } // SetUserID sets the "user_id" field. -func (osu *OfflineSessionUpdate) SetUserID(s string) *OfflineSessionUpdate { - osu.mutation.SetUserID(s) - return osu +func (_u *OfflineSessionUpdate) SetUserID(v string) *OfflineSessionUpdate { + _u.mutation.SetUserID(v) + return _u +} + +// SetNillableUserID sets the "user_id" field if the given value is not nil. +func (_u *OfflineSessionUpdate) SetNillableUserID(v *string) *OfflineSessionUpdate { + if v != nil { + _u.SetUserID(*v) + } + return _u } // SetConnID sets the "conn_id" field. -func (osu *OfflineSessionUpdate) SetConnID(s string) *OfflineSessionUpdate { - osu.mutation.SetConnID(s) - return osu +func (_u *OfflineSessionUpdate) SetConnID(v string) *OfflineSessionUpdate { + _u.mutation.SetConnID(v) + return _u +} + +// SetNillableConnID sets the "conn_id" field if the given value is not nil. +func (_u *OfflineSessionUpdate) SetNillableConnID(v *string) *OfflineSessionUpdate { + if v != nil { + _u.SetConnID(*v) + } + return _u } // SetRefresh sets the "refresh" field. -func (osu *OfflineSessionUpdate) SetRefresh(b []byte) *OfflineSessionUpdate { - osu.mutation.SetRefresh(b) - return osu +func (_u *OfflineSessionUpdate) SetRefresh(v []byte) *OfflineSessionUpdate { + _u.mutation.SetRefresh(v) + return _u } // SetConnectorData sets the "connector_data" field. -func (osu *OfflineSessionUpdate) SetConnectorData(b []byte) *OfflineSessionUpdate { - osu.mutation.SetConnectorData(b) - return osu +func (_u *OfflineSessionUpdate) SetConnectorData(v []byte) *OfflineSessionUpdate { + _u.mutation.SetConnectorData(v) + return _u } // ClearConnectorData clears the value of the "connector_data" field. -func (osu *OfflineSessionUpdate) ClearConnectorData() *OfflineSessionUpdate { - osu.mutation.ClearConnectorData() - return osu +func (_u *OfflineSessionUpdate) ClearConnectorData() *OfflineSessionUpdate { + _u.mutation.ClearConnectorData() + return _u } // Mutation returns the OfflineSessionMutation object of the builder. -func (osu *OfflineSessionUpdate) Mutation() *OfflineSessionMutation { - return osu.mutation +func (_u *OfflineSessionUpdate) Mutation() *OfflineSessionMutation { + return _u.mutation } // Save executes the query and returns the number of nodes affected by the update operation. -func (osu *OfflineSessionUpdate) Save(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(osu.hooks) == 0 { - if err = osu.check(); err != nil { - return 0, err - } - affected, err = osu.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*OfflineSessionMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = osu.check(); err != nil { - return 0, err - } - osu.mutation = mutation - affected, err = osu.sqlSave(ctx) - mutation.done = true - return affected, err - }) - for i := len(osu.hooks) - 1; i >= 0; i-- { - if osu.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = osu.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, osu.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_u *OfflineSessionUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (osu *OfflineSessionUpdate) SaveX(ctx context.Context) int { - affected, err := osu.Save(ctx) +func (_u *OfflineSessionUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) if err != nil { panic(err) } @@ -110,26 +93,26 @@ func (osu *OfflineSessionUpdate) SaveX(ctx context.Context) int { } // Exec executes the query. -func (osu *OfflineSessionUpdate) Exec(ctx context.Context) error { - _, err := osu.Save(ctx) +func (_u *OfflineSessionUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (osu *OfflineSessionUpdate) ExecX(ctx context.Context) { - if err := osu.Exec(ctx); err != nil { +func (_u *OfflineSessionUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (osu *OfflineSessionUpdate) check() error { - if v, ok := osu.mutation.UserID(); ok { +func (_u *OfflineSessionUpdate) check() error { + if v, ok := _u.mutation.UserID(); ok { if err := offlinesession.UserIDValidator(v); err != nil { return &ValidationError{Name: "user_id", err: fmt.Errorf(`db: validator failed for field "OfflineSession.user_id": %w`, err)} } } - if v, ok := osu.mutation.ConnID(); ok { + if v, ok := _u.mutation.ConnID(); ok { if err := offlinesession.ConnIDValidator(v); err != nil { return &ValidationError{Name: "conn_id", err: fmt.Errorf(`db: validator failed for field "OfflineSession.conn_id": %w`, err)} } @@ -137,59 +120,34 @@ func (osu *OfflineSessionUpdate) check() error { return nil } -func (osu *OfflineSessionUpdate) sqlSave(ctx context.Context) (n int, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: offlinesession.Table, - Columns: offlinesession.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: offlinesession.FieldID, - }, - }, +func (_u *OfflineSessionUpdate) sqlSave(ctx context.Context) (_node int, err error) { + if err := _u.check(); err != nil { + return _node, err } - if ps := osu.mutation.predicates; len(ps) > 0 { + _spec := sqlgraph.NewUpdateSpec(offlinesession.Table, offlinesession.Columns, sqlgraph.NewFieldSpec(offlinesession.FieldID, field.TypeString)) + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := osu.mutation.UserID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: offlinesession.FieldUserID, - }) + if value, ok := _u.mutation.UserID(); ok { + _spec.SetField(offlinesession.FieldUserID, field.TypeString, value) } - if value, ok := osu.mutation.ConnID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: offlinesession.FieldConnID, - }) + if value, ok := _u.mutation.ConnID(); ok { + _spec.SetField(offlinesession.FieldConnID, field.TypeString, value) } - if value, ok := osu.mutation.Refresh(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: offlinesession.FieldRefresh, - }) + if value, ok := _u.mutation.Refresh(); ok { + _spec.SetField(offlinesession.FieldRefresh, field.TypeBytes, value) } - if value, ok := osu.mutation.ConnectorData(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: offlinesession.FieldConnectorData, - }) + if value, ok := _u.mutation.ConnectorData(); ok { + _spec.SetField(offlinesession.FieldConnectorData, field.TypeBytes, value) } - if osu.mutation.ConnectorDataCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Column: offlinesession.FieldConnectorData, - }) + if _u.mutation.ConnectorDataCleared() { + _spec.ClearField(offlinesession.FieldConnectorData, field.TypeBytes) } - if n, err = sqlgraph.UpdateNodes(ctx, osu.driver, _spec); err != nil { + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{offlinesession.Label} } else if sqlgraph.IsConstraintError(err) { @@ -197,7 +155,8 @@ func (osu *OfflineSessionUpdate) sqlSave(ctx context.Context) (n int, err error) } return 0, err } - return n, nil + _u.mutation.done = true + return _node, nil } // OfflineSessionUpdateOne is the builder for updating a single OfflineSession entity. @@ -209,94 +168,77 @@ type OfflineSessionUpdateOne struct { } // SetUserID sets the "user_id" field. -func (osuo *OfflineSessionUpdateOne) SetUserID(s string) *OfflineSessionUpdateOne { - osuo.mutation.SetUserID(s) - return osuo +func (_u *OfflineSessionUpdateOne) SetUserID(v string) *OfflineSessionUpdateOne { + _u.mutation.SetUserID(v) + return _u +} + +// SetNillableUserID sets the "user_id" field if the given value is not nil. +func (_u *OfflineSessionUpdateOne) SetNillableUserID(v *string) *OfflineSessionUpdateOne { + if v != nil { + _u.SetUserID(*v) + } + return _u } // SetConnID sets the "conn_id" field. -func (osuo *OfflineSessionUpdateOne) SetConnID(s string) *OfflineSessionUpdateOne { - osuo.mutation.SetConnID(s) - return osuo +func (_u *OfflineSessionUpdateOne) SetConnID(v string) *OfflineSessionUpdateOne { + _u.mutation.SetConnID(v) + return _u +} + +// SetNillableConnID sets the "conn_id" field if the given value is not nil. +func (_u *OfflineSessionUpdateOne) SetNillableConnID(v *string) *OfflineSessionUpdateOne { + if v != nil { + _u.SetConnID(*v) + } + return _u } // SetRefresh sets the "refresh" field. -func (osuo *OfflineSessionUpdateOne) SetRefresh(b []byte) *OfflineSessionUpdateOne { - osuo.mutation.SetRefresh(b) - return osuo +func (_u *OfflineSessionUpdateOne) SetRefresh(v []byte) *OfflineSessionUpdateOne { + _u.mutation.SetRefresh(v) + return _u } // SetConnectorData sets the "connector_data" field. -func (osuo *OfflineSessionUpdateOne) SetConnectorData(b []byte) *OfflineSessionUpdateOne { - osuo.mutation.SetConnectorData(b) - return osuo +func (_u *OfflineSessionUpdateOne) SetConnectorData(v []byte) *OfflineSessionUpdateOne { + _u.mutation.SetConnectorData(v) + return _u } // ClearConnectorData clears the value of the "connector_data" field. -func (osuo *OfflineSessionUpdateOne) ClearConnectorData() *OfflineSessionUpdateOne { - osuo.mutation.ClearConnectorData() - return osuo +func (_u *OfflineSessionUpdateOne) ClearConnectorData() *OfflineSessionUpdateOne { + _u.mutation.ClearConnectorData() + return _u } // Mutation returns the OfflineSessionMutation object of the builder. -func (osuo *OfflineSessionUpdateOne) Mutation() *OfflineSessionMutation { - return osuo.mutation +func (_u *OfflineSessionUpdateOne) Mutation() *OfflineSessionMutation { + return _u.mutation +} + +// Where appends a list predicates to the OfflineSessionUpdate builder. +func (_u *OfflineSessionUpdateOne) Where(ps ...predicate.OfflineSession) *OfflineSessionUpdateOne { + _u.mutation.Where(ps...) + return _u } // Select allows selecting one or more fields (columns) of the returned entity. // The default is selecting all fields defined in the entity schema. -func (osuo *OfflineSessionUpdateOne) Select(field string, fields ...string) *OfflineSessionUpdateOne { - osuo.fields = append([]string{field}, fields...) - return osuo +func (_u *OfflineSessionUpdateOne) Select(field string, fields ...string) *OfflineSessionUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u } // Save executes the query and returns the updated OfflineSession entity. -func (osuo *OfflineSessionUpdateOne) Save(ctx context.Context) (*OfflineSession, error) { - var ( - err error - node *OfflineSession - ) - if len(osuo.hooks) == 0 { - if err = osuo.check(); err != nil { - return nil, err - } - node, err = osuo.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*OfflineSessionMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = osuo.check(); err != nil { - return nil, err - } - osuo.mutation = mutation - node, err = osuo.sqlSave(ctx) - mutation.done = true - return node, err - }) - for i := len(osuo.hooks) - 1; i >= 0; i-- { - if osuo.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = osuo.hooks[i](mut) - } - v, err := mut.Mutate(ctx, osuo.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*OfflineSession) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from OfflineSessionMutation", v) - } - node = nv - } - return node, err +func (_u *OfflineSessionUpdateOne) Save(ctx context.Context) (*OfflineSession, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (osuo *OfflineSessionUpdateOne) SaveX(ctx context.Context) *OfflineSession { - node, err := osuo.Save(ctx) +func (_u *OfflineSessionUpdateOne) SaveX(ctx context.Context) *OfflineSession { + node, err := _u.Save(ctx) if err != nil { panic(err) } @@ -304,26 +246,26 @@ func (osuo *OfflineSessionUpdateOne) SaveX(ctx context.Context) *OfflineSession } // Exec executes the query on the entity. -func (osuo *OfflineSessionUpdateOne) Exec(ctx context.Context) error { - _, err := osuo.Save(ctx) +func (_u *OfflineSessionUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (osuo *OfflineSessionUpdateOne) ExecX(ctx context.Context) { - if err := osuo.Exec(ctx); err != nil { +func (_u *OfflineSessionUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (osuo *OfflineSessionUpdateOne) check() error { - if v, ok := osuo.mutation.UserID(); ok { +func (_u *OfflineSessionUpdateOne) check() error { + if v, ok := _u.mutation.UserID(); ok { if err := offlinesession.UserIDValidator(v); err != nil { return &ValidationError{Name: "user_id", err: fmt.Errorf(`db: validator failed for field "OfflineSession.user_id": %w`, err)} } } - if v, ok := osuo.mutation.ConnID(); ok { + if v, ok := _u.mutation.ConnID(); ok { if err := offlinesession.ConnIDValidator(v); err != nil { return &ValidationError{Name: "conn_id", err: fmt.Errorf(`db: validator failed for field "OfflineSession.conn_id": %w`, err)} } @@ -331,23 +273,17 @@ func (osuo *OfflineSessionUpdateOne) check() error { return nil } -func (osuo *OfflineSessionUpdateOne) sqlSave(ctx context.Context) (_node *OfflineSession, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: offlinesession.Table, - Columns: offlinesession.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: offlinesession.FieldID, - }, - }, +func (_u *OfflineSessionUpdateOne) sqlSave(ctx context.Context) (_node *OfflineSession, err error) { + if err := _u.check(); err != nil { + return _node, err } - id, ok := osuo.mutation.ID() + _spec := sqlgraph.NewUpdateSpec(offlinesession.Table, offlinesession.Columns, sqlgraph.NewFieldSpec(offlinesession.FieldID, field.TypeString)) + id, ok := _u.mutation.ID() if !ok { return nil, &ValidationError{Name: "id", err: errors.New(`db: missing "OfflineSession.id" for update`)} } _spec.Node.ID.Value = id - if fields := osuo.fields; len(fields) > 0 { + if fields := _u.fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, offlinesession.FieldID) for _, f := range fields { @@ -359,51 +295,32 @@ func (osuo *OfflineSessionUpdateOne) sqlSave(ctx context.Context) (_node *Offlin } } } - if ps := osuo.mutation.predicates; len(ps) > 0 { + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := osuo.mutation.UserID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: offlinesession.FieldUserID, - }) + if value, ok := _u.mutation.UserID(); ok { + _spec.SetField(offlinesession.FieldUserID, field.TypeString, value) } - if value, ok := osuo.mutation.ConnID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: offlinesession.FieldConnID, - }) + if value, ok := _u.mutation.ConnID(); ok { + _spec.SetField(offlinesession.FieldConnID, field.TypeString, value) } - if value, ok := osuo.mutation.Refresh(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: offlinesession.FieldRefresh, - }) + if value, ok := _u.mutation.Refresh(); ok { + _spec.SetField(offlinesession.FieldRefresh, field.TypeBytes, value) } - if value, ok := osuo.mutation.ConnectorData(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: offlinesession.FieldConnectorData, - }) + if value, ok := _u.mutation.ConnectorData(); ok { + _spec.SetField(offlinesession.FieldConnectorData, field.TypeBytes, value) } - if osuo.mutation.ConnectorDataCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Column: offlinesession.FieldConnectorData, - }) + if _u.mutation.ConnectorDataCleared() { + _spec.ClearField(offlinesession.FieldConnectorData, field.TypeBytes) } - _node = &OfflineSession{config: osuo.config} + _node = &OfflineSession{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues - if err = sqlgraph.UpdateNode(ctx, osuo.driver, _spec); err != nil { + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{offlinesession.Label} } else if sqlgraph.IsConstraintError(err) { @@ -411,5 +328,6 @@ func (osuo *OfflineSessionUpdateOne) sqlSave(ctx context.Context) (_node *Offlin } return nil, err } + _u.mutation.done = true return _node, nil } diff --git a/storage/ent/db/password.go b/storage/ent/db/password.go index cd30ec54ed..e2ceec8f22 100644 --- a/storage/ent/db/password.go +++ b/storage/ent/db/password.go @@ -6,6 +6,7 @@ import ( "fmt" "strings" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/dexidp/dex/storage/ent/db/password" ) @@ -22,12 +23,13 @@ type Password struct { // Username holds the value of the "username" field. Username string `json:"username,omitempty"` // UserID holds the value of the "user_id" field. - UserID string `json:"user_id,omitempty"` + UserID string `json:"user_id,omitempty"` + selectValues sql.SelectValues } // scanValues returns the types for scanning values from sql.Rows. -func (*Password) scanValues(columns []string) ([]interface{}, error) { - values := make([]interface{}, len(columns)) +func (*Password) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) for i := range columns { switch columns[i] { case password.FieldHash: @@ -37,7 +39,7 @@ func (*Password) scanValues(columns []string) ([]interface{}, error) { case password.FieldEmail, password.FieldUsername, password.FieldUserID: values[i] = new(sql.NullString) default: - return nil, fmt.Errorf("unexpected column %q for type Password", columns[i]) + values[i] = new(sql.UnknownType) } } return values, nil @@ -45,7 +47,7 @@ func (*Password) scanValues(columns []string) ([]interface{}, error) { // assignValues assigns the values that were returned from sql.Rows (after scanning) // to the Password fields. -func (pa *Password) assignValues(columns []string, values []interface{}) error { +func (_m *Password) assignValues(columns []string, values []any) error { if m, n := len(values), len(columns); m < n { return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) } @@ -56,79 +58,81 @@ func (pa *Password) assignValues(columns []string, values []interface{}) error { if !ok { return fmt.Errorf("unexpected type %T for field id", value) } - pa.ID = int(value.Int64) + _m.ID = int(value.Int64) case password.FieldEmail: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field email", values[i]) } else if value.Valid { - pa.Email = value.String + _m.Email = value.String } case password.FieldHash: if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field hash", values[i]) } else if value != nil { - pa.Hash = *value + _m.Hash = *value } case password.FieldUsername: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field username", values[i]) } else if value.Valid { - pa.Username = value.String + _m.Username = value.String } case password.FieldUserID: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field user_id", values[i]) } else if value.Valid { - pa.UserID = value.String + _m.UserID = value.String } + default: + _m.selectValues.Set(columns[i], values[i]) } } return nil } +// Value returns the ent.Value that was dynamically selected and assigned to the Password. +// This includes values selected through modifiers, order, etc. +func (_m *Password) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + // Update returns a builder for updating this Password. // Note that you need to call Password.Unwrap() before calling this method if this Password // was returned from a transaction, and the transaction was committed or rolled back. -func (pa *Password) Update() *PasswordUpdateOne { - return (&PasswordClient{config: pa.config}).UpdateOne(pa) +func (_m *Password) Update() *PasswordUpdateOne { + return NewPasswordClient(_m.config).UpdateOne(_m) } // Unwrap unwraps the Password entity that was returned from a transaction after it was closed, // so that all future queries will be executed through the driver which created the transaction. -func (pa *Password) Unwrap() *Password { - _tx, ok := pa.config.driver.(*txDriver) +func (_m *Password) Unwrap() *Password { + _tx, ok := _m.config.driver.(*txDriver) if !ok { panic("db: Password is not a transactional entity") } - pa.config.driver = _tx.drv - return pa + _m.config.driver = _tx.drv + return _m } // String implements the fmt.Stringer. -func (pa *Password) String() string { +func (_m *Password) String() string { var builder strings.Builder builder.WriteString("Password(") - builder.WriteString(fmt.Sprintf("id=%v, ", pa.ID)) + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) builder.WriteString("email=") - builder.WriteString(pa.Email) + builder.WriteString(_m.Email) builder.WriteString(", ") builder.WriteString("hash=") - builder.WriteString(fmt.Sprintf("%v", pa.Hash)) + builder.WriteString(fmt.Sprintf("%v", _m.Hash)) builder.WriteString(", ") builder.WriteString("username=") - builder.WriteString(pa.Username) + builder.WriteString(_m.Username) builder.WriteString(", ") builder.WriteString("user_id=") - builder.WriteString(pa.UserID) + builder.WriteString(_m.UserID) builder.WriteByte(')') return builder.String() } // Passwords is a parsable slice of Password. type Passwords []*Password - -func (pa Passwords) config(cfg config) { - for _i := range pa { - pa[_i].config = cfg - } -} diff --git a/storage/ent/db/password/password.go b/storage/ent/db/password/password.go index 34fcac69b8..37ab1e49a0 100644 --- a/storage/ent/db/password/password.go +++ b/storage/ent/db/password/password.go @@ -2,6 +2,10 @@ package password +import ( + "entgo.io/ent/dialect/sql" +) + const ( // Label holds the string label denoting the password type in the database. Label = "password" @@ -46,3 +50,26 @@ var ( // UserIDValidator is a validator for the "user_id" field. It is called by the builders before save. UserIDValidator func(string) error ) + +// OrderOption defines the ordering options for the Password queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByEmail orders the results by the email field. +func ByEmail(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldEmail, opts...).ToFunc() +} + +// ByUsername orders the results by the username field. +func ByUsername(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUsername, opts...).ToFunc() +} + +// ByUserID orders the results by the user_id field. +func ByUserID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldUserID, opts...).ToFunc() +} diff --git a/storage/ent/db/password/where.go b/storage/ent/db/password/where.go index e33c134f2e..105a8d4fc2 100644 --- a/storage/ent/db/password/where.go +++ b/storage/ent/db/password/where.go @@ -9,492 +9,315 @@ import ( // ID filters vertices based on their ID field. func ID(id int) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.Password(sql.FieldEQ(FieldID, id)) } // IDEQ applies the EQ predicate on the ID field. func IDEQ(id int) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.Password(sql.FieldEQ(FieldID, id)) } // IDNEQ applies the NEQ predicate on the ID field. func IDNEQ(id int) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldID), id)) - }) + return predicate.Password(sql.FieldNEQ(FieldID, id)) } // IDIn applies the In predicate on the ID field. func IDIn(ids ...int) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.In(s.C(FieldID), v...)) - }) + return predicate.Password(sql.FieldIn(FieldID, ids...)) } // IDNotIn applies the NotIn predicate on the ID field. func IDNotIn(ids ...int) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.NotIn(s.C(FieldID), v...)) - }) + return predicate.Password(sql.FieldNotIn(FieldID, ids...)) } // IDGT applies the GT predicate on the ID field. func IDGT(id int) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldID), id)) - }) + return predicate.Password(sql.FieldGT(FieldID, id)) } // IDGTE applies the GTE predicate on the ID field. func IDGTE(id int) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldID), id)) - }) + return predicate.Password(sql.FieldGTE(FieldID, id)) } // IDLT applies the LT predicate on the ID field. func IDLT(id int) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldID), id)) - }) + return predicate.Password(sql.FieldLT(FieldID, id)) } // IDLTE applies the LTE predicate on the ID field. func IDLTE(id int) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldID), id)) - }) + return predicate.Password(sql.FieldLTE(FieldID, id)) } // Email applies equality check predicate on the "email" field. It's identical to EmailEQ. func Email(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldEmail), v)) - }) + return predicate.Password(sql.FieldEQ(FieldEmail, v)) } // Hash applies equality check predicate on the "hash" field. It's identical to HashEQ. func Hash(v []byte) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldHash), v)) - }) + return predicate.Password(sql.FieldEQ(FieldHash, v)) } // Username applies equality check predicate on the "username" field. It's identical to UsernameEQ. func Username(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldUsername), v)) - }) + return predicate.Password(sql.FieldEQ(FieldUsername, v)) } // UserID applies equality check predicate on the "user_id" field. It's identical to UserIDEQ. func UserID(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldUserID), v)) - }) + return predicate.Password(sql.FieldEQ(FieldUserID, v)) } // EmailEQ applies the EQ predicate on the "email" field. func EmailEQ(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldEmail), v)) - }) + return predicate.Password(sql.FieldEQ(FieldEmail, v)) } // EmailNEQ applies the NEQ predicate on the "email" field. func EmailNEQ(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldEmail), v)) - }) + return predicate.Password(sql.FieldNEQ(FieldEmail, v)) } // EmailIn applies the In predicate on the "email" field. func EmailIn(vs ...string) predicate.Password { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldEmail), v...)) - }) + return predicate.Password(sql.FieldIn(FieldEmail, vs...)) } // EmailNotIn applies the NotIn predicate on the "email" field. func EmailNotIn(vs ...string) predicate.Password { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldEmail), v...)) - }) + return predicate.Password(sql.FieldNotIn(FieldEmail, vs...)) } // EmailGT applies the GT predicate on the "email" field. func EmailGT(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldEmail), v)) - }) + return predicate.Password(sql.FieldGT(FieldEmail, v)) } // EmailGTE applies the GTE predicate on the "email" field. func EmailGTE(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldEmail), v)) - }) + return predicate.Password(sql.FieldGTE(FieldEmail, v)) } // EmailLT applies the LT predicate on the "email" field. func EmailLT(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldEmail), v)) - }) + return predicate.Password(sql.FieldLT(FieldEmail, v)) } // EmailLTE applies the LTE predicate on the "email" field. func EmailLTE(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldEmail), v)) - }) + return predicate.Password(sql.FieldLTE(FieldEmail, v)) } // EmailContains applies the Contains predicate on the "email" field. func EmailContains(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldEmail), v)) - }) + return predicate.Password(sql.FieldContains(FieldEmail, v)) } // EmailHasPrefix applies the HasPrefix predicate on the "email" field. func EmailHasPrefix(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldEmail), v)) - }) + return predicate.Password(sql.FieldHasPrefix(FieldEmail, v)) } // EmailHasSuffix applies the HasSuffix predicate on the "email" field. func EmailHasSuffix(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldEmail), v)) - }) + return predicate.Password(sql.FieldHasSuffix(FieldEmail, v)) } // EmailEqualFold applies the EqualFold predicate on the "email" field. func EmailEqualFold(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldEmail), v)) - }) + return predicate.Password(sql.FieldEqualFold(FieldEmail, v)) } // EmailContainsFold applies the ContainsFold predicate on the "email" field. func EmailContainsFold(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldEmail), v)) - }) + return predicate.Password(sql.FieldContainsFold(FieldEmail, v)) } // HashEQ applies the EQ predicate on the "hash" field. func HashEQ(v []byte) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldHash), v)) - }) + return predicate.Password(sql.FieldEQ(FieldHash, v)) } // HashNEQ applies the NEQ predicate on the "hash" field. func HashNEQ(v []byte) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldHash), v)) - }) + return predicate.Password(sql.FieldNEQ(FieldHash, v)) } // HashIn applies the In predicate on the "hash" field. func HashIn(vs ...[]byte) predicate.Password { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldHash), v...)) - }) + return predicate.Password(sql.FieldIn(FieldHash, vs...)) } // HashNotIn applies the NotIn predicate on the "hash" field. func HashNotIn(vs ...[]byte) predicate.Password { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldHash), v...)) - }) + return predicate.Password(sql.FieldNotIn(FieldHash, vs...)) } // HashGT applies the GT predicate on the "hash" field. func HashGT(v []byte) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldHash), v)) - }) + return predicate.Password(sql.FieldGT(FieldHash, v)) } // HashGTE applies the GTE predicate on the "hash" field. func HashGTE(v []byte) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldHash), v)) - }) + return predicate.Password(sql.FieldGTE(FieldHash, v)) } // HashLT applies the LT predicate on the "hash" field. func HashLT(v []byte) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldHash), v)) - }) + return predicate.Password(sql.FieldLT(FieldHash, v)) } // HashLTE applies the LTE predicate on the "hash" field. func HashLTE(v []byte) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldHash), v)) - }) + return predicate.Password(sql.FieldLTE(FieldHash, v)) } // UsernameEQ applies the EQ predicate on the "username" field. func UsernameEQ(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldUsername), v)) - }) + return predicate.Password(sql.FieldEQ(FieldUsername, v)) } // UsernameNEQ applies the NEQ predicate on the "username" field. func UsernameNEQ(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldUsername), v)) - }) + return predicate.Password(sql.FieldNEQ(FieldUsername, v)) } // UsernameIn applies the In predicate on the "username" field. func UsernameIn(vs ...string) predicate.Password { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldUsername), v...)) - }) + return predicate.Password(sql.FieldIn(FieldUsername, vs...)) } // UsernameNotIn applies the NotIn predicate on the "username" field. func UsernameNotIn(vs ...string) predicate.Password { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldUsername), v...)) - }) + return predicate.Password(sql.FieldNotIn(FieldUsername, vs...)) } // UsernameGT applies the GT predicate on the "username" field. func UsernameGT(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldUsername), v)) - }) + return predicate.Password(sql.FieldGT(FieldUsername, v)) } // UsernameGTE applies the GTE predicate on the "username" field. func UsernameGTE(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldUsername), v)) - }) + return predicate.Password(sql.FieldGTE(FieldUsername, v)) } // UsernameLT applies the LT predicate on the "username" field. func UsernameLT(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldUsername), v)) - }) + return predicate.Password(sql.FieldLT(FieldUsername, v)) } // UsernameLTE applies the LTE predicate on the "username" field. func UsernameLTE(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldUsername), v)) - }) + return predicate.Password(sql.FieldLTE(FieldUsername, v)) } // UsernameContains applies the Contains predicate on the "username" field. func UsernameContains(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldUsername), v)) - }) + return predicate.Password(sql.FieldContains(FieldUsername, v)) } // UsernameHasPrefix applies the HasPrefix predicate on the "username" field. func UsernameHasPrefix(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldUsername), v)) - }) + return predicate.Password(sql.FieldHasPrefix(FieldUsername, v)) } // UsernameHasSuffix applies the HasSuffix predicate on the "username" field. func UsernameHasSuffix(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldUsername), v)) - }) + return predicate.Password(sql.FieldHasSuffix(FieldUsername, v)) } // UsernameEqualFold applies the EqualFold predicate on the "username" field. func UsernameEqualFold(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldUsername), v)) - }) + return predicate.Password(sql.FieldEqualFold(FieldUsername, v)) } // UsernameContainsFold applies the ContainsFold predicate on the "username" field. func UsernameContainsFold(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldUsername), v)) - }) + return predicate.Password(sql.FieldContainsFold(FieldUsername, v)) } // UserIDEQ applies the EQ predicate on the "user_id" field. func UserIDEQ(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldUserID), v)) - }) + return predicate.Password(sql.FieldEQ(FieldUserID, v)) } // UserIDNEQ applies the NEQ predicate on the "user_id" field. func UserIDNEQ(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldUserID), v)) - }) + return predicate.Password(sql.FieldNEQ(FieldUserID, v)) } // UserIDIn applies the In predicate on the "user_id" field. func UserIDIn(vs ...string) predicate.Password { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldUserID), v...)) - }) + return predicate.Password(sql.FieldIn(FieldUserID, vs...)) } // UserIDNotIn applies the NotIn predicate on the "user_id" field. func UserIDNotIn(vs ...string) predicate.Password { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldUserID), v...)) - }) + return predicate.Password(sql.FieldNotIn(FieldUserID, vs...)) } // UserIDGT applies the GT predicate on the "user_id" field. func UserIDGT(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldUserID), v)) - }) + return predicate.Password(sql.FieldGT(FieldUserID, v)) } // UserIDGTE applies the GTE predicate on the "user_id" field. func UserIDGTE(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldUserID), v)) - }) + return predicate.Password(sql.FieldGTE(FieldUserID, v)) } // UserIDLT applies the LT predicate on the "user_id" field. func UserIDLT(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldUserID), v)) - }) + return predicate.Password(sql.FieldLT(FieldUserID, v)) } // UserIDLTE applies the LTE predicate on the "user_id" field. func UserIDLTE(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldUserID), v)) - }) + return predicate.Password(sql.FieldLTE(FieldUserID, v)) } // UserIDContains applies the Contains predicate on the "user_id" field. func UserIDContains(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldUserID), v)) - }) + return predicate.Password(sql.FieldContains(FieldUserID, v)) } // UserIDHasPrefix applies the HasPrefix predicate on the "user_id" field. func UserIDHasPrefix(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldUserID), v)) - }) + return predicate.Password(sql.FieldHasPrefix(FieldUserID, v)) } // UserIDHasSuffix applies the HasSuffix predicate on the "user_id" field. func UserIDHasSuffix(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldUserID), v)) - }) + return predicate.Password(sql.FieldHasSuffix(FieldUserID, v)) } // UserIDEqualFold applies the EqualFold predicate on the "user_id" field. func UserIDEqualFold(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldUserID), v)) - }) + return predicate.Password(sql.FieldEqualFold(FieldUserID, v)) } // UserIDContainsFold applies the ContainsFold predicate on the "user_id" field. func UserIDContainsFold(v string) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldUserID), v)) - }) + return predicate.Password(sql.FieldContainsFold(FieldUserID, v)) } // And groups predicates with the AND operator between them. func And(predicates ...predicate.Password) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for _, p := range predicates { - p(s1) - } - s.Where(s1.P()) - }) + return predicate.Password(sql.AndPredicates(predicates...)) } // Or groups predicates with the OR operator between them. func Or(predicates ...predicate.Password) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for i, p := range predicates { - if i > 0 { - s1.Or() - } - p(s1) - } - s.Where(s1.P()) - }) + return predicate.Password(sql.OrPredicates(predicates...)) } // Not applies the not operator on the given predicate. func Not(p predicate.Password) predicate.Password { - return predicate.Password(func(s *sql.Selector) { - p(s.Not()) - }) + return predicate.Password(sql.NotPredicates(p)) } diff --git a/storage/ent/db/password_create.go b/storage/ent/db/password_create.go index 277a5c8321..4d68de8f38 100644 --- a/storage/ent/db/password_create.go +++ b/storage/ent/db/password_create.go @@ -20,84 +20,42 @@ type PasswordCreate struct { } // SetEmail sets the "email" field. -func (pc *PasswordCreate) SetEmail(s string) *PasswordCreate { - pc.mutation.SetEmail(s) - return pc +func (_c *PasswordCreate) SetEmail(v string) *PasswordCreate { + _c.mutation.SetEmail(v) + return _c } // SetHash sets the "hash" field. -func (pc *PasswordCreate) SetHash(b []byte) *PasswordCreate { - pc.mutation.SetHash(b) - return pc +func (_c *PasswordCreate) SetHash(v []byte) *PasswordCreate { + _c.mutation.SetHash(v) + return _c } // SetUsername sets the "username" field. -func (pc *PasswordCreate) SetUsername(s string) *PasswordCreate { - pc.mutation.SetUsername(s) - return pc +func (_c *PasswordCreate) SetUsername(v string) *PasswordCreate { + _c.mutation.SetUsername(v) + return _c } // SetUserID sets the "user_id" field. -func (pc *PasswordCreate) SetUserID(s string) *PasswordCreate { - pc.mutation.SetUserID(s) - return pc +func (_c *PasswordCreate) SetUserID(v string) *PasswordCreate { + _c.mutation.SetUserID(v) + return _c } // Mutation returns the PasswordMutation object of the builder. -func (pc *PasswordCreate) Mutation() *PasswordMutation { - return pc.mutation +func (_c *PasswordCreate) Mutation() *PasswordMutation { + return _c.mutation } // Save creates the Password in the database. -func (pc *PasswordCreate) Save(ctx context.Context) (*Password, error) { - var ( - err error - node *Password - ) - if len(pc.hooks) == 0 { - if err = pc.check(); err != nil { - return nil, err - } - node, err = pc.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*PasswordMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = pc.check(); err != nil { - return nil, err - } - pc.mutation = mutation - if node, err = pc.sqlSave(ctx); err != nil { - return nil, err - } - mutation.id = &node.ID - mutation.done = true - return node, err - }) - for i := len(pc.hooks) - 1; i >= 0; i-- { - if pc.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = pc.hooks[i](mut) - } - v, err := mut.Mutate(ctx, pc.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*Password) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from PasswordMutation", v) - } - node = nv - } - return node, err +func (_c *PasswordCreate) Save(ctx context.Context) (*Password, error) { + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) } // SaveX calls Save and panics if Save returns an error. -func (pc *PasswordCreate) SaveX(ctx context.Context) *Password { - v, err := pc.Save(ctx) +func (_c *PasswordCreate) SaveX(ctx context.Context) *Password { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -105,43 +63,43 @@ func (pc *PasswordCreate) SaveX(ctx context.Context) *Password { } // Exec executes the query. -func (pc *PasswordCreate) Exec(ctx context.Context) error { - _, err := pc.Save(ctx) +func (_c *PasswordCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (pc *PasswordCreate) ExecX(ctx context.Context) { - if err := pc.Exec(ctx); err != nil { +func (_c *PasswordCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (pc *PasswordCreate) check() error { - if _, ok := pc.mutation.Email(); !ok { +func (_c *PasswordCreate) check() error { + if _, ok := _c.mutation.Email(); !ok { return &ValidationError{Name: "email", err: errors.New(`db: missing required field "Password.email"`)} } - if v, ok := pc.mutation.Email(); ok { + if v, ok := _c.mutation.Email(); ok { if err := password.EmailValidator(v); err != nil { return &ValidationError{Name: "email", err: fmt.Errorf(`db: validator failed for field "Password.email": %w`, err)} } } - if _, ok := pc.mutation.Hash(); !ok { + if _, ok := _c.mutation.Hash(); !ok { return &ValidationError{Name: "hash", err: errors.New(`db: missing required field "Password.hash"`)} } - if _, ok := pc.mutation.Username(); !ok { + if _, ok := _c.mutation.Username(); !ok { return &ValidationError{Name: "username", err: errors.New(`db: missing required field "Password.username"`)} } - if v, ok := pc.mutation.Username(); ok { + if v, ok := _c.mutation.Username(); ok { if err := password.UsernameValidator(v); err != nil { return &ValidationError{Name: "username", err: fmt.Errorf(`db: validator failed for field "Password.username": %w`, err)} } } - if _, ok := pc.mutation.UserID(); !ok { + if _, ok := _c.mutation.UserID(); !ok { return &ValidationError{Name: "user_id", err: errors.New(`db: missing required field "Password.user_id"`)} } - if v, ok := pc.mutation.UserID(); ok { + if v, ok := _c.mutation.UserID(); ok { if err := password.UserIDValidator(v); err != nil { return &ValidationError{Name: "user_id", err: fmt.Errorf(`db: validator failed for field "Password.user_id": %w`, err)} } @@ -149,9 +107,12 @@ func (pc *PasswordCreate) check() error { return nil } -func (pc *PasswordCreate) sqlSave(ctx context.Context) (*Password, error) { - _node, _spec := pc.createSpec() - if err := sqlgraph.CreateNode(ctx, pc.driver, _spec); err != nil { +func (_c *PasswordCreate) sqlSave(ctx context.Context) (*Password, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -159,50 +120,30 @@ func (pc *PasswordCreate) sqlSave(ctx context.Context) (*Password, error) { } id := _spec.ID.Value.(int64) _node.ID = int(id) + _c.mutation.id = &_node.ID + _c.mutation.done = true return _node, nil } -func (pc *PasswordCreate) createSpec() (*Password, *sqlgraph.CreateSpec) { +func (_c *PasswordCreate) createSpec() (*Password, *sqlgraph.CreateSpec) { var ( - _node = &Password{config: pc.config} - _spec = &sqlgraph.CreateSpec{ - Table: password.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: password.FieldID, - }, - } + _node = &Password{config: _c.config} + _spec = sqlgraph.NewCreateSpec(password.Table, sqlgraph.NewFieldSpec(password.FieldID, field.TypeInt)) ) - if value, ok := pc.mutation.Email(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: password.FieldEmail, - }) + if value, ok := _c.mutation.Email(); ok { + _spec.SetField(password.FieldEmail, field.TypeString, value) _node.Email = value } - if value, ok := pc.mutation.Hash(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: password.FieldHash, - }) + if value, ok := _c.mutation.Hash(); ok { + _spec.SetField(password.FieldHash, field.TypeBytes, value) _node.Hash = value } - if value, ok := pc.mutation.Username(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: password.FieldUsername, - }) + if value, ok := _c.mutation.Username(); ok { + _spec.SetField(password.FieldUsername, field.TypeString, value) _node.Username = value } - if value, ok := pc.mutation.UserID(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: password.FieldUserID, - }) + if value, ok := _c.mutation.UserID(); ok { + _spec.SetField(password.FieldUserID, field.TypeString, value) _node.UserID = value } return _node, _spec @@ -211,17 +152,21 @@ func (pc *PasswordCreate) createSpec() (*Password, *sqlgraph.CreateSpec) { // PasswordCreateBulk is the builder for creating many Password entities in bulk. type PasswordCreateBulk struct { config + err error builders []*PasswordCreate } // Save creates the Password entities in the database. -func (pcb *PasswordCreateBulk) Save(ctx context.Context) ([]*Password, error) { - specs := make([]*sqlgraph.CreateSpec, len(pcb.builders)) - nodes := make([]*Password, len(pcb.builders)) - mutators := make([]Mutator, len(pcb.builders)) - for i := range pcb.builders { +func (_c *PasswordCreateBulk) Save(ctx context.Context) ([]*Password, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*Password, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { func(i int, root context.Context) { - builder := pcb.builders[i] + builder := _c.builders[i] var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { mutation, ok := m.(*PasswordMutation) if !ok { @@ -231,14 +176,14 @@ func (pcb *PasswordCreateBulk) Save(ctx context.Context) ([]*Password, error) { return nil, err } builder.mutation = mutation - nodes[i], specs[i] = builder.createSpec() var err error + nodes[i], specs[i] = builder.createSpec() if i < len(mutators)-1 { - _, err = mutators[i+1].Mutate(root, pcb.builders[i+1].mutation) + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} // Invoke the actual operation on the latest mutation in the chain. - if err = sqlgraph.BatchCreate(ctx, pcb.driver, spec); err != nil { + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -262,7 +207,7 @@ func (pcb *PasswordCreateBulk) Save(ctx context.Context) ([]*Password, error) { }(i, ctx) } if len(mutators) > 0 { - if _, err := mutators[0].Mutate(ctx, pcb.builders[0].mutation); err != nil { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { return nil, err } } @@ -270,8 +215,8 @@ func (pcb *PasswordCreateBulk) Save(ctx context.Context) ([]*Password, error) { } // SaveX is like Save, but panics if an error occurs. -func (pcb *PasswordCreateBulk) SaveX(ctx context.Context) []*Password { - v, err := pcb.Save(ctx) +func (_c *PasswordCreateBulk) SaveX(ctx context.Context) []*Password { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -279,14 +224,14 @@ func (pcb *PasswordCreateBulk) SaveX(ctx context.Context) []*Password { } // Exec executes the query. -func (pcb *PasswordCreateBulk) Exec(ctx context.Context) error { - _, err := pcb.Save(ctx) +func (_c *PasswordCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (pcb *PasswordCreateBulk) ExecX(ctx context.Context) { - if err := pcb.Exec(ctx); err != nil { +func (_c *PasswordCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } diff --git a/storage/ent/db/password_delete.go b/storage/ent/db/password_delete.go index 6bbe5af57b..35ecfbc30d 100644 --- a/storage/ent/db/password_delete.go +++ b/storage/ent/db/password_delete.go @@ -4,7 +4,6 @@ package db import ( "context" - "fmt" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" @@ -21,84 +20,56 @@ type PasswordDelete struct { } // Where appends a list predicates to the PasswordDelete builder. -func (pd *PasswordDelete) Where(ps ...predicate.Password) *PasswordDelete { - pd.mutation.Where(ps...) - return pd +func (_d *PasswordDelete) Where(ps ...predicate.Password) *PasswordDelete { + _d.mutation.Where(ps...) + return _d } // Exec executes the deletion query and returns how many vertices were deleted. -func (pd *PasswordDelete) Exec(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(pd.hooks) == 0 { - affected, err = pd.sqlExec(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*PasswordMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - pd.mutation = mutation - affected, err = pd.sqlExec(ctx) - mutation.done = true - return affected, err - }) - for i := len(pd.hooks) - 1; i >= 0; i-- { - if pd.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = pd.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, pd.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_d *PasswordDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) } // ExecX is like Exec, but panics if an error occurs. -func (pd *PasswordDelete) ExecX(ctx context.Context) int { - n, err := pd.Exec(ctx) +func (_d *PasswordDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) if err != nil { panic(err) } return n } -func (pd *PasswordDelete) sqlExec(ctx context.Context) (int, error) { - _spec := &sqlgraph.DeleteSpec{ - Node: &sqlgraph.NodeSpec{ - Table: password.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: password.FieldID, - }, - }, - } - if ps := pd.mutation.predicates; len(ps) > 0 { +func (_d *PasswordDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(password.Table, sqlgraph.NewFieldSpec(password.FieldID, field.TypeInt)) + if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - affected, err := sqlgraph.DeleteNodes(ctx, pd.driver, _spec) + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) if err != nil && sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } + _d.mutation.done = true return affected, err } // PasswordDeleteOne is the builder for deleting a single Password entity. type PasswordDeleteOne struct { - pd *PasswordDelete + _d *PasswordDelete +} + +// Where appends a list predicates to the PasswordDelete builder. +func (_d *PasswordDeleteOne) Where(ps ...predicate.Password) *PasswordDeleteOne { + _d._d.mutation.Where(ps...) + return _d } // Exec executes the deletion query. -func (pdo *PasswordDeleteOne) Exec(ctx context.Context) error { - n, err := pdo.pd.Exec(ctx) +func (_d *PasswordDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) switch { case err != nil: return err @@ -110,6 +81,8 @@ func (pdo *PasswordDeleteOne) Exec(ctx context.Context) error { } // ExecX is like Exec, but panics if an error occurs. -func (pdo *PasswordDeleteOne) ExecX(ctx context.Context) { - pdo.pd.ExecX(ctx) +func (_d *PasswordDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } } diff --git a/storage/ent/db/password_query.go b/storage/ent/db/password_query.go index 0da4d08aef..eaeb28bba0 100644 --- a/storage/ent/db/password_query.go +++ b/storage/ent/db/password_query.go @@ -7,6 +7,7 @@ import ( "fmt" "math" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" @@ -17,11 +18,9 @@ import ( // PasswordQuery is the builder for querying Password entities. type PasswordQuery struct { config - limit *int - offset *int - unique *bool - order []OrderFunc - fields []string + ctx *QueryContext + order []password.OrderOption + inters []Interceptor predicates []predicate.Password // intermediate query (i.e. traversal path). sql *sql.Selector @@ -29,40 +28,40 @@ type PasswordQuery struct { } // Where adds a new predicate for the PasswordQuery builder. -func (pq *PasswordQuery) Where(ps ...predicate.Password) *PasswordQuery { - pq.predicates = append(pq.predicates, ps...) - return pq +func (_q *PasswordQuery) Where(ps ...predicate.Password) *PasswordQuery { + _q.predicates = append(_q.predicates, ps...) + return _q } -// Limit adds a limit step to the query. -func (pq *PasswordQuery) Limit(limit int) *PasswordQuery { - pq.limit = &limit - return pq +// Limit the number of records to be returned by this query. +func (_q *PasswordQuery) Limit(limit int) *PasswordQuery { + _q.ctx.Limit = &limit + return _q } -// Offset adds an offset step to the query. -func (pq *PasswordQuery) Offset(offset int) *PasswordQuery { - pq.offset = &offset - return pq +// Offset to start from. +func (_q *PasswordQuery) Offset(offset int) *PasswordQuery { + _q.ctx.Offset = &offset + return _q } // Unique configures the query builder to filter duplicate records on query. // By default, unique is set to true, and can be disabled using this method. -func (pq *PasswordQuery) Unique(unique bool) *PasswordQuery { - pq.unique = &unique - return pq +func (_q *PasswordQuery) Unique(unique bool) *PasswordQuery { + _q.ctx.Unique = &unique + return _q } -// Order adds an order step to the query. -func (pq *PasswordQuery) Order(o ...OrderFunc) *PasswordQuery { - pq.order = append(pq.order, o...) - return pq +// Order specifies how the records should be ordered. +func (_q *PasswordQuery) Order(o ...password.OrderOption) *PasswordQuery { + _q.order = append(_q.order, o...) + return _q } // First returns the first Password entity from the query. // Returns a *NotFoundError when no Password was found. -func (pq *PasswordQuery) First(ctx context.Context) (*Password, error) { - nodes, err := pq.Limit(1).All(ctx) +func (_q *PasswordQuery) First(ctx context.Context) (*Password, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) if err != nil { return nil, err } @@ -73,8 +72,8 @@ func (pq *PasswordQuery) First(ctx context.Context) (*Password, error) { } // FirstX is like First, but panics if an error occurs. -func (pq *PasswordQuery) FirstX(ctx context.Context) *Password { - node, err := pq.First(ctx) +func (_q *PasswordQuery) FirstX(ctx context.Context) *Password { + node, err := _q.First(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -83,9 +82,9 @@ func (pq *PasswordQuery) FirstX(ctx context.Context) *Password { // FirstID returns the first Password ID from the query. // Returns a *NotFoundError when no Password ID was found. -func (pq *PasswordQuery) FirstID(ctx context.Context) (id int, err error) { +func (_q *PasswordQuery) FirstID(ctx context.Context) (id int, err error) { var ids []int - if ids, err = pq.Limit(1).IDs(ctx); err != nil { + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { return } if len(ids) == 0 { @@ -96,8 +95,8 @@ func (pq *PasswordQuery) FirstID(ctx context.Context) (id int, err error) { } // FirstIDX is like FirstID, but panics if an error occurs. -func (pq *PasswordQuery) FirstIDX(ctx context.Context) int { - id, err := pq.FirstID(ctx) +func (_q *PasswordQuery) FirstIDX(ctx context.Context) int { + id, err := _q.FirstID(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -107,8 +106,8 @@ func (pq *PasswordQuery) FirstIDX(ctx context.Context) int { // Only returns a single Password entity found by the query, ensuring it only returns one. // Returns a *NotSingularError when more than one Password entity is found. // Returns a *NotFoundError when no Password entities are found. -func (pq *PasswordQuery) Only(ctx context.Context) (*Password, error) { - nodes, err := pq.Limit(2).All(ctx) +func (_q *PasswordQuery) Only(ctx context.Context) (*Password, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) if err != nil { return nil, err } @@ -123,8 +122,8 @@ func (pq *PasswordQuery) Only(ctx context.Context) (*Password, error) { } // OnlyX is like Only, but panics if an error occurs. -func (pq *PasswordQuery) OnlyX(ctx context.Context) *Password { - node, err := pq.Only(ctx) +func (_q *PasswordQuery) OnlyX(ctx context.Context) *Password { + node, err := _q.Only(ctx) if err != nil { panic(err) } @@ -134,9 +133,9 @@ func (pq *PasswordQuery) OnlyX(ctx context.Context) *Password { // OnlyID is like Only, but returns the only Password ID in the query. // Returns a *NotSingularError when more than one Password ID is found. // Returns a *NotFoundError when no entities are found. -func (pq *PasswordQuery) OnlyID(ctx context.Context) (id int, err error) { +func (_q *PasswordQuery) OnlyID(ctx context.Context) (id int, err error) { var ids []int - if ids, err = pq.Limit(2).IDs(ctx); err != nil { + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { return } switch len(ids) { @@ -151,8 +150,8 @@ func (pq *PasswordQuery) OnlyID(ctx context.Context) (id int, err error) { } // OnlyIDX is like OnlyID, but panics if an error occurs. -func (pq *PasswordQuery) OnlyIDX(ctx context.Context) int { - id, err := pq.OnlyID(ctx) +func (_q *PasswordQuery) OnlyIDX(ctx context.Context) int { + id, err := _q.OnlyID(ctx) if err != nil { panic(err) } @@ -160,16 +159,18 @@ func (pq *PasswordQuery) OnlyIDX(ctx context.Context) int { } // All executes the query and returns a list of Passwords. -func (pq *PasswordQuery) All(ctx context.Context) ([]*Password, error) { - if err := pq.prepareQuery(ctx); err != nil { +func (_q *PasswordQuery) All(ctx context.Context) ([]*Password, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { return nil, err } - return pq.sqlAll(ctx) + qr := querierAll[[]*Password, *PasswordQuery]() + return withInterceptors[[]*Password](ctx, _q, qr, _q.inters) } // AllX is like All, but panics if an error occurs. -func (pq *PasswordQuery) AllX(ctx context.Context) []*Password { - nodes, err := pq.All(ctx) +func (_q *PasswordQuery) AllX(ctx context.Context) []*Password { + nodes, err := _q.All(ctx) if err != nil { panic(err) } @@ -177,17 +178,20 @@ func (pq *PasswordQuery) AllX(ctx context.Context) []*Password { } // IDs executes the query and returns a list of Password IDs. -func (pq *PasswordQuery) IDs(ctx context.Context) ([]int, error) { - var ids []int - if err := pq.Select(password.FieldID).Scan(ctx, &ids); err != nil { +func (_q *PasswordQuery) IDs(ctx context.Context) (ids []int, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(password.FieldID).Scan(ctx, &ids); err != nil { return nil, err } return ids, nil } // IDsX is like IDs, but panics if an error occurs. -func (pq *PasswordQuery) IDsX(ctx context.Context) []int { - ids, err := pq.IDs(ctx) +func (_q *PasswordQuery) IDsX(ctx context.Context) []int { + ids, err := _q.IDs(ctx) if err != nil { panic(err) } @@ -195,16 +199,17 @@ func (pq *PasswordQuery) IDsX(ctx context.Context) []int { } // Count returns the count of the given query. -func (pq *PasswordQuery) Count(ctx context.Context) (int, error) { - if err := pq.prepareQuery(ctx); err != nil { +func (_q *PasswordQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { return 0, err } - return pq.sqlCount(ctx) + return withInterceptors[int](ctx, _q, querierCount[*PasswordQuery](), _q.inters) } // CountX is like Count, but panics if an error occurs. -func (pq *PasswordQuery) CountX(ctx context.Context) int { - count, err := pq.Count(ctx) +func (_q *PasswordQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) if err != nil { panic(err) } @@ -212,16 +217,21 @@ func (pq *PasswordQuery) CountX(ctx context.Context) int { } // Exist returns true if the query has elements in the graph. -func (pq *PasswordQuery) Exist(ctx context.Context) (bool, error) { - if err := pq.prepareQuery(ctx); err != nil { - return false, err +func (_q *PasswordQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("db: check existence: %w", err) + default: + return true, nil } - return pq.sqlExist(ctx) } // ExistX is like Exist, but panics if an error occurs. -func (pq *PasswordQuery) ExistX(ctx context.Context) bool { - exist, err := pq.Exist(ctx) +func (_q *PasswordQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) if err != nil { panic(err) } @@ -230,20 +240,19 @@ func (pq *PasswordQuery) ExistX(ctx context.Context) bool { // Clone returns a duplicate of the PasswordQuery builder, including all associated steps. It can be // used to prepare common query builders and use them differently after the clone is made. -func (pq *PasswordQuery) Clone() *PasswordQuery { - if pq == nil { +func (_q *PasswordQuery) Clone() *PasswordQuery { + if _q == nil { return nil } return &PasswordQuery{ - config: pq.config, - limit: pq.limit, - offset: pq.offset, - order: append([]OrderFunc{}, pq.order...), - predicates: append([]predicate.Password{}, pq.predicates...), + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]password.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.Password{}, _q.predicates...), // clone intermediate query. - sql: pq.sql.Clone(), - path: pq.path, - unique: pq.unique, + sql: _q.sql.Clone(), + path: _q.path, } } @@ -261,18 +270,12 @@ func (pq *PasswordQuery) Clone() *PasswordQuery { // GroupBy(password.FieldEmail). // Aggregate(db.Count()). // Scan(ctx, &v) -// -func (pq *PasswordQuery) GroupBy(field string, fields ...string) *PasswordGroupBy { - grbuild := &PasswordGroupBy{config: pq.config} - grbuild.fields = append([]string{field}, fields...) - grbuild.path = func(ctx context.Context) (prev *sql.Selector, err error) { - if err := pq.prepareQuery(ctx); err != nil { - return nil, err - } - return pq.sqlQuery(ctx), nil - } +func (_q *PasswordQuery) GroupBy(field string, fields ...string) *PasswordGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &PasswordGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields grbuild.label = password.Label - grbuild.flds, grbuild.scan = &grbuild.fields, grbuild.Scan + grbuild.scan = grbuild.Scan return grbuild } @@ -288,48 +291,62 @@ func (pq *PasswordQuery) GroupBy(field string, fields ...string) *PasswordGroupB // client.Password.Query(). // Select(password.FieldEmail). // Scan(ctx, &v) -// -func (pq *PasswordQuery) Select(fields ...string) *PasswordSelect { - pq.fields = append(pq.fields, fields...) - selbuild := &PasswordSelect{PasswordQuery: pq} - selbuild.label = password.Label - selbuild.flds, selbuild.scan = &pq.fields, selbuild.Scan - return selbuild +func (_q *PasswordQuery) Select(fields ...string) *PasswordSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &PasswordSelect{PasswordQuery: _q} + sbuild.label = password.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a PasswordSelect configured with the given aggregations. +func (_q *PasswordQuery) Aggregate(fns ...AggregateFunc) *PasswordSelect { + return _q.Select().Aggregate(fns...) } -func (pq *PasswordQuery) prepareQuery(ctx context.Context) error { - for _, f := range pq.fields { +func (_q *PasswordQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("db: uninitialized interceptor (forgotten import db/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { if !password.ValidColumn(f) { return &ValidationError{Name: f, err: fmt.Errorf("db: invalid field %q for query", f)} } } - if pq.path != nil { - prev, err := pq.path(ctx) + if _q.path != nil { + prev, err := _q.path(ctx) if err != nil { return err } - pq.sql = prev + _q.sql = prev } return nil } -func (pq *PasswordQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Password, error) { +func (_q *PasswordQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Password, error) { var ( nodes = []*Password{} - _spec = pq.querySpec() + _spec = _q.querySpec() ) - _spec.ScanValues = func(columns []string) ([]interface{}, error) { + _spec.ScanValues = func(columns []string) ([]any, error) { return (*Password).scanValues(nil, columns) } - _spec.Assign = func(columns []string, values []interface{}) error { - node := &Password{config: pq.config} + _spec.Assign = func(columns []string, values []any) error { + node := &Password{config: _q.config} nodes = append(nodes, node) return node.assignValues(columns, values) } for i := range hooks { hooks[i](ctx, _spec) } - if err := sqlgraph.QueryNodes(ctx, pq.driver, _spec); err != nil { + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { return nil, err } if len(nodes) == 0 { @@ -338,40 +355,24 @@ func (pq *PasswordQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Pas return nodes, nil } -func (pq *PasswordQuery) sqlCount(ctx context.Context) (int, error) { - _spec := pq.querySpec() - _spec.Node.Columns = pq.fields - if len(pq.fields) > 0 { - _spec.Unique = pq.unique != nil && *pq.unique - } - return sqlgraph.CountNodes(ctx, pq.driver, _spec) -} - -func (pq *PasswordQuery) sqlExist(ctx context.Context) (bool, error) { - n, err := pq.sqlCount(ctx) - if err != nil { - return false, fmt.Errorf("db: check existence: %w", err) +func (_q *PasswordQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique } - return n > 0, nil + return sqlgraph.CountNodes(ctx, _q.driver, _spec) } -func (pq *PasswordQuery) querySpec() *sqlgraph.QuerySpec { - _spec := &sqlgraph.QuerySpec{ - Node: &sqlgraph.NodeSpec{ - Table: password.Table, - Columns: password.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: password.FieldID, - }, - }, - From: pq.sql, - Unique: true, - } - if unique := pq.unique; unique != nil { +func (_q *PasswordQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(password.Table, password.Columns, sqlgraph.NewFieldSpec(password.FieldID, field.TypeInt)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true } - if fields := pq.fields; len(fields) > 0 { + if fields := _q.ctx.Fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, password.FieldID) for i := range fields { @@ -380,20 +381,20 @@ func (pq *PasswordQuery) querySpec() *sqlgraph.QuerySpec { } } } - if ps := pq.predicates; len(ps) > 0 { + if ps := _q.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if limit := pq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { _spec.Limit = *limit } - if offset := pq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { _spec.Offset = *offset } - if ps := pq.order; len(ps) > 0 { + if ps := _q.order; len(ps) > 0 { _spec.Order = func(selector *sql.Selector) { for i := range ps { ps[i](selector) @@ -403,33 +404,33 @@ func (pq *PasswordQuery) querySpec() *sqlgraph.QuerySpec { return _spec } -func (pq *PasswordQuery) sqlQuery(ctx context.Context) *sql.Selector { - builder := sql.Dialect(pq.driver.Dialect()) +func (_q *PasswordQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) t1 := builder.Table(password.Table) - columns := pq.fields + columns := _q.ctx.Fields if len(columns) == 0 { columns = password.Columns } selector := builder.Select(t1.Columns(columns...)...).From(t1) - if pq.sql != nil { - selector = pq.sql + if _q.sql != nil { + selector = _q.sql selector.Select(selector.Columns(columns...)...) } - if pq.unique != nil && *pq.unique { + if _q.ctx.Unique != nil && *_q.ctx.Unique { selector.Distinct() } - for _, p := range pq.predicates { + for _, p := range _q.predicates { p(selector) } - for _, p := range pq.order { + for _, p := range _q.order { p(selector) } - if offset := pq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { // limit is mandatory for offset clause. We start // with default value, and override it below if needed. selector.Offset(*offset).Limit(math.MaxInt32) } - if limit := pq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { selector.Limit(*limit) } return selector @@ -437,90 +438,88 @@ func (pq *PasswordQuery) sqlQuery(ctx context.Context) *sql.Selector { // PasswordGroupBy is the group-by builder for Password entities. type PasswordGroupBy struct { - config selector - fields []string - fns []AggregateFunc - // intermediate query (i.e. traversal path). - sql *sql.Selector - path func(context.Context) (*sql.Selector, error) + build *PasswordQuery } // Aggregate adds the given aggregation functions to the group-by query. -func (pgb *PasswordGroupBy) Aggregate(fns ...AggregateFunc) *PasswordGroupBy { - pgb.fns = append(pgb.fns, fns...) - return pgb +func (_g *PasswordGroupBy) Aggregate(fns ...AggregateFunc) *PasswordGroupBy { + _g.fns = append(_g.fns, fns...) + return _g } -// Scan applies the group-by query and scans the result into the given value. -func (pgb *PasswordGroupBy) Scan(ctx context.Context, v interface{}) error { - query, err := pgb.path(ctx) - if err != nil { +// Scan applies the selector query and scans the result into the given value. +func (_g *PasswordGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { return err } - pgb.sql = query - return pgb.sqlScan(ctx, v) + return scanWithInterceptors[*PasswordQuery, *PasswordGroupBy](ctx, _g.build, _g, _g.build.inters, v) } -func (pgb *PasswordGroupBy) sqlScan(ctx context.Context, v interface{}) error { - for _, f := range pgb.fields { - if !password.ValidColumn(f) { - return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)} +func (_g *PasswordGroupBy) sqlScan(ctx context.Context, root *PasswordQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) } + columns = append(columns, aggregation...) + selector.Select(columns...) } - selector := pgb.sqlQuery() + selector.GroupBy(selector.Columns(*_g.flds...)...) if err := selector.Err(); err != nil { return err } rows := &sql.Rows{} query, args := selector.Query() - if err := pgb.driver.Query(ctx, query, args, rows); err != nil { + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() return sql.ScanSlice(rows, v) } -func (pgb *PasswordGroupBy) sqlQuery() *sql.Selector { - selector := pgb.sql.Select() - aggregation := make([]string, 0, len(pgb.fns)) - for _, fn := range pgb.fns { - aggregation = append(aggregation, fn(selector)) - } - // If no columns were selected in a custom aggregation function, the default - // selection is the fields used for "group-by", and the aggregation functions. - if len(selector.SelectedColumns()) == 0 { - columns := make([]string, 0, len(pgb.fields)+len(pgb.fns)) - for _, f := range pgb.fields { - columns = append(columns, selector.C(f)) - } - columns = append(columns, aggregation...) - selector.Select(columns...) - } - return selector.GroupBy(selector.Columns(pgb.fields...)...) -} - // PasswordSelect is the builder for selecting fields of Password entities. type PasswordSelect struct { *PasswordQuery selector - // intermediate query (i.e. traversal path). - sql *sql.Selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *PasswordSelect) Aggregate(fns ...AggregateFunc) *PasswordSelect { + _s.fns = append(_s.fns, fns...) + return _s } // Scan applies the selector query and scans the result into the given value. -func (ps *PasswordSelect) Scan(ctx context.Context, v interface{}) error { - if err := ps.prepareQuery(ctx); err != nil { +func (_s *PasswordSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { return err } - ps.sql = ps.PasswordQuery.sqlQuery(ctx) - return ps.sqlScan(ctx, v) + return scanWithInterceptors[*PasswordQuery, *PasswordSelect](ctx, _s.PasswordQuery, _s, _s.inters, v) } -func (ps *PasswordSelect) sqlScan(ctx context.Context, v interface{}) error { +func (_s *PasswordSelect) sqlScan(ctx context.Context, root *PasswordQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } rows := &sql.Rows{} - query, args := ps.sql.Query() - if err := ps.driver.Query(ctx, query, args, rows); err != nil { + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() diff --git a/storage/ent/db/password_update.go b/storage/ent/db/password_update.go index 8d149991a8..75394a78a2 100644 --- a/storage/ent/db/password_update.go +++ b/storage/ent/db/password_update.go @@ -22,81 +22,72 @@ type PasswordUpdate struct { } // Where appends a list predicates to the PasswordUpdate builder. -func (pu *PasswordUpdate) Where(ps ...predicate.Password) *PasswordUpdate { - pu.mutation.Where(ps...) - return pu +func (_u *PasswordUpdate) Where(ps ...predicate.Password) *PasswordUpdate { + _u.mutation.Where(ps...) + return _u } // SetEmail sets the "email" field. -func (pu *PasswordUpdate) SetEmail(s string) *PasswordUpdate { - pu.mutation.SetEmail(s) - return pu +func (_u *PasswordUpdate) SetEmail(v string) *PasswordUpdate { + _u.mutation.SetEmail(v) + return _u +} + +// SetNillableEmail sets the "email" field if the given value is not nil. +func (_u *PasswordUpdate) SetNillableEmail(v *string) *PasswordUpdate { + if v != nil { + _u.SetEmail(*v) + } + return _u } // SetHash sets the "hash" field. -func (pu *PasswordUpdate) SetHash(b []byte) *PasswordUpdate { - pu.mutation.SetHash(b) - return pu +func (_u *PasswordUpdate) SetHash(v []byte) *PasswordUpdate { + _u.mutation.SetHash(v) + return _u } // SetUsername sets the "username" field. -func (pu *PasswordUpdate) SetUsername(s string) *PasswordUpdate { - pu.mutation.SetUsername(s) - return pu +func (_u *PasswordUpdate) SetUsername(v string) *PasswordUpdate { + _u.mutation.SetUsername(v) + return _u +} + +// SetNillableUsername sets the "username" field if the given value is not nil. +func (_u *PasswordUpdate) SetNillableUsername(v *string) *PasswordUpdate { + if v != nil { + _u.SetUsername(*v) + } + return _u } // SetUserID sets the "user_id" field. -func (pu *PasswordUpdate) SetUserID(s string) *PasswordUpdate { - pu.mutation.SetUserID(s) - return pu +func (_u *PasswordUpdate) SetUserID(v string) *PasswordUpdate { + _u.mutation.SetUserID(v) + return _u +} + +// SetNillableUserID sets the "user_id" field if the given value is not nil. +func (_u *PasswordUpdate) SetNillableUserID(v *string) *PasswordUpdate { + if v != nil { + _u.SetUserID(*v) + } + return _u } // Mutation returns the PasswordMutation object of the builder. -func (pu *PasswordUpdate) Mutation() *PasswordMutation { - return pu.mutation +func (_u *PasswordUpdate) Mutation() *PasswordMutation { + return _u.mutation } // Save executes the query and returns the number of nodes affected by the update operation. -func (pu *PasswordUpdate) Save(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(pu.hooks) == 0 { - if err = pu.check(); err != nil { - return 0, err - } - affected, err = pu.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*PasswordMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = pu.check(); err != nil { - return 0, err - } - pu.mutation = mutation - affected, err = pu.sqlSave(ctx) - mutation.done = true - return affected, err - }) - for i := len(pu.hooks) - 1; i >= 0; i-- { - if pu.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = pu.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, pu.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_u *PasswordUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (pu *PasswordUpdate) SaveX(ctx context.Context) int { - affected, err := pu.Save(ctx) +func (_u *PasswordUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) if err != nil { panic(err) } @@ -104,31 +95,31 @@ func (pu *PasswordUpdate) SaveX(ctx context.Context) int { } // Exec executes the query. -func (pu *PasswordUpdate) Exec(ctx context.Context) error { - _, err := pu.Save(ctx) +func (_u *PasswordUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (pu *PasswordUpdate) ExecX(ctx context.Context) { - if err := pu.Exec(ctx); err != nil { +func (_u *PasswordUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (pu *PasswordUpdate) check() error { - if v, ok := pu.mutation.Email(); ok { +func (_u *PasswordUpdate) check() error { + if v, ok := _u.mutation.Email(); ok { if err := password.EmailValidator(v); err != nil { return &ValidationError{Name: "email", err: fmt.Errorf(`db: validator failed for field "Password.email": %w`, err)} } } - if v, ok := pu.mutation.Username(); ok { + if v, ok := _u.mutation.Username(); ok { if err := password.UsernameValidator(v); err != nil { return &ValidationError{Name: "username", err: fmt.Errorf(`db: validator failed for field "Password.username": %w`, err)} } } - if v, ok := pu.mutation.UserID(); ok { + if v, ok := _u.mutation.UserID(); ok { if err := password.UserIDValidator(v); err != nil { return &ValidationError{Name: "user_id", err: fmt.Errorf(`db: validator failed for field "Password.user_id": %w`, err)} } @@ -136,53 +127,31 @@ func (pu *PasswordUpdate) check() error { return nil } -func (pu *PasswordUpdate) sqlSave(ctx context.Context) (n int, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: password.Table, - Columns: password.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: password.FieldID, - }, - }, +func (_u *PasswordUpdate) sqlSave(ctx context.Context) (_node int, err error) { + if err := _u.check(); err != nil { + return _node, err } - if ps := pu.mutation.predicates; len(ps) > 0 { + _spec := sqlgraph.NewUpdateSpec(password.Table, password.Columns, sqlgraph.NewFieldSpec(password.FieldID, field.TypeInt)) + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := pu.mutation.Email(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: password.FieldEmail, - }) - } - if value, ok := pu.mutation.Hash(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: password.FieldHash, - }) - } - if value, ok := pu.mutation.Username(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: password.FieldUsername, - }) - } - if value, ok := pu.mutation.UserID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: password.FieldUserID, - }) - } - if n, err = sqlgraph.UpdateNodes(ctx, pu.driver, _spec); err != nil { + if value, ok := _u.mutation.Email(); ok { + _spec.SetField(password.FieldEmail, field.TypeString, value) + } + if value, ok := _u.mutation.Hash(); ok { + _spec.SetField(password.FieldHash, field.TypeBytes, value) + } + if value, ok := _u.mutation.Username(); ok { + _spec.SetField(password.FieldUsername, field.TypeString, value) + } + if value, ok := _u.mutation.UserID(); ok { + _spec.SetField(password.FieldUserID, field.TypeString, value) + } + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{password.Label} } else if sqlgraph.IsConstraintError(err) { @@ -190,7 +159,8 @@ func (pu *PasswordUpdate) sqlSave(ctx context.Context) (n int, err error) { } return 0, err } - return n, nil + _u.mutation.done = true + return _node, nil } // PasswordUpdateOne is the builder for updating a single Password entity. @@ -202,88 +172,79 @@ type PasswordUpdateOne struct { } // SetEmail sets the "email" field. -func (puo *PasswordUpdateOne) SetEmail(s string) *PasswordUpdateOne { - puo.mutation.SetEmail(s) - return puo +func (_u *PasswordUpdateOne) SetEmail(v string) *PasswordUpdateOne { + _u.mutation.SetEmail(v) + return _u +} + +// SetNillableEmail sets the "email" field if the given value is not nil. +func (_u *PasswordUpdateOne) SetNillableEmail(v *string) *PasswordUpdateOne { + if v != nil { + _u.SetEmail(*v) + } + return _u } // SetHash sets the "hash" field. -func (puo *PasswordUpdateOne) SetHash(b []byte) *PasswordUpdateOne { - puo.mutation.SetHash(b) - return puo +func (_u *PasswordUpdateOne) SetHash(v []byte) *PasswordUpdateOne { + _u.mutation.SetHash(v) + return _u } // SetUsername sets the "username" field. -func (puo *PasswordUpdateOne) SetUsername(s string) *PasswordUpdateOne { - puo.mutation.SetUsername(s) - return puo +func (_u *PasswordUpdateOne) SetUsername(v string) *PasswordUpdateOne { + _u.mutation.SetUsername(v) + return _u +} + +// SetNillableUsername sets the "username" field if the given value is not nil. +func (_u *PasswordUpdateOne) SetNillableUsername(v *string) *PasswordUpdateOne { + if v != nil { + _u.SetUsername(*v) + } + return _u } // SetUserID sets the "user_id" field. -func (puo *PasswordUpdateOne) SetUserID(s string) *PasswordUpdateOne { - puo.mutation.SetUserID(s) - return puo +func (_u *PasswordUpdateOne) SetUserID(v string) *PasswordUpdateOne { + _u.mutation.SetUserID(v) + return _u +} + +// SetNillableUserID sets the "user_id" field if the given value is not nil. +func (_u *PasswordUpdateOne) SetNillableUserID(v *string) *PasswordUpdateOne { + if v != nil { + _u.SetUserID(*v) + } + return _u } // Mutation returns the PasswordMutation object of the builder. -func (puo *PasswordUpdateOne) Mutation() *PasswordMutation { - return puo.mutation +func (_u *PasswordUpdateOne) Mutation() *PasswordMutation { + return _u.mutation +} + +// Where appends a list predicates to the PasswordUpdate builder. +func (_u *PasswordUpdateOne) Where(ps ...predicate.Password) *PasswordUpdateOne { + _u.mutation.Where(ps...) + return _u } // Select allows selecting one or more fields (columns) of the returned entity. // The default is selecting all fields defined in the entity schema. -func (puo *PasswordUpdateOne) Select(field string, fields ...string) *PasswordUpdateOne { - puo.fields = append([]string{field}, fields...) - return puo +func (_u *PasswordUpdateOne) Select(field string, fields ...string) *PasswordUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u } // Save executes the query and returns the updated Password entity. -func (puo *PasswordUpdateOne) Save(ctx context.Context) (*Password, error) { - var ( - err error - node *Password - ) - if len(puo.hooks) == 0 { - if err = puo.check(); err != nil { - return nil, err - } - node, err = puo.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*PasswordMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = puo.check(); err != nil { - return nil, err - } - puo.mutation = mutation - node, err = puo.sqlSave(ctx) - mutation.done = true - return node, err - }) - for i := len(puo.hooks) - 1; i >= 0; i-- { - if puo.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = puo.hooks[i](mut) - } - v, err := mut.Mutate(ctx, puo.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*Password) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from PasswordMutation", v) - } - node = nv - } - return node, err +func (_u *PasswordUpdateOne) Save(ctx context.Context) (*Password, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (puo *PasswordUpdateOne) SaveX(ctx context.Context) *Password { - node, err := puo.Save(ctx) +func (_u *PasswordUpdateOne) SaveX(ctx context.Context) *Password { + node, err := _u.Save(ctx) if err != nil { panic(err) } @@ -291,31 +252,31 @@ func (puo *PasswordUpdateOne) SaveX(ctx context.Context) *Password { } // Exec executes the query on the entity. -func (puo *PasswordUpdateOne) Exec(ctx context.Context) error { - _, err := puo.Save(ctx) +func (_u *PasswordUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (puo *PasswordUpdateOne) ExecX(ctx context.Context) { - if err := puo.Exec(ctx); err != nil { +func (_u *PasswordUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (puo *PasswordUpdateOne) check() error { - if v, ok := puo.mutation.Email(); ok { +func (_u *PasswordUpdateOne) check() error { + if v, ok := _u.mutation.Email(); ok { if err := password.EmailValidator(v); err != nil { return &ValidationError{Name: "email", err: fmt.Errorf(`db: validator failed for field "Password.email": %w`, err)} } } - if v, ok := puo.mutation.Username(); ok { + if v, ok := _u.mutation.Username(); ok { if err := password.UsernameValidator(v); err != nil { return &ValidationError{Name: "username", err: fmt.Errorf(`db: validator failed for field "Password.username": %w`, err)} } } - if v, ok := puo.mutation.UserID(); ok { + if v, ok := _u.mutation.UserID(); ok { if err := password.UserIDValidator(v); err != nil { return &ValidationError{Name: "user_id", err: fmt.Errorf(`db: validator failed for field "Password.user_id": %w`, err)} } @@ -323,23 +284,17 @@ func (puo *PasswordUpdateOne) check() error { return nil } -func (puo *PasswordUpdateOne) sqlSave(ctx context.Context) (_node *Password, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: password.Table, - Columns: password.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Column: password.FieldID, - }, - }, +func (_u *PasswordUpdateOne) sqlSave(ctx context.Context) (_node *Password, err error) { + if err := _u.check(); err != nil { + return _node, err } - id, ok := puo.mutation.ID() + _spec := sqlgraph.NewUpdateSpec(password.Table, password.Columns, sqlgraph.NewFieldSpec(password.FieldID, field.TypeInt)) + id, ok := _u.mutation.ID() if !ok { return nil, &ValidationError{Name: "id", err: errors.New(`db: missing "Password.id" for update`)} } _spec.Node.ID.Value = id - if fields := puo.fields; len(fields) > 0 { + if fields := _u.fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, password.FieldID) for _, f := range fields { @@ -351,45 +306,29 @@ func (puo *PasswordUpdateOne) sqlSave(ctx context.Context) (_node *Password, err } } } - if ps := puo.mutation.predicates; len(ps) > 0 { + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := puo.mutation.Email(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: password.FieldEmail, - }) - } - if value, ok := puo.mutation.Hash(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: password.FieldHash, - }) - } - if value, ok := puo.mutation.Username(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: password.FieldUsername, - }) - } - if value, ok := puo.mutation.UserID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: password.FieldUserID, - }) - } - _node = &Password{config: puo.config} + if value, ok := _u.mutation.Email(); ok { + _spec.SetField(password.FieldEmail, field.TypeString, value) + } + if value, ok := _u.mutation.Hash(); ok { + _spec.SetField(password.FieldHash, field.TypeBytes, value) + } + if value, ok := _u.mutation.Username(); ok { + _spec.SetField(password.FieldUsername, field.TypeString, value) + } + if value, ok := _u.mutation.UserID(); ok { + _spec.SetField(password.FieldUserID, field.TypeString, value) + } + _node = &Password{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues - if err = sqlgraph.UpdateNode(ctx, puo.driver, _spec); err != nil { + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{password.Label} } else if sqlgraph.IsConstraintError(err) { @@ -397,5 +336,6 @@ func (puo *PasswordUpdateOne) sqlSave(ctx context.Context) (_node *Password, err } return nil, err } + _u.mutation.done = true return _node, nil } diff --git a/storage/ent/db/refreshtoken.go b/storage/ent/db/refreshtoken.go index b5c75bb101..12f5910a7a 100644 --- a/storage/ent/db/refreshtoken.go +++ b/storage/ent/db/refreshtoken.go @@ -8,6 +8,7 @@ import ( "strings" "time" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "github.com/dexidp/dex/storage/ent/db/refreshtoken" ) @@ -46,12 +47,13 @@ type RefreshToken struct { // CreatedAt holds the value of the "created_at" field. CreatedAt time.Time `json:"created_at,omitempty"` // LastUsed holds the value of the "last_used" field. - LastUsed time.Time `json:"last_used,omitempty"` + LastUsed time.Time `json:"last_used,omitempty"` + selectValues sql.SelectValues } // scanValues returns the types for scanning values from sql.Rows. -func (*RefreshToken) scanValues(columns []string) ([]interface{}, error) { - values := make([]interface{}, len(columns)) +func (*RefreshToken) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) for i := range columns { switch columns[i] { case refreshtoken.FieldScopes, refreshtoken.FieldClaimsGroups, refreshtoken.FieldConnectorData: @@ -63,7 +65,7 @@ func (*RefreshToken) scanValues(columns []string) ([]interface{}, error) { case refreshtoken.FieldCreatedAt, refreshtoken.FieldLastUsed: values[i] = new(sql.NullTime) default: - return nil, fmt.Errorf("unexpected column %q for type RefreshToken", columns[i]) + values[i] = new(sql.UnknownType) } } return values, nil @@ -71,7 +73,7 @@ func (*RefreshToken) scanValues(columns []string) ([]interface{}, error) { // assignValues assigns the values that were returned from sql.Rows (after scanning) // to the RefreshToken fields. -func (rt *RefreshToken) assignValues(columns []string, values []interface{}) error { +func (_m *RefreshToken) assignValues(columns []string, values []any) error { if m, n := len(values), len(columns); m < n { return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) } @@ -81,19 +83,19 @@ func (rt *RefreshToken) assignValues(columns []string, values []interface{}) err if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field id", values[i]) } else if value.Valid { - rt.ID = value.String + _m.ID = value.String } case refreshtoken.FieldClientID: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field client_id", values[i]) } else if value.Valid { - rt.ClientID = value.String + _m.ClientID = value.String } case refreshtoken.FieldScopes: if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field scopes", values[i]) } else if value != nil && len(*value) > 0 { - if err := json.Unmarshal(*value, &rt.Scopes); err != nil { + if err := json.Unmarshal(*value, &_m.Scopes); err != nil { return fmt.Errorf("unmarshal field scopes: %w", err) } } @@ -101,37 +103,37 @@ func (rt *RefreshToken) assignValues(columns []string, values []interface{}) err if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field nonce", values[i]) } else if value.Valid { - rt.Nonce = value.String + _m.Nonce = value.String } case refreshtoken.FieldClaimsUserID: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field claims_user_id", values[i]) } else if value.Valid { - rt.ClaimsUserID = value.String + _m.ClaimsUserID = value.String } case refreshtoken.FieldClaimsUsername: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field claims_username", values[i]) } else if value.Valid { - rt.ClaimsUsername = value.String + _m.ClaimsUsername = value.String } case refreshtoken.FieldClaimsEmail: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field claims_email", values[i]) } else if value.Valid { - rt.ClaimsEmail = value.String + _m.ClaimsEmail = value.String } case refreshtoken.FieldClaimsEmailVerified: if value, ok := values[i].(*sql.NullBool); !ok { return fmt.Errorf("unexpected type %T for field claims_email_verified", values[i]) } else if value.Valid { - rt.ClaimsEmailVerified = value.Bool + _m.ClaimsEmailVerified = value.Bool } case refreshtoken.FieldClaimsGroups: if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field claims_groups", values[i]) } else if value != nil && len(*value) > 0 { - if err := json.Unmarshal(*value, &rt.ClaimsGroups); err != nil { + if err := json.Unmarshal(*value, &_m.ClaimsGroups); err != nil { return fmt.Errorf("unmarshal field claims_groups: %w", err) } } @@ -139,127 +141,129 @@ func (rt *RefreshToken) assignValues(columns []string, values []interface{}) err if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field claims_preferred_username", values[i]) } else if value.Valid { - rt.ClaimsPreferredUsername = value.String + _m.ClaimsPreferredUsername = value.String } case refreshtoken.FieldConnectorID: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field connector_id", values[i]) } else if value.Valid { - rt.ConnectorID = value.String + _m.ConnectorID = value.String } case refreshtoken.FieldConnectorData: if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field connector_data", values[i]) } else if value != nil { - rt.ConnectorData = value + _m.ConnectorData = value } case refreshtoken.FieldToken: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field token", values[i]) } else if value.Valid { - rt.Token = value.String + _m.Token = value.String } case refreshtoken.FieldObsoleteToken: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field obsolete_token", values[i]) } else if value.Valid { - rt.ObsoleteToken = value.String + _m.ObsoleteToken = value.String } case refreshtoken.FieldCreatedAt: if value, ok := values[i].(*sql.NullTime); !ok { return fmt.Errorf("unexpected type %T for field created_at", values[i]) } else if value.Valid { - rt.CreatedAt = value.Time + _m.CreatedAt = value.Time } case refreshtoken.FieldLastUsed: if value, ok := values[i].(*sql.NullTime); !ok { return fmt.Errorf("unexpected type %T for field last_used", values[i]) } else if value.Valid { - rt.LastUsed = value.Time + _m.LastUsed = value.Time } + default: + _m.selectValues.Set(columns[i], values[i]) } } return nil } +// Value returns the ent.Value that was dynamically selected and assigned to the RefreshToken. +// This includes values selected through modifiers, order, etc. +func (_m *RefreshToken) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + // Update returns a builder for updating this RefreshToken. // Note that you need to call RefreshToken.Unwrap() before calling this method if this RefreshToken // was returned from a transaction, and the transaction was committed or rolled back. -func (rt *RefreshToken) Update() *RefreshTokenUpdateOne { - return (&RefreshTokenClient{config: rt.config}).UpdateOne(rt) +func (_m *RefreshToken) Update() *RefreshTokenUpdateOne { + return NewRefreshTokenClient(_m.config).UpdateOne(_m) } // Unwrap unwraps the RefreshToken entity that was returned from a transaction after it was closed, // so that all future queries will be executed through the driver which created the transaction. -func (rt *RefreshToken) Unwrap() *RefreshToken { - _tx, ok := rt.config.driver.(*txDriver) +func (_m *RefreshToken) Unwrap() *RefreshToken { + _tx, ok := _m.config.driver.(*txDriver) if !ok { panic("db: RefreshToken is not a transactional entity") } - rt.config.driver = _tx.drv - return rt + _m.config.driver = _tx.drv + return _m } // String implements the fmt.Stringer. -func (rt *RefreshToken) String() string { +func (_m *RefreshToken) String() string { var builder strings.Builder builder.WriteString("RefreshToken(") - builder.WriteString(fmt.Sprintf("id=%v, ", rt.ID)) + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) builder.WriteString("client_id=") - builder.WriteString(rt.ClientID) + builder.WriteString(_m.ClientID) builder.WriteString(", ") builder.WriteString("scopes=") - builder.WriteString(fmt.Sprintf("%v", rt.Scopes)) + builder.WriteString(fmt.Sprintf("%v", _m.Scopes)) builder.WriteString(", ") builder.WriteString("nonce=") - builder.WriteString(rt.Nonce) + builder.WriteString(_m.Nonce) builder.WriteString(", ") builder.WriteString("claims_user_id=") - builder.WriteString(rt.ClaimsUserID) + builder.WriteString(_m.ClaimsUserID) builder.WriteString(", ") builder.WriteString("claims_username=") - builder.WriteString(rt.ClaimsUsername) + builder.WriteString(_m.ClaimsUsername) builder.WriteString(", ") builder.WriteString("claims_email=") - builder.WriteString(rt.ClaimsEmail) + builder.WriteString(_m.ClaimsEmail) builder.WriteString(", ") builder.WriteString("claims_email_verified=") - builder.WriteString(fmt.Sprintf("%v", rt.ClaimsEmailVerified)) + builder.WriteString(fmt.Sprintf("%v", _m.ClaimsEmailVerified)) builder.WriteString(", ") builder.WriteString("claims_groups=") - builder.WriteString(fmt.Sprintf("%v", rt.ClaimsGroups)) + builder.WriteString(fmt.Sprintf("%v", _m.ClaimsGroups)) builder.WriteString(", ") builder.WriteString("claims_preferred_username=") - builder.WriteString(rt.ClaimsPreferredUsername) + builder.WriteString(_m.ClaimsPreferredUsername) builder.WriteString(", ") builder.WriteString("connector_id=") - builder.WriteString(rt.ConnectorID) + builder.WriteString(_m.ConnectorID) builder.WriteString(", ") - if v := rt.ConnectorData; v != nil { + if v := _m.ConnectorData; v != nil { builder.WriteString("connector_data=") builder.WriteString(fmt.Sprintf("%v", *v)) } builder.WriteString(", ") builder.WriteString("token=") - builder.WriteString(rt.Token) + builder.WriteString(_m.Token) builder.WriteString(", ") builder.WriteString("obsolete_token=") - builder.WriteString(rt.ObsoleteToken) + builder.WriteString(_m.ObsoleteToken) builder.WriteString(", ") builder.WriteString("created_at=") - builder.WriteString(rt.CreatedAt.Format(time.ANSIC)) + builder.WriteString(_m.CreatedAt.Format(time.ANSIC)) builder.WriteString(", ") builder.WriteString("last_used=") - builder.WriteString(rt.LastUsed.Format(time.ANSIC)) + builder.WriteString(_m.LastUsed.Format(time.ANSIC)) builder.WriteByte(')') return builder.String() } // RefreshTokens is a parsable slice of RefreshToken. type RefreshTokens []*RefreshToken - -func (rt RefreshTokens) config(cfg config) { - for _i := range rt { - rt[_i].config = cfg - } -} diff --git a/storage/ent/db/refreshtoken/refreshtoken.go b/storage/ent/db/refreshtoken/refreshtoken.go index d11d84075a..1163113d6b 100644 --- a/storage/ent/db/refreshtoken/refreshtoken.go +++ b/storage/ent/db/refreshtoken/refreshtoken.go @@ -4,6 +4,8 @@ package refreshtoken import ( "time" + + "entgo.io/ent/dialect/sql" ) const ( @@ -101,3 +103,71 @@ var ( // IDValidator is a validator for the "id" field. It is called by the builders before save. IDValidator func(string) error ) + +// OrderOption defines the ordering options for the RefreshToken queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByClientID orders the results by the client_id field. +func ByClientID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClientID, opts...).ToFunc() +} + +// ByNonce orders the results by the nonce field. +func ByNonce(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldNonce, opts...).ToFunc() +} + +// ByClaimsUserID orders the results by the claims_user_id field. +func ByClaimsUserID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClaimsUserID, opts...).ToFunc() +} + +// ByClaimsUsername orders the results by the claims_username field. +func ByClaimsUsername(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClaimsUsername, opts...).ToFunc() +} + +// ByClaimsEmail orders the results by the claims_email field. +func ByClaimsEmail(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClaimsEmail, opts...).ToFunc() +} + +// ByClaimsEmailVerified orders the results by the claims_email_verified field. +func ByClaimsEmailVerified(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClaimsEmailVerified, opts...).ToFunc() +} + +// ByClaimsPreferredUsername orders the results by the claims_preferred_username field. +func ByClaimsPreferredUsername(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldClaimsPreferredUsername, opts...).ToFunc() +} + +// ByConnectorID orders the results by the connector_id field. +func ByConnectorID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldConnectorID, opts...).ToFunc() +} + +// ByToken orders the results by the token field. +func ByToken(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldToken, opts...).ToFunc() +} + +// ByObsoleteToken orders the results by the obsolete_token field. +func ByObsoleteToken(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldObsoleteToken, opts...).ToFunc() +} + +// ByCreatedAt orders the results by the created_at field. +func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldCreatedAt, opts...).ToFunc() +} + +// ByLastUsed orders the results by the last_used field. +func ByLastUsed(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldLastUsed, opts...).ToFunc() +} diff --git a/storage/ent/db/refreshtoken/where.go b/storage/ent/db/refreshtoken/where.go index e6abf9824b..9fece40fcc 100644 --- a/storage/ent/db/refreshtoken/where.go +++ b/storage/ent/db/refreshtoken/where.go @@ -11,1333 +11,880 @@ import ( // ID filters vertices based on their ID field. func ID(id string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldID, id)) } // IDEQ applies the EQ predicate on the ID field. func IDEQ(id string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldID), id)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldID, id)) } // IDNEQ applies the NEQ predicate on the ID field. func IDNEQ(id string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldID), id)) - }) + return predicate.RefreshToken(sql.FieldNEQ(FieldID, id)) } // IDIn applies the In predicate on the ID field. func IDIn(ids ...string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.In(s.C(FieldID), v...)) - }) + return predicate.RefreshToken(sql.FieldIn(FieldID, ids...)) } // IDNotIn applies the NotIn predicate on the ID field. func IDNotIn(ids ...string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - v := make([]interface{}, len(ids)) - for i := range v { - v[i] = ids[i] - } - s.Where(sql.NotIn(s.C(FieldID), v...)) - }) + return predicate.RefreshToken(sql.FieldNotIn(FieldID, ids...)) } // IDGT applies the GT predicate on the ID field. func IDGT(id string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldID), id)) - }) + return predicate.RefreshToken(sql.FieldGT(FieldID, id)) } // IDGTE applies the GTE predicate on the ID field. func IDGTE(id string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldID), id)) - }) + return predicate.RefreshToken(sql.FieldGTE(FieldID, id)) } // IDLT applies the LT predicate on the ID field. func IDLT(id string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldID), id)) - }) + return predicate.RefreshToken(sql.FieldLT(FieldID, id)) } // IDLTE applies the LTE predicate on the ID field. func IDLTE(id string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldID), id)) - }) + return predicate.RefreshToken(sql.FieldLTE(FieldID, id)) +} + +// IDEqualFold applies the EqualFold predicate on the ID field. +func IDEqualFold(id string) predicate.RefreshToken { + return predicate.RefreshToken(sql.FieldEqualFold(FieldID, id)) +} + +// IDContainsFold applies the ContainsFold predicate on the ID field. +func IDContainsFold(id string) predicate.RefreshToken { + return predicate.RefreshToken(sql.FieldContainsFold(FieldID, id)) } // ClientID applies equality check predicate on the "client_id" field. It's identical to ClientIDEQ. func ClientID(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClientID), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldClientID, v)) } // Nonce applies equality check predicate on the "nonce" field. It's identical to NonceEQ. func Nonce(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldNonce), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldNonce, v)) } // ClaimsUserID applies equality check predicate on the "claims_user_id" field. It's identical to ClaimsUserIDEQ. func ClaimsUserID(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsUserID), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldClaimsUserID, v)) } // ClaimsUsername applies equality check predicate on the "claims_username" field. It's identical to ClaimsUsernameEQ. func ClaimsUsername(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsUsername), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldClaimsUsername, v)) } // ClaimsEmail applies equality check predicate on the "claims_email" field. It's identical to ClaimsEmailEQ. func ClaimsEmail(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsEmail), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldClaimsEmail, v)) } // ClaimsEmailVerified applies equality check predicate on the "claims_email_verified" field. It's identical to ClaimsEmailVerifiedEQ. func ClaimsEmailVerified(v bool) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsEmailVerified), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldClaimsEmailVerified, v)) } // ClaimsPreferredUsername applies equality check predicate on the "claims_preferred_username" field. It's identical to ClaimsPreferredUsernameEQ. func ClaimsPreferredUsername(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldClaimsPreferredUsername, v)) } // ConnectorID applies equality check predicate on the "connector_id" field. It's identical to ConnectorIDEQ. func ConnectorID(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldConnectorID), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldConnectorID, v)) } // ConnectorData applies equality check predicate on the "connector_data" field. It's identical to ConnectorDataEQ. func ConnectorData(v []byte) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldConnectorData), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldConnectorData, v)) } // Token applies equality check predicate on the "token" field. It's identical to TokenEQ. func Token(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldToken), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldToken, v)) } // ObsoleteToken applies equality check predicate on the "obsolete_token" field. It's identical to ObsoleteTokenEQ. func ObsoleteToken(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldObsoleteToken), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldObsoleteToken, v)) } // CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. func CreatedAt(v time.Time) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldCreatedAt), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldCreatedAt, v)) } // LastUsed applies equality check predicate on the "last_used" field. It's identical to LastUsedEQ. func LastUsed(v time.Time) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldLastUsed), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldLastUsed, v)) } // ClientIDEQ applies the EQ predicate on the "client_id" field. func ClientIDEQ(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClientID), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldClientID, v)) } // ClientIDNEQ applies the NEQ predicate on the "client_id" field. func ClientIDNEQ(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClientID), v)) - }) + return predicate.RefreshToken(sql.FieldNEQ(FieldClientID, v)) } // ClientIDIn applies the In predicate on the "client_id" field. func ClientIDIn(vs ...string) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldClientID), v...)) - }) + return predicate.RefreshToken(sql.FieldIn(FieldClientID, vs...)) } // ClientIDNotIn applies the NotIn predicate on the "client_id" field. func ClientIDNotIn(vs ...string) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldClientID), v...)) - }) + return predicate.RefreshToken(sql.FieldNotIn(FieldClientID, vs...)) } // ClientIDGT applies the GT predicate on the "client_id" field. func ClientIDGT(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldClientID), v)) - }) + return predicate.RefreshToken(sql.FieldGT(FieldClientID, v)) } // ClientIDGTE applies the GTE predicate on the "client_id" field. func ClientIDGTE(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldClientID), v)) - }) + return predicate.RefreshToken(sql.FieldGTE(FieldClientID, v)) } // ClientIDLT applies the LT predicate on the "client_id" field. func ClientIDLT(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldClientID), v)) - }) + return predicate.RefreshToken(sql.FieldLT(FieldClientID, v)) } // ClientIDLTE applies the LTE predicate on the "client_id" field. func ClientIDLTE(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldClientID), v)) - }) + return predicate.RefreshToken(sql.FieldLTE(FieldClientID, v)) } // ClientIDContains applies the Contains predicate on the "client_id" field. func ClientIDContains(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldClientID), v)) - }) + return predicate.RefreshToken(sql.FieldContains(FieldClientID, v)) } // ClientIDHasPrefix applies the HasPrefix predicate on the "client_id" field. func ClientIDHasPrefix(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldClientID), v)) - }) + return predicate.RefreshToken(sql.FieldHasPrefix(FieldClientID, v)) } // ClientIDHasSuffix applies the HasSuffix predicate on the "client_id" field. func ClientIDHasSuffix(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldClientID), v)) - }) + return predicate.RefreshToken(sql.FieldHasSuffix(FieldClientID, v)) } // ClientIDEqualFold applies the EqualFold predicate on the "client_id" field. func ClientIDEqualFold(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldClientID), v)) - }) + return predicate.RefreshToken(sql.FieldEqualFold(FieldClientID, v)) } // ClientIDContainsFold applies the ContainsFold predicate on the "client_id" field. func ClientIDContainsFold(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldClientID), v)) - }) + return predicate.RefreshToken(sql.FieldContainsFold(FieldClientID, v)) } // ScopesIsNil applies the IsNil predicate on the "scopes" field. func ScopesIsNil() predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.IsNull(s.C(FieldScopes))) - }) + return predicate.RefreshToken(sql.FieldIsNull(FieldScopes)) } // ScopesNotNil applies the NotNil predicate on the "scopes" field. func ScopesNotNil() predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NotNull(s.C(FieldScopes))) - }) + return predicate.RefreshToken(sql.FieldNotNull(FieldScopes)) } // NonceEQ applies the EQ predicate on the "nonce" field. func NonceEQ(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldNonce), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldNonce, v)) } // NonceNEQ applies the NEQ predicate on the "nonce" field. func NonceNEQ(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldNonce), v)) - }) + return predicate.RefreshToken(sql.FieldNEQ(FieldNonce, v)) } // NonceIn applies the In predicate on the "nonce" field. func NonceIn(vs ...string) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldNonce), v...)) - }) + return predicate.RefreshToken(sql.FieldIn(FieldNonce, vs...)) } // NonceNotIn applies the NotIn predicate on the "nonce" field. func NonceNotIn(vs ...string) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldNonce), v...)) - }) + return predicate.RefreshToken(sql.FieldNotIn(FieldNonce, vs...)) } // NonceGT applies the GT predicate on the "nonce" field. func NonceGT(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldNonce), v)) - }) + return predicate.RefreshToken(sql.FieldGT(FieldNonce, v)) } // NonceGTE applies the GTE predicate on the "nonce" field. func NonceGTE(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldNonce), v)) - }) + return predicate.RefreshToken(sql.FieldGTE(FieldNonce, v)) } // NonceLT applies the LT predicate on the "nonce" field. func NonceLT(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldNonce), v)) - }) + return predicate.RefreshToken(sql.FieldLT(FieldNonce, v)) } // NonceLTE applies the LTE predicate on the "nonce" field. func NonceLTE(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldNonce), v)) - }) + return predicate.RefreshToken(sql.FieldLTE(FieldNonce, v)) } // NonceContains applies the Contains predicate on the "nonce" field. func NonceContains(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldNonce), v)) - }) + return predicate.RefreshToken(sql.FieldContains(FieldNonce, v)) } // NonceHasPrefix applies the HasPrefix predicate on the "nonce" field. func NonceHasPrefix(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldNonce), v)) - }) + return predicate.RefreshToken(sql.FieldHasPrefix(FieldNonce, v)) } // NonceHasSuffix applies the HasSuffix predicate on the "nonce" field. func NonceHasSuffix(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldNonce), v)) - }) + return predicate.RefreshToken(sql.FieldHasSuffix(FieldNonce, v)) } // NonceEqualFold applies the EqualFold predicate on the "nonce" field. func NonceEqualFold(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldNonce), v)) - }) + return predicate.RefreshToken(sql.FieldEqualFold(FieldNonce, v)) } // NonceContainsFold applies the ContainsFold predicate on the "nonce" field. func NonceContainsFold(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldNonce), v)) - }) + return predicate.RefreshToken(sql.FieldContainsFold(FieldNonce, v)) } // ClaimsUserIDEQ applies the EQ predicate on the "claims_user_id" field. func ClaimsUserIDEQ(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsUserID), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldClaimsUserID, v)) } // ClaimsUserIDNEQ applies the NEQ predicate on the "claims_user_id" field. func ClaimsUserIDNEQ(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClaimsUserID), v)) - }) + return predicate.RefreshToken(sql.FieldNEQ(FieldClaimsUserID, v)) } // ClaimsUserIDIn applies the In predicate on the "claims_user_id" field. func ClaimsUserIDIn(vs ...string) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldClaimsUserID), v...)) - }) + return predicate.RefreshToken(sql.FieldIn(FieldClaimsUserID, vs...)) } // ClaimsUserIDNotIn applies the NotIn predicate on the "claims_user_id" field. func ClaimsUserIDNotIn(vs ...string) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldClaimsUserID), v...)) - }) + return predicate.RefreshToken(sql.FieldNotIn(FieldClaimsUserID, vs...)) } // ClaimsUserIDGT applies the GT predicate on the "claims_user_id" field. func ClaimsUserIDGT(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldClaimsUserID), v)) - }) + return predicate.RefreshToken(sql.FieldGT(FieldClaimsUserID, v)) } // ClaimsUserIDGTE applies the GTE predicate on the "claims_user_id" field. func ClaimsUserIDGTE(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldClaimsUserID), v)) - }) + return predicate.RefreshToken(sql.FieldGTE(FieldClaimsUserID, v)) } // ClaimsUserIDLT applies the LT predicate on the "claims_user_id" field. func ClaimsUserIDLT(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldClaimsUserID), v)) - }) + return predicate.RefreshToken(sql.FieldLT(FieldClaimsUserID, v)) } // ClaimsUserIDLTE applies the LTE predicate on the "claims_user_id" field. func ClaimsUserIDLTE(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldClaimsUserID), v)) - }) + return predicate.RefreshToken(sql.FieldLTE(FieldClaimsUserID, v)) } // ClaimsUserIDContains applies the Contains predicate on the "claims_user_id" field. func ClaimsUserIDContains(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldClaimsUserID), v)) - }) + return predicate.RefreshToken(sql.FieldContains(FieldClaimsUserID, v)) } // ClaimsUserIDHasPrefix applies the HasPrefix predicate on the "claims_user_id" field. func ClaimsUserIDHasPrefix(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldClaimsUserID), v)) - }) + return predicate.RefreshToken(sql.FieldHasPrefix(FieldClaimsUserID, v)) } // ClaimsUserIDHasSuffix applies the HasSuffix predicate on the "claims_user_id" field. func ClaimsUserIDHasSuffix(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldClaimsUserID), v)) - }) + return predicate.RefreshToken(sql.FieldHasSuffix(FieldClaimsUserID, v)) } // ClaimsUserIDEqualFold applies the EqualFold predicate on the "claims_user_id" field. func ClaimsUserIDEqualFold(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldClaimsUserID), v)) - }) + return predicate.RefreshToken(sql.FieldEqualFold(FieldClaimsUserID, v)) } // ClaimsUserIDContainsFold applies the ContainsFold predicate on the "claims_user_id" field. func ClaimsUserIDContainsFold(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldClaimsUserID), v)) - }) + return predicate.RefreshToken(sql.FieldContainsFold(FieldClaimsUserID, v)) } // ClaimsUsernameEQ applies the EQ predicate on the "claims_username" field. func ClaimsUsernameEQ(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsUsername), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldClaimsUsername, v)) } // ClaimsUsernameNEQ applies the NEQ predicate on the "claims_username" field. func ClaimsUsernameNEQ(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClaimsUsername), v)) - }) + return predicate.RefreshToken(sql.FieldNEQ(FieldClaimsUsername, v)) } // ClaimsUsernameIn applies the In predicate on the "claims_username" field. func ClaimsUsernameIn(vs ...string) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldClaimsUsername), v...)) - }) + return predicate.RefreshToken(sql.FieldIn(FieldClaimsUsername, vs...)) } // ClaimsUsernameNotIn applies the NotIn predicate on the "claims_username" field. func ClaimsUsernameNotIn(vs ...string) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldClaimsUsername), v...)) - }) + return predicate.RefreshToken(sql.FieldNotIn(FieldClaimsUsername, vs...)) } // ClaimsUsernameGT applies the GT predicate on the "claims_username" field. func ClaimsUsernameGT(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldClaimsUsername), v)) - }) + return predicate.RefreshToken(sql.FieldGT(FieldClaimsUsername, v)) } // ClaimsUsernameGTE applies the GTE predicate on the "claims_username" field. func ClaimsUsernameGTE(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldClaimsUsername), v)) - }) + return predicate.RefreshToken(sql.FieldGTE(FieldClaimsUsername, v)) } // ClaimsUsernameLT applies the LT predicate on the "claims_username" field. func ClaimsUsernameLT(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldClaimsUsername), v)) - }) + return predicate.RefreshToken(sql.FieldLT(FieldClaimsUsername, v)) } // ClaimsUsernameLTE applies the LTE predicate on the "claims_username" field. func ClaimsUsernameLTE(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldClaimsUsername), v)) - }) + return predicate.RefreshToken(sql.FieldLTE(FieldClaimsUsername, v)) } // ClaimsUsernameContains applies the Contains predicate on the "claims_username" field. func ClaimsUsernameContains(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldClaimsUsername), v)) - }) + return predicate.RefreshToken(sql.FieldContains(FieldClaimsUsername, v)) } // ClaimsUsernameHasPrefix applies the HasPrefix predicate on the "claims_username" field. func ClaimsUsernameHasPrefix(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldClaimsUsername), v)) - }) + return predicate.RefreshToken(sql.FieldHasPrefix(FieldClaimsUsername, v)) } // ClaimsUsernameHasSuffix applies the HasSuffix predicate on the "claims_username" field. func ClaimsUsernameHasSuffix(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldClaimsUsername), v)) - }) + return predicate.RefreshToken(sql.FieldHasSuffix(FieldClaimsUsername, v)) } // ClaimsUsernameEqualFold applies the EqualFold predicate on the "claims_username" field. func ClaimsUsernameEqualFold(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldClaimsUsername), v)) - }) + return predicate.RefreshToken(sql.FieldEqualFold(FieldClaimsUsername, v)) } // ClaimsUsernameContainsFold applies the ContainsFold predicate on the "claims_username" field. func ClaimsUsernameContainsFold(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldClaimsUsername), v)) - }) + return predicate.RefreshToken(sql.FieldContainsFold(FieldClaimsUsername, v)) } // ClaimsEmailEQ applies the EQ predicate on the "claims_email" field. func ClaimsEmailEQ(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsEmail), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldClaimsEmail, v)) } // ClaimsEmailNEQ applies the NEQ predicate on the "claims_email" field. func ClaimsEmailNEQ(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClaimsEmail), v)) - }) + return predicate.RefreshToken(sql.FieldNEQ(FieldClaimsEmail, v)) } // ClaimsEmailIn applies the In predicate on the "claims_email" field. func ClaimsEmailIn(vs ...string) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldClaimsEmail), v...)) - }) + return predicate.RefreshToken(sql.FieldIn(FieldClaimsEmail, vs...)) } // ClaimsEmailNotIn applies the NotIn predicate on the "claims_email" field. func ClaimsEmailNotIn(vs ...string) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldClaimsEmail), v...)) - }) + return predicate.RefreshToken(sql.FieldNotIn(FieldClaimsEmail, vs...)) } // ClaimsEmailGT applies the GT predicate on the "claims_email" field. func ClaimsEmailGT(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldClaimsEmail), v)) - }) + return predicate.RefreshToken(sql.FieldGT(FieldClaimsEmail, v)) } // ClaimsEmailGTE applies the GTE predicate on the "claims_email" field. func ClaimsEmailGTE(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldClaimsEmail), v)) - }) + return predicate.RefreshToken(sql.FieldGTE(FieldClaimsEmail, v)) } // ClaimsEmailLT applies the LT predicate on the "claims_email" field. func ClaimsEmailLT(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldClaimsEmail), v)) - }) + return predicate.RefreshToken(sql.FieldLT(FieldClaimsEmail, v)) } // ClaimsEmailLTE applies the LTE predicate on the "claims_email" field. func ClaimsEmailLTE(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldClaimsEmail), v)) - }) + return predicate.RefreshToken(sql.FieldLTE(FieldClaimsEmail, v)) } // ClaimsEmailContains applies the Contains predicate on the "claims_email" field. func ClaimsEmailContains(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldClaimsEmail), v)) - }) + return predicate.RefreshToken(sql.FieldContains(FieldClaimsEmail, v)) } // ClaimsEmailHasPrefix applies the HasPrefix predicate on the "claims_email" field. func ClaimsEmailHasPrefix(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldClaimsEmail), v)) - }) + return predicate.RefreshToken(sql.FieldHasPrefix(FieldClaimsEmail, v)) } // ClaimsEmailHasSuffix applies the HasSuffix predicate on the "claims_email" field. func ClaimsEmailHasSuffix(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldClaimsEmail), v)) - }) + return predicate.RefreshToken(sql.FieldHasSuffix(FieldClaimsEmail, v)) } // ClaimsEmailEqualFold applies the EqualFold predicate on the "claims_email" field. func ClaimsEmailEqualFold(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldClaimsEmail), v)) - }) + return predicate.RefreshToken(sql.FieldEqualFold(FieldClaimsEmail, v)) } // ClaimsEmailContainsFold applies the ContainsFold predicate on the "claims_email" field. func ClaimsEmailContainsFold(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldClaimsEmail), v)) - }) + return predicate.RefreshToken(sql.FieldContainsFold(FieldClaimsEmail, v)) } // ClaimsEmailVerifiedEQ applies the EQ predicate on the "claims_email_verified" field. func ClaimsEmailVerifiedEQ(v bool) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsEmailVerified), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldClaimsEmailVerified, v)) } // ClaimsEmailVerifiedNEQ applies the NEQ predicate on the "claims_email_verified" field. func ClaimsEmailVerifiedNEQ(v bool) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClaimsEmailVerified), v)) - }) + return predicate.RefreshToken(sql.FieldNEQ(FieldClaimsEmailVerified, v)) } // ClaimsGroupsIsNil applies the IsNil predicate on the "claims_groups" field. func ClaimsGroupsIsNil() predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.IsNull(s.C(FieldClaimsGroups))) - }) + return predicate.RefreshToken(sql.FieldIsNull(FieldClaimsGroups)) } // ClaimsGroupsNotNil applies the NotNil predicate on the "claims_groups" field. func ClaimsGroupsNotNil() predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NotNull(s.C(FieldClaimsGroups))) - }) + return predicate.RefreshToken(sql.FieldNotNull(FieldClaimsGroups)) } // ClaimsPreferredUsernameEQ applies the EQ predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameEQ(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameNEQ applies the NEQ predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameNEQ(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.RefreshToken(sql.FieldNEQ(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameIn applies the In predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameIn(vs ...string) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldClaimsPreferredUsername), v...)) - }) + return predicate.RefreshToken(sql.FieldIn(FieldClaimsPreferredUsername, vs...)) } // ClaimsPreferredUsernameNotIn applies the NotIn predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameNotIn(vs ...string) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldClaimsPreferredUsername), v...)) - }) + return predicate.RefreshToken(sql.FieldNotIn(FieldClaimsPreferredUsername, vs...)) } // ClaimsPreferredUsernameGT applies the GT predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameGT(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.RefreshToken(sql.FieldGT(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameGTE applies the GTE predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameGTE(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.RefreshToken(sql.FieldGTE(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameLT applies the LT predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameLT(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.RefreshToken(sql.FieldLT(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameLTE applies the LTE predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameLTE(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.RefreshToken(sql.FieldLTE(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameContains applies the Contains predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameContains(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.RefreshToken(sql.FieldContains(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameHasPrefix applies the HasPrefix predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameHasPrefix(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.RefreshToken(sql.FieldHasPrefix(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameHasSuffix applies the HasSuffix predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameHasSuffix(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.RefreshToken(sql.FieldHasSuffix(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameEqualFold applies the EqualFold predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameEqualFold(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.RefreshToken(sql.FieldEqualFold(FieldClaimsPreferredUsername, v)) } // ClaimsPreferredUsernameContainsFold applies the ContainsFold predicate on the "claims_preferred_username" field. func ClaimsPreferredUsernameContainsFold(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldClaimsPreferredUsername), v)) - }) + return predicate.RefreshToken(sql.FieldContainsFold(FieldClaimsPreferredUsername, v)) } // ConnectorIDEQ applies the EQ predicate on the "connector_id" field. func ConnectorIDEQ(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldConnectorID), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldConnectorID, v)) } // ConnectorIDNEQ applies the NEQ predicate on the "connector_id" field. func ConnectorIDNEQ(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldConnectorID), v)) - }) + return predicate.RefreshToken(sql.FieldNEQ(FieldConnectorID, v)) } // ConnectorIDIn applies the In predicate on the "connector_id" field. func ConnectorIDIn(vs ...string) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldConnectorID), v...)) - }) + return predicate.RefreshToken(sql.FieldIn(FieldConnectorID, vs...)) } // ConnectorIDNotIn applies the NotIn predicate on the "connector_id" field. func ConnectorIDNotIn(vs ...string) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldConnectorID), v...)) - }) + return predicate.RefreshToken(sql.FieldNotIn(FieldConnectorID, vs...)) } // ConnectorIDGT applies the GT predicate on the "connector_id" field. func ConnectorIDGT(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldConnectorID), v)) - }) + return predicate.RefreshToken(sql.FieldGT(FieldConnectorID, v)) } // ConnectorIDGTE applies the GTE predicate on the "connector_id" field. func ConnectorIDGTE(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldConnectorID), v)) - }) + return predicate.RefreshToken(sql.FieldGTE(FieldConnectorID, v)) } // ConnectorIDLT applies the LT predicate on the "connector_id" field. func ConnectorIDLT(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldConnectorID), v)) - }) + return predicate.RefreshToken(sql.FieldLT(FieldConnectorID, v)) } // ConnectorIDLTE applies the LTE predicate on the "connector_id" field. func ConnectorIDLTE(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldConnectorID), v)) - }) + return predicate.RefreshToken(sql.FieldLTE(FieldConnectorID, v)) } // ConnectorIDContains applies the Contains predicate on the "connector_id" field. func ConnectorIDContains(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldConnectorID), v)) - }) + return predicate.RefreshToken(sql.FieldContains(FieldConnectorID, v)) } // ConnectorIDHasPrefix applies the HasPrefix predicate on the "connector_id" field. func ConnectorIDHasPrefix(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldConnectorID), v)) - }) + return predicate.RefreshToken(sql.FieldHasPrefix(FieldConnectorID, v)) } // ConnectorIDHasSuffix applies the HasSuffix predicate on the "connector_id" field. func ConnectorIDHasSuffix(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldConnectorID), v)) - }) + return predicate.RefreshToken(sql.FieldHasSuffix(FieldConnectorID, v)) } // ConnectorIDEqualFold applies the EqualFold predicate on the "connector_id" field. func ConnectorIDEqualFold(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldConnectorID), v)) - }) + return predicate.RefreshToken(sql.FieldEqualFold(FieldConnectorID, v)) } // ConnectorIDContainsFold applies the ContainsFold predicate on the "connector_id" field. func ConnectorIDContainsFold(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldConnectorID), v)) - }) + return predicate.RefreshToken(sql.FieldContainsFold(FieldConnectorID, v)) } // ConnectorDataEQ applies the EQ predicate on the "connector_data" field. func ConnectorDataEQ(v []byte) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldConnectorData), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldConnectorData, v)) } // ConnectorDataNEQ applies the NEQ predicate on the "connector_data" field. func ConnectorDataNEQ(v []byte) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldConnectorData), v)) - }) + return predicate.RefreshToken(sql.FieldNEQ(FieldConnectorData, v)) } // ConnectorDataIn applies the In predicate on the "connector_data" field. func ConnectorDataIn(vs ...[]byte) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldConnectorData), v...)) - }) + return predicate.RefreshToken(sql.FieldIn(FieldConnectorData, vs...)) } // ConnectorDataNotIn applies the NotIn predicate on the "connector_data" field. func ConnectorDataNotIn(vs ...[]byte) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldConnectorData), v...)) - }) + return predicate.RefreshToken(sql.FieldNotIn(FieldConnectorData, vs...)) } // ConnectorDataGT applies the GT predicate on the "connector_data" field. func ConnectorDataGT(v []byte) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldConnectorData), v)) - }) + return predicate.RefreshToken(sql.FieldGT(FieldConnectorData, v)) } // ConnectorDataGTE applies the GTE predicate on the "connector_data" field. func ConnectorDataGTE(v []byte) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldConnectorData), v)) - }) + return predicate.RefreshToken(sql.FieldGTE(FieldConnectorData, v)) } // ConnectorDataLT applies the LT predicate on the "connector_data" field. func ConnectorDataLT(v []byte) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldConnectorData), v)) - }) + return predicate.RefreshToken(sql.FieldLT(FieldConnectorData, v)) } // ConnectorDataLTE applies the LTE predicate on the "connector_data" field. func ConnectorDataLTE(v []byte) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldConnectorData), v)) - }) + return predicate.RefreshToken(sql.FieldLTE(FieldConnectorData, v)) } // ConnectorDataIsNil applies the IsNil predicate on the "connector_data" field. func ConnectorDataIsNil() predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.IsNull(s.C(FieldConnectorData))) - }) + return predicate.RefreshToken(sql.FieldIsNull(FieldConnectorData)) } // ConnectorDataNotNil applies the NotNil predicate on the "connector_data" field. func ConnectorDataNotNil() predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NotNull(s.C(FieldConnectorData))) - }) + return predicate.RefreshToken(sql.FieldNotNull(FieldConnectorData)) } // TokenEQ applies the EQ predicate on the "token" field. func TokenEQ(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldToken), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldToken, v)) } // TokenNEQ applies the NEQ predicate on the "token" field. func TokenNEQ(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldToken), v)) - }) + return predicate.RefreshToken(sql.FieldNEQ(FieldToken, v)) } // TokenIn applies the In predicate on the "token" field. func TokenIn(vs ...string) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldToken), v...)) - }) + return predicate.RefreshToken(sql.FieldIn(FieldToken, vs...)) } // TokenNotIn applies the NotIn predicate on the "token" field. func TokenNotIn(vs ...string) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldToken), v...)) - }) + return predicate.RefreshToken(sql.FieldNotIn(FieldToken, vs...)) } // TokenGT applies the GT predicate on the "token" field. func TokenGT(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldToken), v)) - }) + return predicate.RefreshToken(sql.FieldGT(FieldToken, v)) } // TokenGTE applies the GTE predicate on the "token" field. func TokenGTE(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldToken), v)) - }) + return predicate.RefreshToken(sql.FieldGTE(FieldToken, v)) } // TokenLT applies the LT predicate on the "token" field. func TokenLT(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldToken), v)) - }) + return predicate.RefreshToken(sql.FieldLT(FieldToken, v)) } // TokenLTE applies the LTE predicate on the "token" field. func TokenLTE(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldToken), v)) - }) + return predicate.RefreshToken(sql.FieldLTE(FieldToken, v)) } // TokenContains applies the Contains predicate on the "token" field. func TokenContains(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldToken), v)) - }) + return predicate.RefreshToken(sql.FieldContains(FieldToken, v)) } // TokenHasPrefix applies the HasPrefix predicate on the "token" field. func TokenHasPrefix(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldToken), v)) - }) + return predicate.RefreshToken(sql.FieldHasPrefix(FieldToken, v)) } // TokenHasSuffix applies the HasSuffix predicate on the "token" field. func TokenHasSuffix(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldToken), v)) - }) + return predicate.RefreshToken(sql.FieldHasSuffix(FieldToken, v)) } // TokenEqualFold applies the EqualFold predicate on the "token" field. func TokenEqualFold(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldToken), v)) - }) + return predicate.RefreshToken(sql.FieldEqualFold(FieldToken, v)) } // TokenContainsFold applies the ContainsFold predicate on the "token" field. func TokenContainsFold(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldToken), v)) - }) + return predicate.RefreshToken(sql.FieldContainsFold(FieldToken, v)) } // ObsoleteTokenEQ applies the EQ predicate on the "obsolete_token" field. func ObsoleteTokenEQ(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldObsoleteToken), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldObsoleteToken, v)) } // ObsoleteTokenNEQ applies the NEQ predicate on the "obsolete_token" field. func ObsoleteTokenNEQ(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldObsoleteToken), v)) - }) + return predicate.RefreshToken(sql.FieldNEQ(FieldObsoleteToken, v)) } // ObsoleteTokenIn applies the In predicate on the "obsolete_token" field. func ObsoleteTokenIn(vs ...string) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldObsoleteToken), v...)) - }) + return predicate.RefreshToken(sql.FieldIn(FieldObsoleteToken, vs...)) } // ObsoleteTokenNotIn applies the NotIn predicate on the "obsolete_token" field. func ObsoleteTokenNotIn(vs ...string) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldObsoleteToken), v...)) - }) + return predicate.RefreshToken(sql.FieldNotIn(FieldObsoleteToken, vs...)) } // ObsoleteTokenGT applies the GT predicate on the "obsolete_token" field. func ObsoleteTokenGT(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldObsoleteToken), v)) - }) + return predicate.RefreshToken(sql.FieldGT(FieldObsoleteToken, v)) } // ObsoleteTokenGTE applies the GTE predicate on the "obsolete_token" field. func ObsoleteTokenGTE(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldObsoleteToken), v)) - }) + return predicate.RefreshToken(sql.FieldGTE(FieldObsoleteToken, v)) } // ObsoleteTokenLT applies the LT predicate on the "obsolete_token" field. func ObsoleteTokenLT(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldObsoleteToken), v)) - }) + return predicate.RefreshToken(sql.FieldLT(FieldObsoleteToken, v)) } // ObsoleteTokenLTE applies the LTE predicate on the "obsolete_token" field. func ObsoleteTokenLTE(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldObsoleteToken), v)) - }) + return predicate.RefreshToken(sql.FieldLTE(FieldObsoleteToken, v)) } // ObsoleteTokenContains applies the Contains predicate on the "obsolete_token" field. func ObsoleteTokenContains(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.Contains(s.C(FieldObsoleteToken), v)) - }) + return predicate.RefreshToken(sql.FieldContains(FieldObsoleteToken, v)) } // ObsoleteTokenHasPrefix applies the HasPrefix predicate on the "obsolete_token" field. func ObsoleteTokenHasPrefix(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.HasPrefix(s.C(FieldObsoleteToken), v)) - }) + return predicate.RefreshToken(sql.FieldHasPrefix(FieldObsoleteToken, v)) } // ObsoleteTokenHasSuffix applies the HasSuffix predicate on the "obsolete_token" field. func ObsoleteTokenHasSuffix(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.HasSuffix(s.C(FieldObsoleteToken), v)) - }) + return predicate.RefreshToken(sql.FieldHasSuffix(FieldObsoleteToken, v)) } // ObsoleteTokenEqualFold applies the EqualFold predicate on the "obsolete_token" field. func ObsoleteTokenEqualFold(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EqualFold(s.C(FieldObsoleteToken), v)) - }) + return predicate.RefreshToken(sql.FieldEqualFold(FieldObsoleteToken, v)) } // ObsoleteTokenContainsFold applies the ContainsFold predicate on the "obsolete_token" field. func ObsoleteTokenContainsFold(v string) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.ContainsFold(s.C(FieldObsoleteToken), v)) - }) + return predicate.RefreshToken(sql.FieldContainsFold(FieldObsoleteToken, v)) } // CreatedAtEQ applies the EQ predicate on the "created_at" field. func CreatedAtEQ(v time.Time) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldCreatedAt), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldCreatedAt, v)) } // CreatedAtNEQ applies the NEQ predicate on the "created_at" field. func CreatedAtNEQ(v time.Time) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldCreatedAt), v)) - }) + return predicate.RefreshToken(sql.FieldNEQ(FieldCreatedAt, v)) } // CreatedAtIn applies the In predicate on the "created_at" field. func CreatedAtIn(vs ...time.Time) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldCreatedAt), v...)) - }) + return predicate.RefreshToken(sql.FieldIn(FieldCreatedAt, vs...)) } // CreatedAtNotIn applies the NotIn predicate on the "created_at" field. func CreatedAtNotIn(vs ...time.Time) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldCreatedAt), v...)) - }) + return predicate.RefreshToken(sql.FieldNotIn(FieldCreatedAt, vs...)) } // CreatedAtGT applies the GT predicate on the "created_at" field. func CreatedAtGT(v time.Time) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldCreatedAt), v)) - }) + return predicate.RefreshToken(sql.FieldGT(FieldCreatedAt, v)) } // CreatedAtGTE applies the GTE predicate on the "created_at" field. func CreatedAtGTE(v time.Time) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldCreatedAt), v)) - }) + return predicate.RefreshToken(sql.FieldGTE(FieldCreatedAt, v)) } // CreatedAtLT applies the LT predicate on the "created_at" field. func CreatedAtLT(v time.Time) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldCreatedAt), v)) - }) + return predicate.RefreshToken(sql.FieldLT(FieldCreatedAt, v)) } // CreatedAtLTE applies the LTE predicate on the "created_at" field. func CreatedAtLTE(v time.Time) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldCreatedAt), v)) - }) + return predicate.RefreshToken(sql.FieldLTE(FieldCreatedAt, v)) } // LastUsedEQ applies the EQ predicate on the "last_used" field. func LastUsedEQ(v time.Time) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldLastUsed), v)) - }) + return predicate.RefreshToken(sql.FieldEQ(FieldLastUsed, v)) } // LastUsedNEQ applies the NEQ predicate on the "last_used" field. func LastUsedNEQ(v time.Time) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldLastUsed), v)) - }) + return predicate.RefreshToken(sql.FieldNEQ(FieldLastUsed, v)) } // LastUsedIn applies the In predicate on the "last_used" field. func LastUsedIn(vs ...time.Time) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.In(s.C(FieldLastUsed), v...)) - }) + return predicate.RefreshToken(sql.FieldIn(FieldLastUsed, vs...)) } // LastUsedNotIn applies the NotIn predicate on the "last_used" field. func LastUsedNotIn(vs ...time.Time) predicate.RefreshToken { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.NotIn(s.C(FieldLastUsed), v...)) - }) + return predicate.RefreshToken(sql.FieldNotIn(FieldLastUsed, vs...)) } // LastUsedGT applies the GT predicate on the "last_used" field. func LastUsedGT(v time.Time) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldLastUsed), v)) - }) + return predicate.RefreshToken(sql.FieldGT(FieldLastUsed, v)) } // LastUsedGTE applies the GTE predicate on the "last_used" field. func LastUsedGTE(v time.Time) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldLastUsed), v)) - }) + return predicate.RefreshToken(sql.FieldGTE(FieldLastUsed, v)) } // LastUsedLT applies the LT predicate on the "last_used" field. func LastUsedLT(v time.Time) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldLastUsed), v)) - }) + return predicate.RefreshToken(sql.FieldLT(FieldLastUsed, v)) } // LastUsedLTE applies the LTE predicate on the "last_used" field. func LastUsedLTE(v time.Time) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldLastUsed), v)) - }) + return predicate.RefreshToken(sql.FieldLTE(FieldLastUsed, v)) } // And groups predicates with the AND operator between them. func And(predicates ...predicate.RefreshToken) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for _, p := range predicates { - p(s1) - } - s.Where(s1.P()) - }) + return predicate.RefreshToken(sql.AndPredicates(predicates...)) } // Or groups predicates with the OR operator between them. func Or(predicates ...predicate.RefreshToken) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - s1 := s.Clone().SetP(nil) - for i, p := range predicates { - if i > 0 { - s1.Or() - } - p(s1) - } - s.Where(s1.P()) - }) + return predicate.RefreshToken(sql.OrPredicates(predicates...)) } // Not applies the not operator on the given predicate. func Not(p predicate.RefreshToken) predicate.RefreshToken { - return predicate.RefreshToken(func(s *sql.Selector) { - p(s.Not()) - }) + return predicate.RefreshToken(sql.NotPredicates(p)) } diff --git a/storage/ent/db/refreshtoken_create.go b/storage/ent/db/refreshtoken_create.go index e2bd6c2fad..2feb6f2c27 100644 --- a/storage/ent/db/refreshtoken_create.go +++ b/storage/ent/db/refreshtoken_create.go @@ -21,197 +21,155 @@ type RefreshTokenCreate struct { } // SetClientID sets the "client_id" field. -func (rtc *RefreshTokenCreate) SetClientID(s string) *RefreshTokenCreate { - rtc.mutation.SetClientID(s) - return rtc +func (_c *RefreshTokenCreate) SetClientID(v string) *RefreshTokenCreate { + _c.mutation.SetClientID(v) + return _c } // SetScopes sets the "scopes" field. -func (rtc *RefreshTokenCreate) SetScopes(s []string) *RefreshTokenCreate { - rtc.mutation.SetScopes(s) - return rtc +func (_c *RefreshTokenCreate) SetScopes(v []string) *RefreshTokenCreate { + _c.mutation.SetScopes(v) + return _c } // SetNonce sets the "nonce" field. -func (rtc *RefreshTokenCreate) SetNonce(s string) *RefreshTokenCreate { - rtc.mutation.SetNonce(s) - return rtc +func (_c *RefreshTokenCreate) SetNonce(v string) *RefreshTokenCreate { + _c.mutation.SetNonce(v) + return _c } // SetClaimsUserID sets the "claims_user_id" field. -func (rtc *RefreshTokenCreate) SetClaimsUserID(s string) *RefreshTokenCreate { - rtc.mutation.SetClaimsUserID(s) - return rtc +func (_c *RefreshTokenCreate) SetClaimsUserID(v string) *RefreshTokenCreate { + _c.mutation.SetClaimsUserID(v) + return _c } // SetClaimsUsername sets the "claims_username" field. -func (rtc *RefreshTokenCreate) SetClaimsUsername(s string) *RefreshTokenCreate { - rtc.mutation.SetClaimsUsername(s) - return rtc +func (_c *RefreshTokenCreate) SetClaimsUsername(v string) *RefreshTokenCreate { + _c.mutation.SetClaimsUsername(v) + return _c } // SetClaimsEmail sets the "claims_email" field. -func (rtc *RefreshTokenCreate) SetClaimsEmail(s string) *RefreshTokenCreate { - rtc.mutation.SetClaimsEmail(s) - return rtc +func (_c *RefreshTokenCreate) SetClaimsEmail(v string) *RefreshTokenCreate { + _c.mutation.SetClaimsEmail(v) + return _c } // SetClaimsEmailVerified sets the "claims_email_verified" field. -func (rtc *RefreshTokenCreate) SetClaimsEmailVerified(b bool) *RefreshTokenCreate { - rtc.mutation.SetClaimsEmailVerified(b) - return rtc +func (_c *RefreshTokenCreate) SetClaimsEmailVerified(v bool) *RefreshTokenCreate { + _c.mutation.SetClaimsEmailVerified(v) + return _c } // SetClaimsGroups sets the "claims_groups" field. -func (rtc *RefreshTokenCreate) SetClaimsGroups(s []string) *RefreshTokenCreate { - rtc.mutation.SetClaimsGroups(s) - return rtc +func (_c *RefreshTokenCreate) SetClaimsGroups(v []string) *RefreshTokenCreate { + _c.mutation.SetClaimsGroups(v) + return _c } // SetClaimsPreferredUsername sets the "claims_preferred_username" field. -func (rtc *RefreshTokenCreate) SetClaimsPreferredUsername(s string) *RefreshTokenCreate { - rtc.mutation.SetClaimsPreferredUsername(s) - return rtc +func (_c *RefreshTokenCreate) SetClaimsPreferredUsername(v string) *RefreshTokenCreate { + _c.mutation.SetClaimsPreferredUsername(v) + return _c } // SetNillableClaimsPreferredUsername sets the "claims_preferred_username" field if the given value is not nil. -func (rtc *RefreshTokenCreate) SetNillableClaimsPreferredUsername(s *string) *RefreshTokenCreate { - if s != nil { - rtc.SetClaimsPreferredUsername(*s) +func (_c *RefreshTokenCreate) SetNillableClaimsPreferredUsername(v *string) *RefreshTokenCreate { + if v != nil { + _c.SetClaimsPreferredUsername(*v) } - return rtc + return _c } // SetConnectorID sets the "connector_id" field. -func (rtc *RefreshTokenCreate) SetConnectorID(s string) *RefreshTokenCreate { - rtc.mutation.SetConnectorID(s) - return rtc +func (_c *RefreshTokenCreate) SetConnectorID(v string) *RefreshTokenCreate { + _c.mutation.SetConnectorID(v) + return _c } // SetConnectorData sets the "connector_data" field. -func (rtc *RefreshTokenCreate) SetConnectorData(b []byte) *RefreshTokenCreate { - rtc.mutation.SetConnectorData(b) - return rtc +func (_c *RefreshTokenCreate) SetConnectorData(v []byte) *RefreshTokenCreate { + _c.mutation.SetConnectorData(v) + return _c } // SetToken sets the "token" field. -func (rtc *RefreshTokenCreate) SetToken(s string) *RefreshTokenCreate { - rtc.mutation.SetToken(s) - return rtc +func (_c *RefreshTokenCreate) SetToken(v string) *RefreshTokenCreate { + _c.mutation.SetToken(v) + return _c } // SetNillableToken sets the "token" field if the given value is not nil. -func (rtc *RefreshTokenCreate) SetNillableToken(s *string) *RefreshTokenCreate { - if s != nil { - rtc.SetToken(*s) +func (_c *RefreshTokenCreate) SetNillableToken(v *string) *RefreshTokenCreate { + if v != nil { + _c.SetToken(*v) } - return rtc + return _c } // SetObsoleteToken sets the "obsolete_token" field. -func (rtc *RefreshTokenCreate) SetObsoleteToken(s string) *RefreshTokenCreate { - rtc.mutation.SetObsoleteToken(s) - return rtc +func (_c *RefreshTokenCreate) SetObsoleteToken(v string) *RefreshTokenCreate { + _c.mutation.SetObsoleteToken(v) + return _c } // SetNillableObsoleteToken sets the "obsolete_token" field if the given value is not nil. -func (rtc *RefreshTokenCreate) SetNillableObsoleteToken(s *string) *RefreshTokenCreate { - if s != nil { - rtc.SetObsoleteToken(*s) +func (_c *RefreshTokenCreate) SetNillableObsoleteToken(v *string) *RefreshTokenCreate { + if v != nil { + _c.SetObsoleteToken(*v) } - return rtc + return _c } // SetCreatedAt sets the "created_at" field. -func (rtc *RefreshTokenCreate) SetCreatedAt(t time.Time) *RefreshTokenCreate { - rtc.mutation.SetCreatedAt(t) - return rtc +func (_c *RefreshTokenCreate) SetCreatedAt(v time.Time) *RefreshTokenCreate { + _c.mutation.SetCreatedAt(v) + return _c } // SetNillableCreatedAt sets the "created_at" field if the given value is not nil. -func (rtc *RefreshTokenCreate) SetNillableCreatedAt(t *time.Time) *RefreshTokenCreate { - if t != nil { - rtc.SetCreatedAt(*t) +func (_c *RefreshTokenCreate) SetNillableCreatedAt(v *time.Time) *RefreshTokenCreate { + if v != nil { + _c.SetCreatedAt(*v) } - return rtc + return _c } // SetLastUsed sets the "last_used" field. -func (rtc *RefreshTokenCreate) SetLastUsed(t time.Time) *RefreshTokenCreate { - rtc.mutation.SetLastUsed(t) - return rtc +func (_c *RefreshTokenCreate) SetLastUsed(v time.Time) *RefreshTokenCreate { + _c.mutation.SetLastUsed(v) + return _c } // SetNillableLastUsed sets the "last_used" field if the given value is not nil. -func (rtc *RefreshTokenCreate) SetNillableLastUsed(t *time.Time) *RefreshTokenCreate { - if t != nil { - rtc.SetLastUsed(*t) +func (_c *RefreshTokenCreate) SetNillableLastUsed(v *time.Time) *RefreshTokenCreate { + if v != nil { + _c.SetLastUsed(*v) } - return rtc + return _c } // SetID sets the "id" field. -func (rtc *RefreshTokenCreate) SetID(s string) *RefreshTokenCreate { - rtc.mutation.SetID(s) - return rtc +func (_c *RefreshTokenCreate) SetID(v string) *RefreshTokenCreate { + _c.mutation.SetID(v) + return _c } // Mutation returns the RefreshTokenMutation object of the builder. -func (rtc *RefreshTokenCreate) Mutation() *RefreshTokenMutation { - return rtc.mutation +func (_c *RefreshTokenCreate) Mutation() *RefreshTokenMutation { + return _c.mutation } // Save creates the RefreshToken in the database. -func (rtc *RefreshTokenCreate) Save(ctx context.Context) (*RefreshToken, error) { - var ( - err error - node *RefreshToken - ) - rtc.defaults() - if len(rtc.hooks) == 0 { - if err = rtc.check(); err != nil { - return nil, err - } - node, err = rtc.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*RefreshTokenMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = rtc.check(); err != nil { - return nil, err - } - rtc.mutation = mutation - if node, err = rtc.sqlSave(ctx); err != nil { - return nil, err - } - mutation.id = &node.ID - mutation.done = true - return node, err - }) - for i := len(rtc.hooks) - 1; i >= 0; i-- { - if rtc.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = rtc.hooks[i](mut) - } - v, err := mut.Mutate(ctx, rtc.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*RefreshToken) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from RefreshTokenMutation", v) - } - node = nv - } - return node, err +func (_c *RefreshTokenCreate) Save(ctx context.Context) (*RefreshToken, error) { + _c.defaults() + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) } // SaveX calls Save and panics if Save returns an error. -func (rtc *RefreshTokenCreate) SaveX(ctx context.Context) *RefreshToken { - v, err := rtc.Save(ctx) +func (_c *RefreshTokenCreate) SaveX(ctx context.Context) *RefreshToken { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -219,111 +177,111 @@ func (rtc *RefreshTokenCreate) SaveX(ctx context.Context) *RefreshToken { } // Exec executes the query. -func (rtc *RefreshTokenCreate) Exec(ctx context.Context) error { - _, err := rtc.Save(ctx) +func (_c *RefreshTokenCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (rtc *RefreshTokenCreate) ExecX(ctx context.Context) { - if err := rtc.Exec(ctx); err != nil { +func (_c *RefreshTokenCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } // defaults sets the default values of the builder before save. -func (rtc *RefreshTokenCreate) defaults() { - if _, ok := rtc.mutation.ClaimsPreferredUsername(); !ok { +func (_c *RefreshTokenCreate) defaults() { + if _, ok := _c.mutation.ClaimsPreferredUsername(); !ok { v := refreshtoken.DefaultClaimsPreferredUsername - rtc.mutation.SetClaimsPreferredUsername(v) + _c.mutation.SetClaimsPreferredUsername(v) } - if _, ok := rtc.mutation.Token(); !ok { + if _, ok := _c.mutation.Token(); !ok { v := refreshtoken.DefaultToken - rtc.mutation.SetToken(v) + _c.mutation.SetToken(v) } - if _, ok := rtc.mutation.ObsoleteToken(); !ok { + if _, ok := _c.mutation.ObsoleteToken(); !ok { v := refreshtoken.DefaultObsoleteToken - rtc.mutation.SetObsoleteToken(v) + _c.mutation.SetObsoleteToken(v) } - if _, ok := rtc.mutation.CreatedAt(); !ok { + if _, ok := _c.mutation.CreatedAt(); !ok { v := refreshtoken.DefaultCreatedAt() - rtc.mutation.SetCreatedAt(v) + _c.mutation.SetCreatedAt(v) } - if _, ok := rtc.mutation.LastUsed(); !ok { + if _, ok := _c.mutation.LastUsed(); !ok { v := refreshtoken.DefaultLastUsed() - rtc.mutation.SetLastUsed(v) + _c.mutation.SetLastUsed(v) } } // check runs all checks and user-defined validators on the builder. -func (rtc *RefreshTokenCreate) check() error { - if _, ok := rtc.mutation.ClientID(); !ok { +func (_c *RefreshTokenCreate) check() error { + if _, ok := _c.mutation.ClientID(); !ok { return &ValidationError{Name: "client_id", err: errors.New(`db: missing required field "RefreshToken.client_id"`)} } - if v, ok := rtc.mutation.ClientID(); ok { + if v, ok := _c.mutation.ClientID(); ok { if err := refreshtoken.ClientIDValidator(v); err != nil { return &ValidationError{Name: "client_id", err: fmt.Errorf(`db: validator failed for field "RefreshToken.client_id": %w`, err)} } } - if _, ok := rtc.mutation.Nonce(); !ok { + if _, ok := _c.mutation.Nonce(); !ok { return &ValidationError{Name: "nonce", err: errors.New(`db: missing required field "RefreshToken.nonce"`)} } - if v, ok := rtc.mutation.Nonce(); ok { + if v, ok := _c.mutation.Nonce(); ok { if err := refreshtoken.NonceValidator(v); err != nil { return &ValidationError{Name: "nonce", err: fmt.Errorf(`db: validator failed for field "RefreshToken.nonce": %w`, err)} } } - if _, ok := rtc.mutation.ClaimsUserID(); !ok { + if _, ok := _c.mutation.ClaimsUserID(); !ok { return &ValidationError{Name: "claims_user_id", err: errors.New(`db: missing required field "RefreshToken.claims_user_id"`)} } - if v, ok := rtc.mutation.ClaimsUserID(); ok { + if v, ok := _c.mutation.ClaimsUserID(); ok { if err := refreshtoken.ClaimsUserIDValidator(v); err != nil { return &ValidationError{Name: "claims_user_id", err: fmt.Errorf(`db: validator failed for field "RefreshToken.claims_user_id": %w`, err)} } } - if _, ok := rtc.mutation.ClaimsUsername(); !ok { + if _, ok := _c.mutation.ClaimsUsername(); !ok { return &ValidationError{Name: "claims_username", err: errors.New(`db: missing required field "RefreshToken.claims_username"`)} } - if v, ok := rtc.mutation.ClaimsUsername(); ok { + if v, ok := _c.mutation.ClaimsUsername(); ok { if err := refreshtoken.ClaimsUsernameValidator(v); err != nil { return &ValidationError{Name: "claims_username", err: fmt.Errorf(`db: validator failed for field "RefreshToken.claims_username": %w`, err)} } } - if _, ok := rtc.mutation.ClaimsEmail(); !ok { + if _, ok := _c.mutation.ClaimsEmail(); !ok { return &ValidationError{Name: "claims_email", err: errors.New(`db: missing required field "RefreshToken.claims_email"`)} } - if v, ok := rtc.mutation.ClaimsEmail(); ok { + if v, ok := _c.mutation.ClaimsEmail(); ok { if err := refreshtoken.ClaimsEmailValidator(v); err != nil { return &ValidationError{Name: "claims_email", err: fmt.Errorf(`db: validator failed for field "RefreshToken.claims_email": %w`, err)} } } - if _, ok := rtc.mutation.ClaimsEmailVerified(); !ok { + if _, ok := _c.mutation.ClaimsEmailVerified(); !ok { return &ValidationError{Name: "claims_email_verified", err: errors.New(`db: missing required field "RefreshToken.claims_email_verified"`)} } - if _, ok := rtc.mutation.ClaimsPreferredUsername(); !ok { + if _, ok := _c.mutation.ClaimsPreferredUsername(); !ok { return &ValidationError{Name: "claims_preferred_username", err: errors.New(`db: missing required field "RefreshToken.claims_preferred_username"`)} } - if _, ok := rtc.mutation.ConnectorID(); !ok { + if _, ok := _c.mutation.ConnectorID(); !ok { return &ValidationError{Name: "connector_id", err: errors.New(`db: missing required field "RefreshToken.connector_id"`)} } - if v, ok := rtc.mutation.ConnectorID(); ok { + if v, ok := _c.mutation.ConnectorID(); ok { if err := refreshtoken.ConnectorIDValidator(v); err != nil { return &ValidationError{Name: "connector_id", err: fmt.Errorf(`db: validator failed for field "RefreshToken.connector_id": %w`, err)} } } - if _, ok := rtc.mutation.Token(); !ok { + if _, ok := _c.mutation.Token(); !ok { return &ValidationError{Name: "token", err: errors.New(`db: missing required field "RefreshToken.token"`)} } - if _, ok := rtc.mutation.ObsoleteToken(); !ok { + if _, ok := _c.mutation.ObsoleteToken(); !ok { return &ValidationError{Name: "obsolete_token", err: errors.New(`db: missing required field "RefreshToken.obsolete_token"`)} } - if _, ok := rtc.mutation.CreatedAt(); !ok { + if _, ok := _c.mutation.CreatedAt(); !ok { return &ValidationError{Name: "created_at", err: errors.New(`db: missing required field "RefreshToken.created_at"`)} } - if _, ok := rtc.mutation.LastUsed(); !ok { + if _, ok := _c.mutation.LastUsed(); !ok { return &ValidationError{Name: "last_used", err: errors.New(`db: missing required field "RefreshToken.last_used"`)} } - if v, ok := rtc.mutation.ID(); ok { + if v, ok := _c.mutation.ID(); ok { if err := refreshtoken.IDValidator(v); err != nil { return &ValidationError{Name: "id", err: fmt.Errorf(`db: validator failed for field "RefreshToken.id": %w`, err)} } @@ -331,9 +289,12 @@ func (rtc *RefreshTokenCreate) check() error { return nil } -func (rtc *RefreshTokenCreate) sqlSave(ctx context.Context) (*RefreshToken, error) { - _node, _spec := rtc.createSpec() - if err := sqlgraph.CreateNode(ctx, rtc.driver, _spec); err != nil { +func (_c *RefreshTokenCreate) sqlSave(ctx context.Context) (*RefreshToken, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -346,142 +307,78 @@ func (rtc *RefreshTokenCreate) sqlSave(ctx context.Context) (*RefreshToken, erro return nil, fmt.Errorf("unexpected RefreshToken.ID type: %T", _spec.ID.Value) } } + _c.mutation.id = &_node.ID + _c.mutation.done = true return _node, nil } -func (rtc *RefreshTokenCreate) createSpec() (*RefreshToken, *sqlgraph.CreateSpec) { +func (_c *RefreshTokenCreate) createSpec() (*RefreshToken, *sqlgraph.CreateSpec) { var ( - _node = &RefreshToken{config: rtc.config} - _spec = &sqlgraph.CreateSpec{ - Table: refreshtoken.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: refreshtoken.FieldID, - }, - } + _node = &RefreshToken{config: _c.config} + _spec = sqlgraph.NewCreateSpec(refreshtoken.Table, sqlgraph.NewFieldSpec(refreshtoken.FieldID, field.TypeString)) ) - if id, ok := rtc.mutation.ID(); ok { + if id, ok := _c.mutation.ID(); ok { _node.ID = id _spec.ID.Value = id } - if value, ok := rtc.mutation.ClientID(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldClientID, - }) + if value, ok := _c.mutation.ClientID(); ok { + _spec.SetField(refreshtoken.FieldClientID, field.TypeString, value) _node.ClientID = value } - if value, ok := rtc.mutation.Scopes(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: refreshtoken.FieldScopes, - }) + if value, ok := _c.mutation.Scopes(); ok { + _spec.SetField(refreshtoken.FieldScopes, field.TypeJSON, value) _node.Scopes = value } - if value, ok := rtc.mutation.Nonce(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldNonce, - }) + if value, ok := _c.mutation.Nonce(); ok { + _spec.SetField(refreshtoken.FieldNonce, field.TypeString, value) _node.Nonce = value } - if value, ok := rtc.mutation.ClaimsUserID(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldClaimsUserID, - }) + if value, ok := _c.mutation.ClaimsUserID(); ok { + _spec.SetField(refreshtoken.FieldClaimsUserID, field.TypeString, value) _node.ClaimsUserID = value } - if value, ok := rtc.mutation.ClaimsUsername(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldClaimsUsername, - }) + if value, ok := _c.mutation.ClaimsUsername(); ok { + _spec.SetField(refreshtoken.FieldClaimsUsername, field.TypeString, value) _node.ClaimsUsername = value } - if value, ok := rtc.mutation.ClaimsEmail(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldClaimsEmail, - }) + if value, ok := _c.mutation.ClaimsEmail(); ok { + _spec.SetField(refreshtoken.FieldClaimsEmail, field.TypeString, value) _node.ClaimsEmail = value } - if value, ok := rtc.mutation.ClaimsEmailVerified(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeBool, - Value: value, - Column: refreshtoken.FieldClaimsEmailVerified, - }) + if value, ok := _c.mutation.ClaimsEmailVerified(); ok { + _spec.SetField(refreshtoken.FieldClaimsEmailVerified, field.TypeBool, value) _node.ClaimsEmailVerified = value } - if value, ok := rtc.mutation.ClaimsGroups(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: refreshtoken.FieldClaimsGroups, - }) + if value, ok := _c.mutation.ClaimsGroups(); ok { + _spec.SetField(refreshtoken.FieldClaimsGroups, field.TypeJSON, value) _node.ClaimsGroups = value } - if value, ok := rtc.mutation.ClaimsPreferredUsername(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldClaimsPreferredUsername, - }) + if value, ok := _c.mutation.ClaimsPreferredUsername(); ok { + _spec.SetField(refreshtoken.FieldClaimsPreferredUsername, field.TypeString, value) _node.ClaimsPreferredUsername = value } - if value, ok := rtc.mutation.ConnectorID(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldConnectorID, - }) + if value, ok := _c.mutation.ConnectorID(); ok { + _spec.SetField(refreshtoken.FieldConnectorID, field.TypeString, value) _node.ConnectorID = value } - if value, ok := rtc.mutation.ConnectorData(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: refreshtoken.FieldConnectorData, - }) + if value, ok := _c.mutation.ConnectorData(); ok { + _spec.SetField(refreshtoken.FieldConnectorData, field.TypeBytes, value) _node.ConnectorData = &value } - if value, ok := rtc.mutation.Token(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldToken, - }) + if value, ok := _c.mutation.Token(); ok { + _spec.SetField(refreshtoken.FieldToken, field.TypeString, value) _node.Token = value } - if value, ok := rtc.mutation.ObsoleteToken(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldObsoleteToken, - }) + if value, ok := _c.mutation.ObsoleteToken(); ok { + _spec.SetField(refreshtoken.FieldObsoleteToken, field.TypeString, value) _node.ObsoleteToken = value } - if value, ok := rtc.mutation.CreatedAt(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: refreshtoken.FieldCreatedAt, - }) + if value, ok := _c.mutation.CreatedAt(); ok { + _spec.SetField(refreshtoken.FieldCreatedAt, field.TypeTime, value) _node.CreatedAt = value } - if value, ok := rtc.mutation.LastUsed(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: refreshtoken.FieldLastUsed, - }) + if value, ok := _c.mutation.LastUsed(); ok { + _spec.SetField(refreshtoken.FieldLastUsed, field.TypeTime, value) _node.LastUsed = value } return _node, _spec @@ -490,17 +387,21 @@ func (rtc *RefreshTokenCreate) createSpec() (*RefreshToken, *sqlgraph.CreateSpec // RefreshTokenCreateBulk is the builder for creating many RefreshToken entities in bulk. type RefreshTokenCreateBulk struct { config + err error builders []*RefreshTokenCreate } // Save creates the RefreshToken entities in the database. -func (rtcb *RefreshTokenCreateBulk) Save(ctx context.Context) ([]*RefreshToken, error) { - specs := make([]*sqlgraph.CreateSpec, len(rtcb.builders)) - nodes := make([]*RefreshToken, len(rtcb.builders)) - mutators := make([]Mutator, len(rtcb.builders)) - for i := range rtcb.builders { +func (_c *RefreshTokenCreateBulk) Save(ctx context.Context) ([]*RefreshToken, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*RefreshToken, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { func(i int, root context.Context) { - builder := rtcb.builders[i] + builder := _c.builders[i] builder.defaults() var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { mutation, ok := m.(*RefreshTokenMutation) @@ -511,14 +412,14 @@ func (rtcb *RefreshTokenCreateBulk) Save(ctx context.Context) ([]*RefreshToken, return nil, err } builder.mutation = mutation - nodes[i], specs[i] = builder.createSpec() var err error + nodes[i], specs[i] = builder.createSpec() if i < len(mutators)-1 { - _, err = mutators[i+1].Mutate(root, rtcb.builders[i+1].mutation) + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} // Invoke the actual operation on the latest mutation in the chain. - if err = sqlgraph.BatchCreate(ctx, rtcb.driver, spec); err != nil { + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } @@ -538,7 +439,7 @@ func (rtcb *RefreshTokenCreateBulk) Save(ctx context.Context) ([]*RefreshToken, }(i, ctx) } if len(mutators) > 0 { - if _, err := mutators[0].Mutate(ctx, rtcb.builders[0].mutation); err != nil { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { return nil, err } } @@ -546,8 +447,8 @@ func (rtcb *RefreshTokenCreateBulk) Save(ctx context.Context) ([]*RefreshToken, } // SaveX is like Save, but panics if an error occurs. -func (rtcb *RefreshTokenCreateBulk) SaveX(ctx context.Context) []*RefreshToken { - v, err := rtcb.Save(ctx) +func (_c *RefreshTokenCreateBulk) SaveX(ctx context.Context) []*RefreshToken { + v, err := _c.Save(ctx) if err != nil { panic(err) } @@ -555,14 +456,14 @@ func (rtcb *RefreshTokenCreateBulk) SaveX(ctx context.Context) []*RefreshToken { } // Exec executes the query. -func (rtcb *RefreshTokenCreateBulk) Exec(ctx context.Context) error { - _, err := rtcb.Save(ctx) +func (_c *RefreshTokenCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (rtcb *RefreshTokenCreateBulk) ExecX(ctx context.Context) { - if err := rtcb.Exec(ctx); err != nil { +func (_c *RefreshTokenCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { panic(err) } } diff --git a/storage/ent/db/refreshtoken_delete.go b/storage/ent/db/refreshtoken_delete.go index 2c8d7c1e80..3e85fd5bd6 100644 --- a/storage/ent/db/refreshtoken_delete.go +++ b/storage/ent/db/refreshtoken_delete.go @@ -4,7 +4,6 @@ package db import ( "context" - "fmt" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" @@ -21,84 +20,56 @@ type RefreshTokenDelete struct { } // Where appends a list predicates to the RefreshTokenDelete builder. -func (rtd *RefreshTokenDelete) Where(ps ...predicate.RefreshToken) *RefreshTokenDelete { - rtd.mutation.Where(ps...) - return rtd +func (_d *RefreshTokenDelete) Where(ps ...predicate.RefreshToken) *RefreshTokenDelete { + _d.mutation.Where(ps...) + return _d } // Exec executes the deletion query and returns how many vertices were deleted. -func (rtd *RefreshTokenDelete) Exec(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(rtd.hooks) == 0 { - affected, err = rtd.sqlExec(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*RefreshTokenMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - rtd.mutation = mutation - affected, err = rtd.sqlExec(ctx) - mutation.done = true - return affected, err - }) - for i := len(rtd.hooks) - 1; i >= 0; i-- { - if rtd.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = rtd.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, rtd.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_d *RefreshTokenDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) } // ExecX is like Exec, but panics if an error occurs. -func (rtd *RefreshTokenDelete) ExecX(ctx context.Context) int { - n, err := rtd.Exec(ctx) +func (_d *RefreshTokenDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) if err != nil { panic(err) } return n } -func (rtd *RefreshTokenDelete) sqlExec(ctx context.Context) (int, error) { - _spec := &sqlgraph.DeleteSpec{ - Node: &sqlgraph.NodeSpec{ - Table: refreshtoken.Table, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: refreshtoken.FieldID, - }, - }, - } - if ps := rtd.mutation.predicates; len(ps) > 0 { +func (_d *RefreshTokenDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(refreshtoken.Table, sqlgraph.NewFieldSpec(refreshtoken.FieldID, field.TypeString)) + if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - affected, err := sqlgraph.DeleteNodes(ctx, rtd.driver, _spec) + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) if err != nil && sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} } + _d.mutation.done = true return affected, err } // RefreshTokenDeleteOne is the builder for deleting a single RefreshToken entity. type RefreshTokenDeleteOne struct { - rtd *RefreshTokenDelete + _d *RefreshTokenDelete +} + +// Where appends a list predicates to the RefreshTokenDelete builder. +func (_d *RefreshTokenDeleteOne) Where(ps ...predicate.RefreshToken) *RefreshTokenDeleteOne { + _d._d.mutation.Where(ps...) + return _d } // Exec executes the deletion query. -func (rtdo *RefreshTokenDeleteOne) Exec(ctx context.Context) error { - n, err := rtdo.rtd.Exec(ctx) +func (_d *RefreshTokenDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) switch { case err != nil: return err @@ -110,6 +81,8 @@ func (rtdo *RefreshTokenDeleteOne) Exec(ctx context.Context) error { } // ExecX is like Exec, but panics if an error occurs. -func (rtdo *RefreshTokenDeleteOne) ExecX(ctx context.Context) { - rtdo.rtd.ExecX(ctx) +func (_d *RefreshTokenDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } } diff --git a/storage/ent/db/refreshtoken_query.go b/storage/ent/db/refreshtoken_query.go index a90ac2f912..e6f399b0e1 100644 --- a/storage/ent/db/refreshtoken_query.go +++ b/storage/ent/db/refreshtoken_query.go @@ -7,6 +7,7 @@ import ( "fmt" "math" + "entgo.io/ent" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" @@ -17,11 +18,9 @@ import ( // RefreshTokenQuery is the builder for querying RefreshToken entities. type RefreshTokenQuery struct { config - limit *int - offset *int - unique *bool - order []OrderFunc - fields []string + ctx *QueryContext + order []refreshtoken.OrderOption + inters []Interceptor predicates []predicate.RefreshToken // intermediate query (i.e. traversal path). sql *sql.Selector @@ -29,40 +28,40 @@ type RefreshTokenQuery struct { } // Where adds a new predicate for the RefreshTokenQuery builder. -func (rtq *RefreshTokenQuery) Where(ps ...predicate.RefreshToken) *RefreshTokenQuery { - rtq.predicates = append(rtq.predicates, ps...) - return rtq +func (_q *RefreshTokenQuery) Where(ps ...predicate.RefreshToken) *RefreshTokenQuery { + _q.predicates = append(_q.predicates, ps...) + return _q } -// Limit adds a limit step to the query. -func (rtq *RefreshTokenQuery) Limit(limit int) *RefreshTokenQuery { - rtq.limit = &limit - return rtq +// Limit the number of records to be returned by this query. +func (_q *RefreshTokenQuery) Limit(limit int) *RefreshTokenQuery { + _q.ctx.Limit = &limit + return _q } -// Offset adds an offset step to the query. -func (rtq *RefreshTokenQuery) Offset(offset int) *RefreshTokenQuery { - rtq.offset = &offset - return rtq +// Offset to start from. +func (_q *RefreshTokenQuery) Offset(offset int) *RefreshTokenQuery { + _q.ctx.Offset = &offset + return _q } // Unique configures the query builder to filter duplicate records on query. // By default, unique is set to true, and can be disabled using this method. -func (rtq *RefreshTokenQuery) Unique(unique bool) *RefreshTokenQuery { - rtq.unique = &unique - return rtq +func (_q *RefreshTokenQuery) Unique(unique bool) *RefreshTokenQuery { + _q.ctx.Unique = &unique + return _q } -// Order adds an order step to the query. -func (rtq *RefreshTokenQuery) Order(o ...OrderFunc) *RefreshTokenQuery { - rtq.order = append(rtq.order, o...) - return rtq +// Order specifies how the records should be ordered. +func (_q *RefreshTokenQuery) Order(o ...refreshtoken.OrderOption) *RefreshTokenQuery { + _q.order = append(_q.order, o...) + return _q } // First returns the first RefreshToken entity from the query. // Returns a *NotFoundError when no RefreshToken was found. -func (rtq *RefreshTokenQuery) First(ctx context.Context) (*RefreshToken, error) { - nodes, err := rtq.Limit(1).All(ctx) +func (_q *RefreshTokenQuery) First(ctx context.Context) (*RefreshToken, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) if err != nil { return nil, err } @@ -73,8 +72,8 @@ func (rtq *RefreshTokenQuery) First(ctx context.Context) (*RefreshToken, error) } // FirstX is like First, but panics if an error occurs. -func (rtq *RefreshTokenQuery) FirstX(ctx context.Context) *RefreshToken { - node, err := rtq.First(ctx) +func (_q *RefreshTokenQuery) FirstX(ctx context.Context) *RefreshToken { + node, err := _q.First(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -83,9 +82,9 @@ func (rtq *RefreshTokenQuery) FirstX(ctx context.Context) *RefreshToken { // FirstID returns the first RefreshToken ID from the query. // Returns a *NotFoundError when no RefreshToken ID was found. -func (rtq *RefreshTokenQuery) FirstID(ctx context.Context) (id string, err error) { +func (_q *RefreshTokenQuery) FirstID(ctx context.Context) (id string, err error) { var ids []string - if ids, err = rtq.Limit(1).IDs(ctx); err != nil { + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { return } if len(ids) == 0 { @@ -96,8 +95,8 @@ func (rtq *RefreshTokenQuery) FirstID(ctx context.Context) (id string, err error } // FirstIDX is like FirstID, but panics if an error occurs. -func (rtq *RefreshTokenQuery) FirstIDX(ctx context.Context) string { - id, err := rtq.FirstID(ctx) +func (_q *RefreshTokenQuery) FirstIDX(ctx context.Context) string { + id, err := _q.FirstID(ctx) if err != nil && !IsNotFound(err) { panic(err) } @@ -107,8 +106,8 @@ func (rtq *RefreshTokenQuery) FirstIDX(ctx context.Context) string { // Only returns a single RefreshToken entity found by the query, ensuring it only returns one. // Returns a *NotSingularError when more than one RefreshToken entity is found. // Returns a *NotFoundError when no RefreshToken entities are found. -func (rtq *RefreshTokenQuery) Only(ctx context.Context) (*RefreshToken, error) { - nodes, err := rtq.Limit(2).All(ctx) +func (_q *RefreshTokenQuery) Only(ctx context.Context) (*RefreshToken, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) if err != nil { return nil, err } @@ -123,8 +122,8 @@ func (rtq *RefreshTokenQuery) Only(ctx context.Context) (*RefreshToken, error) { } // OnlyX is like Only, but panics if an error occurs. -func (rtq *RefreshTokenQuery) OnlyX(ctx context.Context) *RefreshToken { - node, err := rtq.Only(ctx) +func (_q *RefreshTokenQuery) OnlyX(ctx context.Context) *RefreshToken { + node, err := _q.Only(ctx) if err != nil { panic(err) } @@ -134,9 +133,9 @@ func (rtq *RefreshTokenQuery) OnlyX(ctx context.Context) *RefreshToken { // OnlyID is like Only, but returns the only RefreshToken ID in the query. // Returns a *NotSingularError when more than one RefreshToken ID is found. // Returns a *NotFoundError when no entities are found. -func (rtq *RefreshTokenQuery) OnlyID(ctx context.Context) (id string, err error) { +func (_q *RefreshTokenQuery) OnlyID(ctx context.Context) (id string, err error) { var ids []string - if ids, err = rtq.Limit(2).IDs(ctx); err != nil { + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { return } switch len(ids) { @@ -151,8 +150,8 @@ func (rtq *RefreshTokenQuery) OnlyID(ctx context.Context) (id string, err error) } // OnlyIDX is like OnlyID, but panics if an error occurs. -func (rtq *RefreshTokenQuery) OnlyIDX(ctx context.Context) string { - id, err := rtq.OnlyID(ctx) +func (_q *RefreshTokenQuery) OnlyIDX(ctx context.Context) string { + id, err := _q.OnlyID(ctx) if err != nil { panic(err) } @@ -160,16 +159,18 @@ func (rtq *RefreshTokenQuery) OnlyIDX(ctx context.Context) string { } // All executes the query and returns a list of RefreshTokens. -func (rtq *RefreshTokenQuery) All(ctx context.Context) ([]*RefreshToken, error) { - if err := rtq.prepareQuery(ctx); err != nil { +func (_q *RefreshTokenQuery) All(ctx context.Context) ([]*RefreshToken, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { return nil, err } - return rtq.sqlAll(ctx) + qr := querierAll[[]*RefreshToken, *RefreshTokenQuery]() + return withInterceptors[[]*RefreshToken](ctx, _q, qr, _q.inters) } // AllX is like All, but panics if an error occurs. -func (rtq *RefreshTokenQuery) AllX(ctx context.Context) []*RefreshToken { - nodes, err := rtq.All(ctx) +func (_q *RefreshTokenQuery) AllX(ctx context.Context) []*RefreshToken { + nodes, err := _q.All(ctx) if err != nil { panic(err) } @@ -177,17 +178,20 @@ func (rtq *RefreshTokenQuery) AllX(ctx context.Context) []*RefreshToken { } // IDs executes the query and returns a list of RefreshToken IDs. -func (rtq *RefreshTokenQuery) IDs(ctx context.Context) ([]string, error) { - var ids []string - if err := rtq.Select(refreshtoken.FieldID).Scan(ctx, &ids); err != nil { +func (_q *RefreshTokenQuery) IDs(ctx context.Context) (ids []string, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(refreshtoken.FieldID).Scan(ctx, &ids); err != nil { return nil, err } return ids, nil } // IDsX is like IDs, but panics if an error occurs. -func (rtq *RefreshTokenQuery) IDsX(ctx context.Context) []string { - ids, err := rtq.IDs(ctx) +func (_q *RefreshTokenQuery) IDsX(ctx context.Context) []string { + ids, err := _q.IDs(ctx) if err != nil { panic(err) } @@ -195,16 +199,17 @@ func (rtq *RefreshTokenQuery) IDsX(ctx context.Context) []string { } // Count returns the count of the given query. -func (rtq *RefreshTokenQuery) Count(ctx context.Context) (int, error) { - if err := rtq.prepareQuery(ctx); err != nil { +func (_q *RefreshTokenQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { return 0, err } - return rtq.sqlCount(ctx) + return withInterceptors[int](ctx, _q, querierCount[*RefreshTokenQuery](), _q.inters) } // CountX is like Count, but panics if an error occurs. -func (rtq *RefreshTokenQuery) CountX(ctx context.Context) int { - count, err := rtq.Count(ctx) +func (_q *RefreshTokenQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) if err != nil { panic(err) } @@ -212,16 +217,21 @@ func (rtq *RefreshTokenQuery) CountX(ctx context.Context) int { } // Exist returns true if the query has elements in the graph. -func (rtq *RefreshTokenQuery) Exist(ctx context.Context) (bool, error) { - if err := rtq.prepareQuery(ctx); err != nil { - return false, err +func (_q *RefreshTokenQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("db: check existence: %w", err) + default: + return true, nil } - return rtq.sqlExist(ctx) } // ExistX is like Exist, but panics if an error occurs. -func (rtq *RefreshTokenQuery) ExistX(ctx context.Context) bool { - exist, err := rtq.Exist(ctx) +func (_q *RefreshTokenQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) if err != nil { panic(err) } @@ -230,20 +240,19 @@ func (rtq *RefreshTokenQuery) ExistX(ctx context.Context) bool { // Clone returns a duplicate of the RefreshTokenQuery builder, including all associated steps. It can be // used to prepare common query builders and use them differently after the clone is made. -func (rtq *RefreshTokenQuery) Clone() *RefreshTokenQuery { - if rtq == nil { +func (_q *RefreshTokenQuery) Clone() *RefreshTokenQuery { + if _q == nil { return nil } return &RefreshTokenQuery{ - config: rtq.config, - limit: rtq.limit, - offset: rtq.offset, - order: append([]OrderFunc{}, rtq.order...), - predicates: append([]predicate.RefreshToken{}, rtq.predicates...), + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]refreshtoken.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.RefreshToken{}, _q.predicates...), // clone intermediate query. - sql: rtq.sql.Clone(), - path: rtq.path, - unique: rtq.unique, + sql: _q.sql.Clone(), + path: _q.path, } } @@ -261,18 +270,12 @@ func (rtq *RefreshTokenQuery) Clone() *RefreshTokenQuery { // GroupBy(refreshtoken.FieldClientID). // Aggregate(db.Count()). // Scan(ctx, &v) -// -func (rtq *RefreshTokenQuery) GroupBy(field string, fields ...string) *RefreshTokenGroupBy { - grbuild := &RefreshTokenGroupBy{config: rtq.config} - grbuild.fields = append([]string{field}, fields...) - grbuild.path = func(ctx context.Context) (prev *sql.Selector, err error) { - if err := rtq.prepareQuery(ctx); err != nil { - return nil, err - } - return rtq.sqlQuery(ctx), nil - } +func (_q *RefreshTokenQuery) GroupBy(field string, fields ...string) *RefreshTokenGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &RefreshTokenGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields grbuild.label = refreshtoken.Label - grbuild.flds, grbuild.scan = &grbuild.fields, grbuild.Scan + grbuild.scan = grbuild.Scan return grbuild } @@ -288,48 +291,62 @@ func (rtq *RefreshTokenQuery) GroupBy(field string, fields ...string) *RefreshTo // client.RefreshToken.Query(). // Select(refreshtoken.FieldClientID). // Scan(ctx, &v) -// -func (rtq *RefreshTokenQuery) Select(fields ...string) *RefreshTokenSelect { - rtq.fields = append(rtq.fields, fields...) - selbuild := &RefreshTokenSelect{RefreshTokenQuery: rtq} - selbuild.label = refreshtoken.Label - selbuild.flds, selbuild.scan = &rtq.fields, selbuild.Scan - return selbuild +func (_q *RefreshTokenQuery) Select(fields ...string) *RefreshTokenSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &RefreshTokenSelect{RefreshTokenQuery: _q} + sbuild.label = refreshtoken.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a RefreshTokenSelect configured with the given aggregations. +func (_q *RefreshTokenQuery) Aggregate(fns ...AggregateFunc) *RefreshTokenSelect { + return _q.Select().Aggregate(fns...) } -func (rtq *RefreshTokenQuery) prepareQuery(ctx context.Context) error { - for _, f := range rtq.fields { +func (_q *RefreshTokenQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("db: uninitialized interceptor (forgotten import db/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { if !refreshtoken.ValidColumn(f) { return &ValidationError{Name: f, err: fmt.Errorf("db: invalid field %q for query", f)} } } - if rtq.path != nil { - prev, err := rtq.path(ctx) + if _q.path != nil { + prev, err := _q.path(ctx) if err != nil { return err } - rtq.sql = prev + _q.sql = prev } return nil } -func (rtq *RefreshTokenQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*RefreshToken, error) { +func (_q *RefreshTokenQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*RefreshToken, error) { var ( nodes = []*RefreshToken{} - _spec = rtq.querySpec() + _spec = _q.querySpec() ) - _spec.ScanValues = func(columns []string) ([]interface{}, error) { + _spec.ScanValues = func(columns []string) ([]any, error) { return (*RefreshToken).scanValues(nil, columns) } - _spec.Assign = func(columns []string, values []interface{}) error { - node := &RefreshToken{config: rtq.config} + _spec.Assign = func(columns []string, values []any) error { + node := &RefreshToken{config: _q.config} nodes = append(nodes, node) return node.assignValues(columns, values) } for i := range hooks { hooks[i](ctx, _spec) } - if err := sqlgraph.QueryNodes(ctx, rtq.driver, _spec); err != nil { + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { return nil, err } if len(nodes) == 0 { @@ -338,40 +355,24 @@ func (rtq *RefreshTokenQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([ return nodes, nil } -func (rtq *RefreshTokenQuery) sqlCount(ctx context.Context) (int, error) { - _spec := rtq.querySpec() - _spec.Node.Columns = rtq.fields - if len(rtq.fields) > 0 { - _spec.Unique = rtq.unique != nil && *rtq.unique - } - return sqlgraph.CountNodes(ctx, rtq.driver, _spec) -} - -func (rtq *RefreshTokenQuery) sqlExist(ctx context.Context) (bool, error) { - n, err := rtq.sqlCount(ctx) - if err != nil { - return false, fmt.Errorf("db: check existence: %w", err) +func (_q *RefreshTokenQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique } - return n > 0, nil + return sqlgraph.CountNodes(ctx, _q.driver, _spec) } -func (rtq *RefreshTokenQuery) querySpec() *sqlgraph.QuerySpec { - _spec := &sqlgraph.QuerySpec{ - Node: &sqlgraph.NodeSpec{ - Table: refreshtoken.Table, - Columns: refreshtoken.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: refreshtoken.FieldID, - }, - }, - From: rtq.sql, - Unique: true, - } - if unique := rtq.unique; unique != nil { +func (_q *RefreshTokenQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(refreshtoken.Table, refreshtoken.Columns, sqlgraph.NewFieldSpec(refreshtoken.FieldID, field.TypeString)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true } - if fields := rtq.fields; len(fields) > 0 { + if fields := _q.ctx.Fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, refreshtoken.FieldID) for i := range fields { @@ -380,20 +381,20 @@ func (rtq *RefreshTokenQuery) querySpec() *sqlgraph.QuerySpec { } } } - if ps := rtq.predicates; len(ps) > 0 { + if ps := _q.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if limit := rtq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { _spec.Limit = *limit } - if offset := rtq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { _spec.Offset = *offset } - if ps := rtq.order; len(ps) > 0 { + if ps := _q.order; len(ps) > 0 { _spec.Order = func(selector *sql.Selector) { for i := range ps { ps[i](selector) @@ -403,33 +404,33 @@ func (rtq *RefreshTokenQuery) querySpec() *sqlgraph.QuerySpec { return _spec } -func (rtq *RefreshTokenQuery) sqlQuery(ctx context.Context) *sql.Selector { - builder := sql.Dialect(rtq.driver.Dialect()) +func (_q *RefreshTokenQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) t1 := builder.Table(refreshtoken.Table) - columns := rtq.fields + columns := _q.ctx.Fields if len(columns) == 0 { columns = refreshtoken.Columns } selector := builder.Select(t1.Columns(columns...)...).From(t1) - if rtq.sql != nil { - selector = rtq.sql + if _q.sql != nil { + selector = _q.sql selector.Select(selector.Columns(columns...)...) } - if rtq.unique != nil && *rtq.unique { + if _q.ctx.Unique != nil && *_q.ctx.Unique { selector.Distinct() } - for _, p := range rtq.predicates { + for _, p := range _q.predicates { p(selector) } - for _, p := range rtq.order { + for _, p := range _q.order { p(selector) } - if offset := rtq.offset; offset != nil { + if offset := _q.ctx.Offset; offset != nil { // limit is mandatory for offset clause. We start // with default value, and override it below if needed. selector.Offset(*offset).Limit(math.MaxInt32) } - if limit := rtq.limit; limit != nil { + if limit := _q.ctx.Limit; limit != nil { selector.Limit(*limit) } return selector @@ -437,90 +438,88 @@ func (rtq *RefreshTokenQuery) sqlQuery(ctx context.Context) *sql.Selector { // RefreshTokenGroupBy is the group-by builder for RefreshToken entities. type RefreshTokenGroupBy struct { - config selector - fields []string - fns []AggregateFunc - // intermediate query (i.e. traversal path). - sql *sql.Selector - path func(context.Context) (*sql.Selector, error) + build *RefreshTokenQuery } // Aggregate adds the given aggregation functions to the group-by query. -func (rtgb *RefreshTokenGroupBy) Aggregate(fns ...AggregateFunc) *RefreshTokenGroupBy { - rtgb.fns = append(rtgb.fns, fns...) - return rtgb +func (_g *RefreshTokenGroupBy) Aggregate(fns ...AggregateFunc) *RefreshTokenGroupBy { + _g.fns = append(_g.fns, fns...) + return _g } -// Scan applies the group-by query and scans the result into the given value. -func (rtgb *RefreshTokenGroupBy) Scan(ctx context.Context, v interface{}) error { - query, err := rtgb.path(ctx) - if err != nil { +// Scan applies the selector query and scans the result into the given value. +func (_g *RefreshTokenGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { return err } - rtgb.sql = query - return rtgb.sqlScan(ctx, v) + return scanWithInterceptors[*RefreshTokenQuery, *RefreshTokenGroupBy](ctx, _g.build, _g, _g.build.inters, v) } -func (rtgb *RefreshTokenGroupBy) sqlScan(ctx context.Context, v interface{}) error { - for _, f := range rtgb.fields { - if !refreshtoken.ValidColumn(f) { - return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)} +func (_g *RefreshTokenGroupBy) sqlScan(ctx context.Context, root *RefreshTokenQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) } + columns = append(columns, aggregation...) + selector.Select(columns...) } - selector := rtgb.sqlQuery() + selector.GroupBy(selector.Columns(*_g.flds...)...) if err := selector.Err(); err != nil { return err } rows := &sql.Rows{} query, args := selector.Query() - if err := rtgb.driver.Query(ctx, query, args, rows); err != nil { + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() return sql.ScanSlice(rows, v) } -func (rtgb *RefreshTokenGroupBy) sqlQuery() *sql.Selector { - selector := rtgb.sql.Select() - aggregation := make([]string, 0, len(rtgb.fns)) - for _, fn := range rtgb.fns { - aggregation = append(aggregation, fn(selector)) - } - // If no columns were selected in a custom aggregation function, the default - // selection is the fields used for "group-by", and the aggregation functions. - if len(selector.SelectedColumns()) == 0 { - columns := make([]string, 0, len(rtgb.fields)+len(rtgb.fns)) - for _, f := range rtgb.fields { - columns = append(columns, selector.C(f)) - } - columns = append(columns, aggregation...) - selector.Select(columns...) - } - return selector.GroupBy(selector.Columns(rtgb.fields...)...) -} - // RefreshTokenSelect is the builder for selecting fields of RefreshToken entities. type RefreshTokenSelect struct { *RefreshTokenQuery selector - // intermediate query (i.e. traversal path). - sql *sql.Selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *RefreshTokenSelect) Aggregate(fns ...AggregateFunc) *RefreshTokenSelect { + _s.fns = append(_s.fns, fns...) + return _s } // Scan applies the selector query and scans the result into the given value. -func (rts *RefreshTokenSelect) Scan(ctx context.Context, v interface{}) error { - if err := rts.prepareQuery(ctx); err != nil { +func (_s *RefreshTokenSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { return err } - rts.sql = rts.RefreshTokenQuery.sqlQuery(ctx) - return rts.sqlScan(ctx, v) + return scanWithInterceptors[*RefreshTokenQuery, *RefreshTokenSelect](ctx, _s.RefreshTokenQuery, _s, _s.inters, v) } -func (rts *RefreshTokenSelect) sqlScan(ctx context.Context, v interface{}) error { +func (_s *RefreshTokenSelect) sqlScan(ctx context.Context, root *RefreshTokenQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } rows := &sql.Rows{} - query, args := rts.sql.Query() - if err := rts.driver.Query(ctx, query, args, rows); err != nil { + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() diff --git a/storage/ent/db/refreshtoken_update.go b/storage/ent/db/refreshtoken_update.go index 6c11c7f73c..cdf8cee86e 100644 --- a/storage/ent/db/refreshtoken_update.go +++ b/storage/ent/db/refreshtoken_update.go @@ -10,6 +10,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/dialect/sql/sqljson" "entgo.io/ent/schema/field" "github.com/dexidp/dex/storage/ent/db/predicate" "github.com/dexidp/dex/storage/ent/db/refreshtoken" @@ -23,205 +24,240 @@ type RefreshTokenUpdate struct { } // Where appends a list predicates to the RefreshTokenUpdate builder. -func (rtu *RefreshTokenUpdate) Where(ps ...predicate.RefreshToken) *RefreshTokenUpdate { - rtu.mutation.Where(ps...) - return rtu +func (_u *RefreshTokenUpdate) Where(ps ...predicate.RefreshToken) *RefreshTokenUpdate { + _u.mutation.Where(ps...) + return _u } // SetClientID sets the "client_id" field. -func (rtu *RefreshTokenUpdate) SetClientID(s string) *RefreshTokenUpdate { - rtu.mutation.SetClientID(s) - return rtu +func (_u *RefreshTokenUpdate) SetClientID(v string) *RefreshTokenUpdate { + _u.mutation.SetClientID(v) + return _u +} + +// SetNillableClientID sets the "client_id" field if the given value is not nil. +func (_u *RefreshTokenUpdate) SetNillableClientID(v *string) *RefreshTokenUpdate { + if v != nil { + _u.SetClientID(*v) + } + return _u } // SetScopes sets the "scopes" field. -func (rtu *RefreshTokenUpdate) SetScopes(s []string) *RefreshTokenUpdate { - rtu.mutation.SetScopes(s) - return rtu +func (_u *RefreshTokenUpdate) SetScopes(v []string) *RefreshTokenUpdate { + _u.mutation.SetScopes(v) + return _u +} + +// AppendScopes appends value to the "scopes" field. +func (_u *RefreshTokenUpdate) AppendScopes(v []string) *RefreshTokenUpdate { + _u.mutation.AppendScopes(v) + return _u } // ClearScopes clears the value of the "scopes" field. -func (rtu *RefreshTokenUpdate) ClearScopes() *RefreshTokenUpdate { - rtu.mutation.ClearScopes() - return rtu +func (_u *RefreshTokenUpdate) ClearScopes() *RefreshTokenUpdate { + _u.mutation.ClearScopes() + return _u } // SetNonce sets the "nonce" field. -func (rtu *RefreshTokenUpdate) SetNonce(s string) *RefreshTokenUpdate { - rtu.mutation.SetNonce(s) - return rtu +func (_u *RefreshTokenUpdate) SetNonce(v string) *RefreshTokenUpdate { + _u.mutation.SetNonce(v) + return _u +} + +// SetNillableNonce sets the "nonce" field if the given value is not nil. +func (_u *RefreshTokenUpdate) SetNillableNonce(v *string) *RefreshTokenUpdate { + if v != nil { + _u.SetNonce(*v) + } + return _u } // SetClaimsUserID sets the "claims_user_id" field. -func (rtu *RefreshTokenUpdate) SetClaimsUserID(s string) *RefreshTokenUpdate { - rtu.mutation.SetClaimsUserID(s) - return rtu +func (_u *RefreshTokenUpdate) SetClaimsUserID(v string) *RefreshTokenUpdate { + _u.mutation.SetClaimsUserID(v) + return _u +} + +// SetNillableClaimsUserID sets the "claims_user_id" field if the given value is not nil. +func (_u *RefreshTokenUpdate) SetNillableClaimsUserID(v *string) *RefreshTokenUpdate { + if v != nil { + _u.SetClaimsUserID(*v) + } + return _u } // SetClaimsUsername sets the "claims_username" field. -func (rtu *RefreshTokenUpdate) SetClaimsUsername(s string) *RefreshTokenUpdate { - rtu.mutation.SetClaimsUsername(s) - return rtu +func (_u *RefreshTokenUpdate) SetClaimsUsername(v string) *RefreshTokenUpdate { + _u.mutation.SetClaimsUsername(v) + return _u +} + +// SetNillableClaimsUsername sets the "claims_username" field if the given value is not nil. +func (_u *RefreshTokenUpdate) SetNillableClaimsUsername(v *string) *RefreshTokenUpdate { + if v != nil { + _u.SetClaimsUsername(*v) + } + return _u } // SetClaimsEmail sets the "claims_email" field. -func (rtu *RefreshTokenUpdate) SetClaimsEmail(s string) *RefreshTokenUpdate { - rtu.mutation.SetClaimsEmail(s) - return rtu +func (_u *RefreshTokenUpdate) SetClaimsEmail(v string) *RefreshTokenUpdate { + _u.mutation.SetClaimsEmail(v) + return _u +} + +// SetNillableClaimsEmail sets the "claims_email" field if the given value is not nil. +func (_u *RefreshTokenUpdate) SetNillableClaimsEmail(v *string) *RefreshTokenUpdate { + if v != nil { + _u.SetClaimsEmail(*v) + } + return _u } // SetClaimsEmailVerified sets the "claims_email_verified" field. -func (rtu *RefreshTokenUpdate) SetClaimsEmailVerified(b bool) *RefreshTokenUpdate { - rtu.mutation.SetClaimsEmailVerified(b) - return rtu +func (_u *RefreshTokenUpdate) SetClaimsEmailVerified(v bool) *RefreshTokenUpdate { + _u.mutation.SetClaimsEmailVerified(v) + return _u +} + +// SetNillableClaimsEmailVerified sets the "claims_email_verified" field if the given value is not nil. +func (_u *RefreshTokenUpdate) SetNillableClaimsEmailVerified(v *bool) *RefreshTokenUpdate { + if v != nil { + _u.SetClaimsEmailVerified(*v) + } + return _u } // SetClaimsGroups sets the "claims_groups" field. -func (rtu *RefreshTokenUpdate) SetClaimsGroups(s []string) *RefreshTokenUpdate { - rtu.mutation.SetClaimsGroups(s) - return rtu +func (_u *RefreshTokenUpdate) SetClaimsGroups(v []string) *RefreshTokenUpdate { + _u.mutation.SetClaimsGroups(v) + return _u +} + +// AppendClaimsGroups appends value to the "claims_groups" field. +func (_u *RefreshTokenUpdate) AppendClaimsGroups(v []string) *RefreshTokenUpdate { + _u.mutation.AppendClaimsGroups(v) + return _u } // ClearClaimsGroups clears the value of the "claims_groups" field. -func (rtu *RefreshTokenUpdate) ClearClaimsGroups() *RefreshTokenUpdate { - rtu.mutation.ClearClaimsGroups() - return rtu +func (_u *RefreshTokenUpdate) ClearClaimsGroups() *RefreshTokenUpdate { + _u.mutation.ClearClaimsGroups() + return _u } // SetClaimsPreferredUsername sets the "claims_preferred_username" field. -func (rtu *RefreshTokenUpdate) SetClaimsPreferredUsername(s string) *RefreshTokenUpdate { - rtu.mutation.SetClaimsPreferredUsername(s) - return rtu +func (_u *RefreshTokenUpdate) SetClaimsPreferredUsername(v string) *RefreshTokenUpdate { + _u.mutation.SetClaimsPreferredUsername(v) + return _u } // SetNillableClaimsPreferredUsername sets the "claims_preferred_username" field if the given value is not nil. -func (rtu *RefreshTokenUpdate) SetNillableClaimsPreferredUsername(s *string) *RefreshTokenUpdate { - if s != nil { - rtu.SetClaimsPreferredUsername(*s) +func (_u *RefreshTokenUpdate) SetNillableClaimsPreferredUsername(v *string) *RefreshTokenUpdate { + if v != nil { + _u.SetClaimsPreferredUsername(*v) } - return rtu + return _u } // SetConnectorID sets the "connector_id" field. -func (rtu *RefreshTokenUpdate) SetConnectorID(s string) *RefreshTokenUpdate { - rtu.mutation.SetConnectorID(s) - return rtu +func (_u *RefreshTokenUpdate) SetConnectorID(v string) *RefreshTokenUpdate { + _u.mutation.SetConnectorID(v) + return _u +} + +// SetNillableConnectorID sets the "connector_id" field if the given value is not nil. +func (_u *RefreshTokenUpdate) SetNillableConnectorID(v *string) *RefreshTokenUpdate { + if v != nil { + _u.SetConnectorID(*v) + } + return _u } // SetConnectorData sets the "connector_data" field. -func (rtu *RefreshTokenUpdate) SetConnectorData(b []byte) *RefreshTokenUpdate { - rtu.mutation.SetConnectorData(b) - return rtu +func (_u *RefreshTokenUpdate) SetConnectorData(v []byte) *RefreshTokenUpdate { + _u.mutation.SetConnectorData(v) + return _u } // ClearConnectorData clears the value of the "connector_data" field. -func (rtu *RefreshTokenUpdate) ClearConnectorData() *RefreshTokenUpdate { - rtu.mutation.ClearConnectorData() - return rtu +func (_u *RefreshTokenUpdate) ClearConnectorData() *RefreshTokenUpdate { + _u.mutation.ClearConnectorData() + return _u } // SetToken sets the "token" field. -func (rtu *RefreshTokenUpdate) SetToken(s string) *RefreshTokenUpdate { - rtu.mutation.SetToken(s) - return rtu +func (_u *RefreshTokenUpdate) SetToken(v string) *RefreshTokenUpdate { + _u.mutation.SetToken(v) + return _u } // SetNillableToken sets the "token" field if the given value is not nil. -func (rtu *RefreshTokenUpdate) SetNillableToken(s *string) *RefreshTokenUpdate { - if s != nil { - rtu.SetToken(*s) +func (_u *RefreshTokenUpdate) SetNillableToken(v *string) *RefreshTokenUpdate { + if v != nil { + _u.SetToken(*v) } - return rtu + return _u } // SetObsoleteToken sets the "obsolete_token" field. -func (rtu *RefreshTokenUpdate) SetObsoleteToken(s string) *RefreshTokenUpdate { - rtu.mutation.SetObsoleteToken(s) - return rtu +func (_u *RefreshTokenUpdate) SetObsoleteToken(v string) *RefreshTokenUpdate { + _u.mutation.SetObsoleteToken(v) + return _u } // SetNillableObsoleteToken sets the "obsolete_token" field if the given value is not nil. -func (rtu *RefreshTokenUpdate) SetNillableObsoleteToken(s *string) *RefreshTokenUpdate { - if s != nil { - rtu.SetObsoleteToken(*s) +func (_u *RefreshTokenUpdate) SetNillableObsoleteToken(v *string) *RefreshTokenUpdate { + if v != nil { + _u.SetObsoleteToken(*v) } - return rtu + return _u } // SetCreatedAt sets the "created_at" field. -func (rtu *RefreshTokenUpdate) SetCreatedAt(t time.Time) *RefreshTokenUpdate { - rtu.mutation.SetCreatedAt(t) - return rtu +func (_u *RefreshTokenUpdate) SetCreatedAt(v time.Time) *RefreshTokenUpdate { + _u.mutation.SetCreatedAt(v) + return _u } // SetNillableCreatedAt sets the "created_at" field if the given value is not nil. -func (rtu *RefreshTokenUpdate) SetNillableCreatedAt(t *time.Time) *RefreshTokenUpdate { - if t != nil { - rtu.SetCreatedAt(*t) +func (_u *RefreshTokenUpdate) SetNillableCreatedAt(v *time.Time) *RefreshTokenUpdate { + if v != nil { + _u.SetCreatedAt(*v) } - return rtu + return _u } // SetLastUsed sets the "last_used" field. -func (rtu *RefreshTokenUpdate) SetLastUsed(t time.Time) *RefreshTokenUpdate { - rtu.mutation.SetLastUsed(t) - return rtu +func (_u *RefreshTokenUpdate) SetLastUsed(v time.Time) *RefreshTokenUpdate { + _u.mutation.SetLastUsed(v) + return _u } // SetNillableLastUsed sets the "last_used" field if the given value is not nil. -func (rtu *RefreshTokenUpdate) SetNillableLastUsed(t *time.Time) *RefreshTokenUpdate { - if t != nil { - rtu.SetLastUsed(*t) +func (_u *RefreshTokenUpdate) SetNillableLastUsed(v *time.Time) *RefreshTokenUpdate { + if v != nil { + _u.SetLastUsed(*v) } - return rtu + return _u } // Mutation returns the RefreshTokenMutation object of the builder. -func (rtu *RefreshTokenUpdate) Mutation() *RefreshTokenMutation { - return rtu.mutation +func (_u *RefreshTokenUpdate) Mutation() *RefreshTokenMutation { + return _u.mutation } // Save executes the query and returns the number of nodes affected by the update operation. -func (rtu *RefreshTokenUpdate) Save(ctx context.Context) (int, error) { - var ( - err error - affected int - ) - if len(rtu.hooks) == 0 { - if err = rtu.check(); err != nil { - return 0, err - } - affected, err = rtu.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*RefreshTokenMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = rtu.check(); err != nil { - return 0, err - } - rtu.mutation = mutation - affected, err = rtu.sqlSave(ctx) - mutation.done = true - return affected, err - }) - for i := len(rtu.hooks) - 1; i >= 0; i-- { - if rtu.hooks[i] == nil { - return 0, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = rtu.hooks[i](mut) - } - if _, err := mut.Mutate(ctx, rtu.mutation); err != nil { - return 0, err - } - } - return affected, err +func (_u *RefreshTokenUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (rtu *RefreshTokenUpdate) SaveX(ctx context.Context) int { - affected, err := rtu.Save(ctx) +func (_u *RefreshTokenUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) if err != nil { panic(err) } @@ -229,46 +265,46 @@ func (rtu *RefreshTokenUpdate) SaveX(ctx context.Context) int { } // Exec executes the query. -func (rtu *RefreshTokenUpdate) Exec(ctx context.Context) error { - _, err := rtu.Save(ctx) +func (_u *RefreshTokenUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (rtu *RefreshTokenUpdate) ExecX(ctx context.Context) { - if err := rtu.Exec(ctx); err != nil { +func (_u *RefreshTokenUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (rtu *RefreshTokenUpdate) check() error { - if v, ok := rtu.mutation.ClientID(); ok { +func (_u *RefreshTokenUpdate) check() error { + if v, ok := _u.mutation.ClientID(); ok { if err := refreshtoken.ClientIDValidator(v); err != nil { return &ValidationError{Name: "client_id", err: fmt.Errorf(`db: validator failed for field "RefreshToken.client_id": %w`, err)} } } - if v, ok := rtu.mutation.Nonce(); ok { + if v, ok := _u.mutation.Nonce(); ok { if err := refreshtoken.NonceValidator(v); err != nil { return &ValidationError{Name: "nonce", err: fmt.Errorf(`db: validator failed for field "RefreshToken.nonce": %w`, err)} } } - if v, ok := rtu.mutation.ClaimsUserID(); ok { + if v, ok := _u.mutation.ClaimsUserID(); ok { if err := refreshtoken.ClaimsUserIDValidator(v); err != nil { return &ValidationError{Name: "claims_user_id", err: fmt.Errorf(`db: validator failed for field "RefreshToken.claims_user_id": %w`, err)} } } - if v, ok := rtu.mutation.ClaimsUsername(); ok { + if v, ok := _u.mutation.ClaimsUsername(); ok { if err := refreshtoken.ClaimsUsernameValidator(v); err != nil { return &ValidationError{Name: "claims_username", err: fmt.Errorf(`db: validator failed for field "RefreshToken.claims_username": %w`, err)} } } - if v, ok := rtu.mutation.ClaimsEmail(); ok { + if v, ok := _u.mutation.ClaimsEmail(); ok { if err := refreshtoken.ClaimsEmailValidator(v); err != nil { return &ValidationError{Name: "claims_email", err: fmt.Errorf(`db: validator failed for field "RefreshToken.claims_email": %w`, err)} } } - if v, ok := rtu.mutation.ConnectorID(); ok { + if v, ok := _u.mutation.ConnectorID(); ok { if err := refreshtoken.ConnectorIDValidator(v); err != nil { return &ValidationError{Name: "connector_id", err: fmt.Errorf(`db: validator failed for field "RefreshToken.connector_id": %w`, err)} } @@ -276,148 +312,83 @@ func (rtu *RefreshTokenUpdate) check() error { return nil } -func (rtu *RefreshTokenUpdate) sqlSave(ctx context.Context) (n int, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: refreshtoken.Table, - Columns: refreshtoken.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: refreshtoken.FieldID, - }, - }, +func (_u *RefreshTokenUpdate) sqlSave(ctx context.Context) (_node int, err error) { + if err := _u.check(); err != nil { + return _node, err } - if ps := rtu.mutation.predicates; len(ps) > 0 { + _spec := sqlgraph.NewUpdateSpec(refreshtoken.Table, refreshtoken.Columns, sqlgraph.NewFieldSpec(refreshtoken.FieldID, field.TypeString)) + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := rtu.mutation.ClientID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldClientID, - }) + if value, ok := _u.mutation.ClientID(); ok { + _spec.SetField(refreshtoken.FieldClientID, field.TypeString, value) } - if value, ok := rtu.mutation.Scopes(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: refreshtoken.FieldScopes, - }) + if value, ok := _u.mutation.Scopes(); ok { + _spec.SetField(refreshtoken.FieldScopes, field.TypeJSON, value) } - if rtu.mutation.ScopesCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: refreshtoken.FieldScopes, + if value, ok := _u.mutation.AppendedScopes(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, refreshtoken.FieldScopes, value) }) } - if value, ok := rtu.mutation.Nonce(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldNonce, - }) + if _u.mutation.ScopesCleared() { + _spec.ClearField(refreshtoken.FieldScopes, field.TypeJSON) } - if value, ok := rtu.mutation.ClaimsUserID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldClaimsUserID, - }) + if value, ok := _u.mutation.Nonce(); ok { + _spec.SetField(refreshtoken.FieldNonce, field.TypeString, value) } - if value, ok := rtu.mutation.ClaimsUsername(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldClaimsUsername, - }) + if value, ok := _u.mutation.ClaimsUserID(); ok { + _spec.SetField(refreshtoken.FieldClaimsUserID, field.TypeString, value) } - if value, ok := rtu.mutation.ClaimsEmail(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldClaimsEmail, - }) + if value, ok := _u.mutation.ClaimsUsername(); ok { + _spec.SetField(refreshtoken.FieldClaimsUsername, field.TypeString, value) } - if value, ok := rtu.mutation.ClaimsEmailVerified(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBool, - Value: value, - Column: refreshtoken.FieldClaimsEmailVerified, - }) + if value, ok := _u.mutation.ClaimsEmail(); ok { + _spec.SetField(refreshtoken.FieldClaimsEmail, field.TypeString, value) } - if value, ok := rtu.mutation.ClaimsGroups(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: refreshtoken.FieldClaimsGroups, - }) + if value, ok := _u.mutation.ClaimsEmailVerified(); ok { + _spec.SetField(refreshtoken.FieldClaimsEmailVerified, field.TypeBool, value) } - if rtu.mutation.ClaimsGroupsCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: refreshtoken.FieldClaimsGroups, - }) + if value, ok := _u.mutation.ClaimsGroups(); ok { + _spec.SetField(refreshtoken.FieldClaimsGroups, field.TypeJSON, value) } - if value, ok := rtu.mutation.ClaimsPreferredUsername(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldClaimsPreferredUsername, + if value, ok := _u.mutation.AppendedClaimsGroups(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, refreshtoken.FieldClaimsGroups, value) }) } - if value, ok := rtu.mutation.ConnectorID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldConnectorID, - }) + if _u.mutation.ClaimsGroupsCleared() { + _spec.ClearField(refreshtoken.FieldClaimsGroups, field.TypeJSON) } - if value, ok := rtu.mutation.ConnectorData(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: refreshtoken.FieldConnectorData, - }) + if value, ok := _u.mutation.ClaimsPreferredUsername(); ok { + _spec.SetField(refreshtoken.FieldClaimsPreferredUsername, field.TypeString, value) } - if rtu.mutation.ConnectorDataCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Column: refreshtoken.FieldConnectorData, - }) + if value, ok := _u.mutation.ConnectorID(); ok { + _spec.SetField(refreshtoken.FieldConnectorID, field.TypeString, value) } - if value, ok := rtu.mutation.Token(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldToken, - }) + if value, ok := _u.mutation.ConnectorData(); ok { + _spec.SetField(refreshtoken.FieldConnectorData, field.TypeBytes, value) } - if value, ok := rtu.mutation.ObsoleteToken(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldObsoleteToken, - }) + if _u.mutation.ConnectorDataCleared() { + _spec.ClearField(refreshtoken.FieldConnectorData, field.TypeBytes) } - if value, ok := rtu.mutation.CreatedAt(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: refreshtoken.FieldCreatedAt, - }) + if value, ok := _u.mutation.Token(); ok { + _spec.SetField(refreshtoken.FieldToken, field.TypeString, value) } - if value, ok := rtu.mutation.LastUsed(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: refreshtoken.FieldLastUsed, - }) + if value, ok := _u.mutation.ObsoleteToken(); ok { + _spec.SetField(refreshtoken.FieldObsoleteToken, field.TypeString, value) + } + if value, ok := _u.mutation.CreatedAt(); ok { + _spec.SetField(refreshtoken.FieldCreatedAt, field.TypeTime, value) + } + if value, ok := _u.mutation.LastUsed(); ok { + _spec.SetField(refreshtoken.FieldLastUsed, field.TypeTime, value) } - if n, err = sqlgraph.UpdateNodes(ctx, rtu.driver, _spec); err != nil { + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{refreshtoken.Label} } else if sqlgraph.IsConstraintError(err) { @@ -425,7 +396,8 @@ func (rtu *RefreshTokenUpdate) sqlSave(ctx context.Context) (n int, err error) { } return 0, err } - return n, nil + _u.mutation.done = true + return _node, nil } // RefreshTokenUpdateOne is the builder for updating a single RefreshToken entity. @@ -437,212 +409,247 @@ type RefreshTokenUpdateOne struct { } // SetClientID sets the "client_id" field. -func (rtuo *RefreshTokenUpdateOne) SetClientID(s string) *RefreshTokenUpdateOne { - rtuo.mutation.SetClientID(s) - return rtuo +func (_u *RefreshTokenUpdateOne) SetClientID(v string) *RefreshTokenUpdateOne { + _u.mutation.SetClientID(v) + return _u +} + +// SetNillableClientID sets the "client_id" field if the given value is not nil. +func (_u *RefreshTokenUpdateOne) SetNillableClientID(v *string) *RefreshTokenUpdateOne { + if v != nil { + _u.SetClientID(*v) + } + return _u } // SetScopes sets the "scopes" field. -func (rtuo *RefreshTokenUpdateOne) SetScopes(s []string) *RefreshTokenUpdateOne { - rtuo.mutation.SetScopes(s) - return rtuo +func (_u *RefreshTokenUpdateOne) SetScopes(v []string) *RefreshTokenUpdateOne { + _u.mutation.SetScopes(v) + return _u +} + +// AppendScopes appends value to the "scopes" field. +func (_u *RefreshTokenUpdateOne) AppendScopes(v []string) *RefreshTokenUpdateOne { + _u.mutation.AppendScopes(v) + return _u } // ClearScopes clears the value of the "scopes" field. -func (rtuo *RefreshTokenUpdateOne) ClearScopes() *RefreshTokenUpdateOne { - rtuo.mutation.ClearScopes() - return rtuo +func (_u *RefreshTokenUpdateOne) ClearScopes() *RefreshTokenUpdateOne { + _u.mutation.ClearScopes() + return _u } // SetNonce sets the "nonce" field. -func (rtuo *RefreshTokenUpdateOne) SetNonce(s string) *RefreshTokenUpdateOne { - rtuo.mutation.SetNonce(s) - return rtuo +func (_u *RefreshTokenUpdateOne) SetNonce(v string) *RefreshTokenUpdateOne { + _u.mutation.SetNonce(v) + return _u +} + +// SetNillableNonce sets the "nonce" field if the given value is not nil. +func (_u *RefreshTokenUpdateOne) SetNillableNonce(v *string) *RefreshTokenUpdateOne { + if v != nil { + _u.SetNonce(*v) + } + return _u } // SetClaimsUserID sets the "claims_user_id" field. -func (rtuo *RefreshTokenUpdateOne) SetClaimsUserID(s string) *RefreshTokenUpdateOne { - rtuo.mutation.SetClaimsUserID(s) - return rtuo +func (_u *RefreshTokenUpdateOne) SetClaimsUserID(v string) *RefreshTokenUpdateOne { + _u.mutation.SetClaimsUserID(v) + return _u +} + +// SetNillableClaimsUserID sets the "claims_user_id" field if the given value is not nil. +func (_u *RefreshTokenUpdateOne) SetNillableClaimsUserID(v *string) *RefreshTokenUpdateOne { + if v != nil { + _u.SetClaimsUserID(*v) + } + return _u } // SetClaimsUsername sets the "claims_username" field. -func (rtuo *RefreshTokenUpdateOne) SetClaimsUsername(s string) *RefreshTokenUpdateOne { - rtuo.mutation.SetClaimsUsername(s) - return rtuo +func (_u *RefreshTokenUpdateOne) SetClaimsUsername(v string) *RefreshTokenUpdateOne { + _u.mutation.SetClaimsUsername(v) + return _u +} + +// SetNillableClaimsUsername sets the "claims_username" field if the given value is not nil. +func (_u *RefreshTokenUpdateOne) SetNillableClaimsUsername(v *string) *RefreshTokenUpdateOne { + if v != nil { + _u.SetClaimsUsername(*v) + } + return _u } // SetClaimsEmail sets the "claims_email" field. -func (rtuo *RefreshTokenUpdateOne) SetClaimsEmail(s string) *RefreshTokenUpdateOne { - rtuo.mutation.SetClaimsEmail(s) - return rtuo +func (_u *RefreshTokenUpdateOne) SetClaimsEmail(v string) *RefreshTokenUpdateOne { + _u.mutation.SetClaimsEmail(v) + return _u +} + +// SetNillableClaimsEmail sets the "claims_email" field if the given value is not nil. +func (_u *RefreshTokenUpdateOne) SetNillableClaimsEmail(v *string) *RefreshTokenUpdateOne { + if v != nil { + _u.SetClaimsEmail(*v) + } + return _u } // SetClaimsEmailVerified sets the "claims_email_verified" field. -func (rtuo *RefreshTokenUpdateOne) SetClaimsEmailVerified(b bool) *RefreshTokenUpdateOne { - rtuo.mutation.SetClaimsEmailVerified(b) - return rtuo +func (_u *RefreshTokenUpdateOne) SetClaimsEmailVerified(v bool) *RefreshTokenUpdateOne { + _u.mutation.SetClaimsEmailVerified(v) + return _u +} + +// SetNillableClaimsEmailVerified sets the "claims_email_verified" field if the given value is not nil. +func (_u *RefreshTokenUpdateOne) SetNillableClaimsEmailVerified(v *bool) *RefreshTokenUpdateOne { + if v != nil { + _u.SetClaimsEmailVerified(*v) + } + return _u } // SetClaimsGroups sets the "claims_groups" field. -func (rtuo *RefreshTokenUpdateOne) SetClaimsGroups(s []string) *RefreshTokenUpdateOne { - rtuo.mutation.SetClaimsGroups(s) - return rtuo +func (_u *RefreshTokenUpdateOne) SetClaimsGroups(v []string) *RefreshTokenUpdateOne { + _u.mutation.SetClaimsGroups(v) + return _u +} + +// AppendClaimsGroups appends value to the "claims_groups" field. +func (_u *RefreshTokenUpdateOne) AppendClaimsGroups(v []string) *RefreshTokenUpdateOne { + _u.mutation.AppendClaimsGroups(v) + return _u } // ClearClaimsGroups clears the value of the "claims_groups" field. -func (rtuo *RefreshTokenUpdateOne) ClearClaimsGroups() *RefreshTokenUpdateOne { - rtuo.mutation.ClearClaimsGroups() - return rtuo +func (_u *RefreshTokenUpdateOne) ClearClaimsGroups() *RefreshTokenUpdateOne { + _u.mutation.ClearClaimsGroups() + return _u } // SetClaimsPreferredUsername sets the "claims_preferred_username" field. -func (rtuo *RefreshTokenUpdateOne) SetClaimsPreferredUsername(s string) *RefreshTokenUpdateOne { - rtuo.mutation.SetClaimsPreferredUsername(s) - return rtuo +func (_u *RefreshTokenUpdateOne) SetClaimsPreferredUsername(v string) *RefreshTokenUpdateOne { + _u.mutation.SetClaimsPreferredUsername(v) + return _u } // SetNillableClaimsPreferredUsername sets the "claims_preferred_username" field if the given value is not nil. -func (rtuo *RefreshTokenUpdateOne) SetNillableClaimsPreferredUsername(s *string) *RefreshTokenUpdateOne { - if s != nil { - rtuo.SetClaimsPreferredUsername(*s) +func (_u *RefreshTokenUpdateOne) SetNillableClaimsPreferredUsername(v *string) *RefreshTokenUpdateOne { + if v != nil { + _u.SetClaimsPreferredUsername(*v) } - return rtuo + return _u } // SetConnectorID sets the "connector_id" field. -func (rtuo *RefreshTokenUpdateOne) SetConnectorID(s string) *RefreshTokenUpdateOne { - rtuo.mutation.SetConnectorID(s) - return rtuo +func (_u *RefreshTokenUpdateOne) SetConnectorID(v string) *RefreshTokenUpdateOne { + _u.mutation.SetConnectorID(v) + return _u +} + +// SetNillableConnectorID sets the "connector_id" field if the given value is not nil. +func (_u *RefreshTokenUpdateOne) SetNillableConnectorID(v *string) *RefreshTokenUpdateOne { + if v != nil { + _u.SetConnectorID(*v) + } + return _u } // SetConnectorData sets the "connector_data" field. -func (rtuo *RefreshTokenUpdateOne) SetConnectorData(b []byte) *RefreshTokenUpdateOne { - rtuo.mutation.SetConnectorData(b) - return rtuo +func (_u *RefreshTokenUpdateOne) SetConnectorData(v []byte) *RefreshTokenUpdateOne { + _u.mutation.SetConnectorData(v) + return _u } // ClearConnectorData clears the value of the "connector_data" field. -func (rtuo *RefreshTokenUpdateOne) ClearConnectorData() *RefreshTokenUpdateOne { - rtuo.mutation.ClearConnectorData() - return rtuo +func (_u *RefreshTokenUpdateOne) ClearConnectorData() *RefreshTokenUpdateOne { + _u.mutation.ClearConnectorData() + return _u } // SetToken sets the "token" field. -func (rtuo *RefreshTokenUpdateOne) SetToken(s string) *RefreshTokenUpdateOne { - rtuo.mutation.SetToken(s) - return rtuo +func (_u *RefreshTokenUpdateOne) SetToken(v string) *RefreshTokenUpdateOne { + _u.mutation.SetToken(v) + return _u } // SetNillableToken sets the "token" field if the given value is not nil. -func (rtuo *RefreshTokenUpdateOne) SetNillableToken(s *string) *RefreshTokenUpdateOne { - if s != nil { - rtuo.SetToken(*s) +func (_u *RefreshTokenUpdateOne) SetNillableToken(v *string) *RefreshTokenUpdateOne { + if v != nil { + _u.SetToken(*v) } - return rtuo + return _u } // SetObsoleteToken sets the "obsolete_token" field. -func (rtuo *RefreshTokenUpdateOne) SetObsoleteToken(s string) *RefreshTokenUpdateOne { - rtuo.mutation.SetObsoleteToken(s) - return rtuo +func (_u *RefreshTokenUpdateOne) SetObsoleteToken(v string) *RefreshTokenUpdateOne { + _u.mutation.SetObsoleteToken(v) + return _u } // SetNillableObsoleteToken sets the "obsolete_token" field if the given value is not nil. -func (rtuo *RefreshTokenUpdateOne) SetNillableObsoleteToken(s *string) *RefreshTokenUpdateOne { - if s != nil { - rtuo.SetObsoleteToken(*s) +func (_u *RefreshTokenUpdateOne) SetNillableObsoleteToken(v *string) *RefreshTokenUpdateOne { + if v != nil { + _u.SetObsoleteToken(*v) } - return rtuo + return _u } // SetCreatedAt sets the "created_at" field. -func (rtuo *RefreshTokenUpdateOne) SetCreatedAt(t time.Time) *RefreshTokenUpdateOne { - rtuo.mutation.SetCreatedAt(t) - return rtuo +func (_u *RefreshTokenUpdateOne) SetCreatedAt(v time.Time) *RefreshTokenUpdateOne { + _u.mutation.SetCreatedAt(v) + return _u } // SetNillableCreatedAt sets the "created_at" field if the given value is not nil. -func (rtuo *RefreshTokenUpdateOne) SetNillableCreatedAt(t *time.Time) *RefreshTokenUpdateOne { - if t != nil { - rtuo.SetCreatedAt(*t) +func (_u *RefreshTokenUpdateOne) SetNillableCreatedAt(v *time.Time) *RefreshTokenUpdateOne { + if v != nil { + _u.SetCreatedAt(*v) } - return rtuo + return _u } // SetLastUsed sets the "last_used" field. -func (rtuo *RefreshTokenUpdateOne) SetLastUsed(t time.Time) *RefreshTokenUpdateOne { - rtuo.mutation.SetLastUsed(t) - return rtuo +func (_u *RefreshTokenUpdateOne) SetLastUsed(v time.Time) *RefreshTokenUpdateOne { + _u.mutation.SetLastUsed(v) + return _u } // SetNillableLastUsed sets the "last_used" field if the given value is not nil. -func (rtuo *RefreshTokenUpdateOne) SetNillableLastUsed(t *time.Time) *RefreshTokenUpdateOne { - if t != nil { - rtuo.SetLastUsed(*t) +func (_u *RefreshTokenUpdateOne) SetNillableLastUsed(v *time.Time) *RefreshTokenUpdateOne { + if v != nil { + _u.SetLastUsed(*v) } - return rtuo + return _u } // Mutation returns the RefreshTokenMutation object of the builder. -func (rtuo *RefreshTokenUpdateOne) Mutation() *RefreshTokenMutation { - return rtuo.mutation +func (_u *RefreshTokenUpdateOne) Mutation() *RefreshTokenMutation { + return _u.mutation +} + +// Where appends a list predicates to the RefreshTokenUpdate builder. +func (_u *RefreshTokenUpdateOne) Where(ps ...predicate.RefreshToken) *RefreshTokenUpdateOne { + _u.mutation.Where(ps...) + return _u } // Select allows selecting one or more fields (columns) of the returned entity. // The default is selecting all fields defined in the entity schema. -func (rtuo *RefreshTokenUpdateOne) Select(field string, fields ...string) *RefreshTokenUpdateOne { - rtuo.fields = append([]string{field}, fields...) - return rtuo +func (_u *RefreshTokenUpdateOne) Select(field string, fields ...string) *RefreshTokenUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u } // Save executes the query and returns the updated RefreshToken entity. -func (rtuo *RefreshTokenUpdateOne) Save(ctx context.Context) (*RefreshToken, error) { - var ( - err error - node *RefreshToken - ) - if len(rtuo.hooks) == 0 { - if err = rtuo.check(); err != nil { - return nil, err - } - node, err = rtuo.sqlSave(ctx) - } else { - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*RefreshTokenMutation) - if !ok { - return nil, fmt.Errorf("unexpected mutation type %T", m) - } - if err = rtuo.check(); err != nil { - return nil, err - } - rtuo.mutation = mutation - node, err = rtuo.sqlSave(ctx) - mutation.done = true - return node, err - }) - for i := len(rtuo.hooks) - 1; i >= 0; i-- { - if rtuo.hooks[i] == nil { - return nil, fmt.Errorf("db: uninitialized hook (forgotten import db/runtime?)") - } - mut = rtuo.hooks[i](mut) - } - v, err := mut.Mutate(ctx, rtuo.mutation) - if err != nil { - return nil, err - } - nv, ok := v.(*RefreshToken) - if !ok { - return nil, fmt.Errorf("unexpected node type %T returned from RefreshTokenMutation", v) - } - node = nv - } - return node, err +func (_u *RefreshTokenUpdateOne) Save(ctx context.Context) (*RefreshToken, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) } // SaveX is like Save, but panics if an error occurs. -func (rtuo *RefreshTokenUpdateOne) SaveX(ctx context.Context) *RefreshToken { - node, err := rtuo.Save(ctx) +func (_u *RefreshTokenUpdateOne) SaveX(ctx context.Context) *RefreshToken { + node, err := _u.Save(ctx) if err != nil { panic(err) } @@ -650,46 +657,46 @@ func (rtuo *RefreshTokenUpdateOne) SaveX(ctx context.Context) *RefreshToken { } // Exec executes the query on the entity. -func (rtuo *RefreshTokenUpdateOne) Exec(ctx context.Context) error { - _, err := rtuo.Save(ctx) +func (_u *RefreshTokenUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. -func (rtuo *RefreshTokenUpdateOne) ExecX(ctx context.Context) { - if err := rtuo.Exec(ctx); err != nil { +func (_u *RefreshTokenUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. -func (rtuo *RefreshTokenUpdateOne) check() error { - if v, ok := rtuo.mutation.ClientID(); ok { +func (_u *RefreshTokenUpdateOne) check() error { + if v, ok := _u.mutation.ClientID(); ok { if err := refreshtoken.ClientIDValidator(v); err != nil { return &ValidationError{Name: "client_id", err: fmt.Errorf(`db: validator failed for field "RefreshToken.client_id": %w`, err)} } } - if v, ok := rtuo.mutation.Nonce(); ok { + if v, ok := _u.mutation.Nonce(); ok { if err := refreshtoken.NonceValidator(v); err != nil { return &ValidationError{Name: "nonce", err: fmt.Errorf(`db: validator failed for field "RefreshToken.nonce": %w`, err)} } } - if v, ok := rtuo.mutation.ClaimsUserID(); ok { + if v, ok := _u.mutation.ClaimsUserID(); ok { if err := refreshtoken.ClaimsUserIDValidator(v); err != nil { return &ValidationError{Name: "claims_user_id", err: fmt.Errorf(`db: validator failed for field "RefreshToken.claims_user_id": %w`, err)} } } - if v, ok := rtuo.mutation.ClaimsUsername(); ok { + if v, ok := _u.mutation.ClaimsUsername(); ok { if err := refreshtoken.ClaimsUsernameValidator(v); err != nil { return &ValidationError{Name: "claims_username", err: fmt.Errorf(`db: validator failed for field "RefreshToken.claims_username": %w`, err)} } } - if v, ok := rtuo.mutation.ClaimsEmail(); ok { + if v, ok := _u.mutation.ClaimsEmail(); ok { if err := refreshtoken.ClaimsEmailValidator(v); err != nil { return &ValidationError{Name: "claims_email", err: fmt.Errorf(`db: validator failed for field "RefreshToken.claims_email": %w`, err)} } } - if v, ok := rtuo.mutation.ConnectorID(); ok { + if v, ok := _u.mutation.ConnectorID(); ok { if err := refreshtoken.ConnectorIDValidator(v); err != nil { return &ValidationError{Name: "connector_id", err: fmt.Errorf(`db: validator failed for field "RefreshToken.connector_id": %w`, err)} } @@ -697,23 +704,17 @@ func (rtuo *RefreshTokenUpdateOne) check() error { return nil } -func (rtuo *RefreshTokenUpdateOne) sqlSave(ctx context.Context) (_node *RefreshToken, err error) { - _spec := &sqlgraph.UpdateSpec{ - Node: &sqlgraph.NodeSpec{ - Table: refreshtoken.Table, - Columns: refreshtoken.Columns, - ID: &sqlgraph.FieldSpec{ - Type: field.TypeString, - Column: refreshtoken.FieldID, - }, - }, +func (_u *RefreshTokenUpdateOne) sqlSave(ctx context.Context) (_node *RefreshToken, err error) { + if err := _u.check(); err != nil { + return _node, err } - id, ok := rtuo.mutation.ID() + _spec := sqlgraph.NewUpdateSpec(refreshtoken.Table, refreshtoken.Columns, sqlgraph.NewFieldSpec(refreshtoken.FieldID, field.TypeString)) + id, ok := _u.mutation.ID() if !ok { return nil, &ValidationError{Name: "id", err: errors.New(`db: missing "RefreshToken.id" for update`)} } _spec.Node.ID.Value = id - if fields := rtuo.fields; len(fields) > 0 { + if fields := _u.fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, refreshtoken.FieldID) for _, f := range fields { @@ -725,140 +726,81 @@ func (rtuo *RefreshTokenUpdateOne) sqlSave(ctx context.Context) (_node *RefreshT } } } - if ps := rtuo.mutation.predicates; len(ps) > 0 { + if ps := _u.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } - if value, ok := rtuo.mutation.ClientID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldClientID, - }) + if value, ok := _u.mutation.ClientID(); ok { + _spec.SetField(refreshtoken.FieldClientID, field.TypeString, value) } - if value, ok := rtuo.mutation.Scopes(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: refreshtoken.FieldScopes, - }) + if value, ok := _u.mutation.Scopes(); ok { + _spec.SetField(refreshtoken.FieldScopes, field.TypeJSON, value) } - if rtuo.mutation.ScopesCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: refreshtoken.FieldScopes, + if value, ok := _u.mutation.AppendedScopes(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, refreshtoken.FieldScopes, value) }) } - if value, ok := rtuo.mutation.Nonce(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldNonce, - }) + if _u.mutation.ScopesCleared() { + _spec.ClearField(refreshtoken.FieldScopes, field.TypeJSON) } - if value, ok := rtuo.mutation.ClaimsUserID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldClaimsUserID, - }) + if value, ok := _u.mutation.Nonce(); ok { + _spec.SetField(refreshtoken.FieldNonce, field.TypeString, value) } - if value, ok := rtuo.mutation.ClaimsUsername(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldClaimsUsername, - }) + if value, ok := _u.mutation.ClaimsUserID(); ok { + _spec.SetField(refreshtoken.FieldClaimsUserID, field.TypeString, value) } - if value, ok := rtuo.mutation.ClaimsEmail(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldClaimsEmail, - }) + if value, ok := _u.mutation.ClaimsUsername(); ok { + _spec.SetField(refreshtoken.FieldClaimsUsername, field.TypeString, value) } - if value, ok := rtuo.mutation.ClaimsEmailVerified(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBool, - Value: value, - Column: refreshtoken.FieldClaimsEmailVerified, - }) + if value, ok := _u.mutation.ClaimsEmail(); ok { + _spec.SetField(refreshtoken.FieldClaimsEmail, field.TypeString, value) } - if value, ok := rtuo.mutation.ClaimsGroups(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Value: value, - Column: refreshtoken.FieldClaimsGroups, - }) + if value, ok := _u.mutation.ClaimsEmailVerified(); ok { + _spec.SetField(refreshtoken.FieldClaimsEmailVerified, field.TypeBool, value) } - if rtuo.mutation.ClaimsGroupsCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeJSON, - Column: refreshtoken.FieldClaimsGroups, - }) + if value, ok := _u.mutation.ClaimsGroups(); ok { + _spec.SetField(refreshtoken.FieldClaimsGroups, field.TypeJSON, value) } - if value, ok := rtuo.mutation.ClaimsPreferredUsername(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldClaimsPreferredUsername, + if value, ok := _u.mutation.AppendedClaimsGroups(); ok { + _spec.AddModifier(func(u *sql.UpdateBuilder) { + sqljson.Append(u, refreshtoken.FieldClaimsGroups, value) }) } - if value, ok := rtuo.mutation.ConnectorID(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldConnectorID, - }) + if _u.mutation.ClaimsGroupsCleared() { + _spec.ClearField(refreshtoken.FieldClaimsGroups, field.TypeJSON) } - if value, ok := rtuo.mutation.ConnectorData(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Value: value, - Column: refreshtoken.FieldConnectorData, - }) + if value, ok := _u.mutation.ClaimsPreferredUsername(); ok { + _spec.SetField(refreshtoken.FieldClaimsPreferredUsername, field.TypeString, value) } - if rtuo.mutation.ConnectorDataCleared() { - _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ - Type: field.TypeBytes, - Column: refreshtoken.FieldConnectorData, - }) + if value, ok := _u.mutation.ConnectorID(); ok { + _spec.SetField(refreshtoken.FieldConnectorID, field.TypeString, value) } - if value, ok := rtuo.mutation.Token(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldToken, - }) + if value, ok := _u.mutation.ConnectorData(); ok { + _spec.SetField(refreshtoken.FieldConnectorData, field.TypeBytes, value) } - if value, ok := rtuo.mutation.ObsoleteToken(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeString, - Value: value, - Column: refreshtoken.FieldObsoleteToken, - }) + if _u.mutation.ConnectorDataCleared() { + _spec.ClearField(refreshtoken.FieldConnectorData, field.TypeBytes) } - if value, ok := rtuo.mutation.CreatedAt(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: refreshtoken.FieldCreatedAt, - }) + if value, ok := _u.mutation.Token(); ok { + _spec.SetField(refreshtoken.FieldToken, field.TypeString, value) } - if value, ok := rtuo.mutation.LastUsed(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: refreshtoken.FieldLastUsed, - }) + if value, ok := _u.mutation.ObsoleteToken(); ok { + _spec.SetField(refreshtoken.FieldObsoleteToken, field.TypeString, value) + } + if value, ok := _u.mutation.CreatedAt(); ok { + _spec.SetField(refreshtoken.FieldCreatedAt, field.TypeTime, value) + } + if value, ok := _u.mutation.LastUsed(); ok { + _spec.SetField(refreshtoken.FieldLastUsed, field.TypeTime, value) } - _node = &RefreshToken{config: rtuo.config} + _node = &RefreshToken{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues - if err = sqlgraph.UpdateNode(ctx, rtuo.driver, _spec); err != nil { + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{refreshtoken.Label} } else if sqlgraph.IsConstraintError(err) { @@ -866,5 +808,6 @@ func (rtuo *RefreshTokenUpdateOne) sqlSave(ctx context.Context) (_node *RefreshT } return nil, err } + _u.mutation.done = true return _node, nil } diff --git a/storage/ent/db/runtime/runtime.go b/storage/ent/db/runtime/runtime.go index 9000ac4746..ac832af99d 100644 --- a/storage/ent/db/runtime/runtime.go +++ b/storage/ent/db/runtime/runtime.go @@ -5,6 +5,6 @@ package runtime // The schema-stitching logic is generated in github.com/dexidp/dex/storage/ent/db/runtime.go const ( - Version = "v0.11.2" // Version of ent codegen. - Sum = "h1:UM2/BUhF2FfsxPHRxLjQbhqJNaDdVlOwNIAMLs2jyto=" // Sum of ent codegen. + Version = "v0.14.5" // Version of ent codegen. + Sum = "h1:Rj2WOYJtCkWyFo6a+5wB3EfBRP0rnx1fMk6gGA0UUe4=" // Sum of ent codegen. ) diff --git a/storage/ent/db/tx.go b/storage/ent/db/tx.go index 73d1944790..42ba241a7e 100644 --- a/storage/ent/db/tx.go +++ b/storage/ent/db/tx.go @@ -36,12 +36,6 @@ type Tx struct { // lazily loaded. client *Client clientOnce sync.Once - - // completion callbacks. - mu sync.Mutex - onCommit []CommitHook - onRollback []RollbackHook - // ctx lives for the life of the transaction. It is // the same context used by the underlying connection. ctx context.Context @@ -86,9 +80,9 @@ func (tx *Tx) Commit() error { var fn Committer = CommitFunc(func(context.Context, *Tx) error { return txDriver.tx.Commit() }) - tx.mu.Lock() - hooks := append([]CommitHook(nil), tx.onCommit...) - tx.mu.Unlock() + txDriver.mu.Lock() + hooks := append([]CommitHook(nil), txDriver.onCommit...) + txDriver.mu.Unlock() for i := len(hooks) - 1; i >= 0; i-- { fn = hooks[i](fn) } @@ -97,9 +91,10 @@ func (tx *Tx) Commit() error { // OnCommit adds a hook to call on commit. func (tx *Tx) OnCommit(f CommitHook) { - tx.mu.Lock() - defer tx.mu.Unlock() - tx.onCommit = append(tx.onCommit, f) + txDriver := tx.config.driver.(*txDriver) + txDriver.mu.Lock() + txDriver.onCommit = append(txDriver.onCommit, f) + txDriver.mu.Unlock() } type ( @@ -141,9 +136,9 @@ func (tx *Tx) Rollback() error { var fn Rollbacker = RollbackFunc(func(context.Context, *Tx) error { return txDriver.tx.Rollback() }) - tx.mu.Lock() - hooks := append([]RollbackHook(nil), tx.onRollback...) - tx.mu.Unlock() + txDriver.mu.Lock() + hooks := append([]RollbackHook(nil), txDriver.onRollback...) + txDriver.mu.Unlock() for i := len(hooks) - 1; i >= 0; i-- { fn = hooks[i](fn) } @@ -152,9 +147,10 @@ func (tx *Tx) Rollback() error { // OnRollback adds a hook to call on rollback. func (tx *Tx) OnRollback(f RollbackHook) { - tx.mu.Lock() - defer tx.mu.Unlock() - tx.onRollback = append(tx.onRollback, f) + txDriver := tx.config.driver.(*txDriver) + txDriver.mu.Lock() + txDriver.onRollback = append(txDriver.onRollback, f) + txDriver.mu.Unlock() } // Client returns a Client that binds to current transaction. @@ -195,6 +191,10 @@ type txDriver struct { drv dialect.Driver // tx is the underlying transaction. tx dialect.Tx + // completion hooks. + mu sync.Mutex + onCommit []CommitHook + onRollback []RollbackHook } // newTx creates a new transactional driver. @@ -225,12 +225,12 @@ func (*txDriver) Commit() error { return nil } func (*txDriver) Rollback() error { return nil } // Exec calls tx.Exec. -func (tx *txDriver) Exec(ctx context.Context, query string, args, v interface{}) error { +func (tx *txDriver) Exec(ctx context.Context, query string, args, v any) error { return tx.tx.Exec(ctx, query, args, v) } // Query calls tx.Query. -func (tx *txDriver) Query(ctx context.Context, query string, args, v interface{}) error { +func (tx *txDriver) Query(ctx context.Context, query string, args, v any) error { return tx.tx.Query(ctx, query, args, v) } diff --git a/storage/ent/generate.go b/storage/ent/generate.go index 805e8cdb33..8f94740526 100644 --- a/storage/ent/generate.go +++ b/storage/ent/generate.go @@ -1,3 +1,3 @@ package ent -//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate ./schema --target ./db +//go:generate go tool entgo.io/ent/cmd/ent generate ./schema --target ./db diff --git a/storage/ent/mysql.go b/storage/ent/mysql.go index 4a9407f95c..bca6eba50f 100644 --- a/storage/ent/mysql.go +++ b/storage/ent/mysql.go @@ -7,6 +7,7 @@ import ( "crypto/x509" "database/sql" "fmt" + "log/slog" "net" "os" "strconv" @@ -15,7 +16,6 @@ import ( entSQL "entgo.io/ent/dialect/sql" "github.com/go-sql-driver/mysql" // Register mysql driver. - "github.com/dexidp/dex/pkg/log" "github.com/dexidp/dex/storage" "github.com/dexidp/dex/storage/ent/client" "github.com/dexidp/dex/storage/ent/db" @@ -39,7 +39,7 @@ type MySQL struct { } // Open always returns a new in sqlite3 storage. -func (m *MySQL) Open(logger log.Logger) (storage.Storage, error) { +func (m *MySQL) Open(logger *slog.Logger) (storage.Storage, error) { logger.Debug("experimental ent-based storage driver is enabled") drv, err := m.driver() if err != nil { @@ -81,7 +81,7 @@ func (m *MySQL) driver() (*entSQL.Driver, error) { } if m.MaxIdleConns == 0 { - /* Override default behaviour to fix https://github.com/dexidp/dex/issues/1608 */ + /* Override default behavior to fix https://github.com/dexidp/dex/issues/1608 */ drv.DB().SetMaxIdleConns(0) } else { drv.DB().SetMaxIdleConns(m.MaxIdleConns) diff --git a/storage/ent/mysql_test.go b/storage/ent/mysql_test.go index 6c2dfa1ddf..a1baffb39d 100644 --- a/storage/ent/mysql_test.go +++ b/storage/ent/mysql_test.go @@ -1,11 +1,11 @@ package ent import ( + "log/slog" "os" "strconv" "testing" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" "github.com/dexidp/dex/storage" @@ -30,7 +30,9 @@ func mysqlTestConfig(host string, port uint64) *MySQL { Port: uint16(port), }, SSL: SSL{ - Mode: mysqlSSLSkipVerify, + // This was originally mysqlSSLSkipVerify. It lead to handshake errors. + // See https://github.com/go-sql-driver/mysql/issues/1635 for more details. + Mode: mysqlSSLFalse, }, params: map[string]string{ "innodb_lock_wait_timeout": "1", @@ -38,12 +40,8 @@ func mysqlTestConfig(host string, port uint64) *MySQL { } } -func newMySQLStorage(host string, port uint64) storage.Storage { - logger := &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, - } +func newMySQLStorage(t *testing.T, host string, port uint64) storage.Storage { + logger := slog.New(slog.NewTextHandler(t.Output(), &slog.HandlerOptions{Level: slog.LevelDebug})) cfg := mysqlTestConfig(host, port) s, err := cfg.Open(logger) @@ -67,8 +65,8 @@ func TestMySQL(t *testing.T) { require.NoError(t, err, "invalid mysql port %q: %s", rawPort, err) } - newStorage := func() storage.Storage { - return newMySQLStorage(host, port) + newStorage := func(t *testing.T) storage.Storage { + return newMySQLStorage(t, host, port) } conformance.RunTests(t, newStorage) conformance.RunTransactionTests(t, newStorage) diff --git a/storage/ent/postgres.go b/storage/ent/postgres.go index 1953f5992f..dad81df445 100644 --- a/storage/ent/postgres.go +++ b/storage/ent/postgres.go @@ -5,6 +5,7 @@ import ( "crypto/sha256" "database/sql" "fmt" + "log/slog" "net" "regexp" "strconv" @@ -14,13 +15,11 @@ import ( entSQL "entgo.io/ent/dialect/sql" _ "github.com/lib/pq" // Register postgres driver. - "github.com/dexidp/dex/pkg/log" "github.com/dexidp/dex/storage" "github.com/dexidp/dex/storage/ent/client" "github.com/dexidp/dex/storage/ent/db" ) -// nolint const ( // postgres SSL modes pgSSLDisable = "disable" @@ -37,7 +36,7 @@ type Postgres struct { } // Open always returns a new in sqlite3 storage. -func (p *Postgres) Open(logger log.Logger) (storage.Storage, error) { +func (p *Postgres) Open(logger *slog.Logger) (storage.Storage, error) { logger.Debug("experimental ent-based storage driver is enabled") drv, err := p.driver() if err != nil { diff --git a/storage/ent/postgres_test.go b/storage/ent/postgres_test.go index c8e3a54df2..bbbde38edd 100644 --- a/storage/ent/postgres_test.go +++ b/storage/ent/postgres_test.go @@ -1,11 +1,11 @@ package ent import ( + "log/slog" "os" "strconv" "testing" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" "github.com/dexidp/dex/storage" @@ -35,12 +35,8 @@ func postgresTestConfig(host string, port uint64) *Postgres { } } -func newPostgresStorage(host string, port uint64) storage.Storage { - logger := &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, - } +func newPostgresStorage(t *testing.T, host string, port uint64) storage.Storage { + logger := slog.New(slog.NewTextHandler(t.Output(), &slog.HandlerOptions{Level: slog.LevelDebug})) cfg := postgresTestConfig(host, port) s, err := cfg.Open(logger) @@ -64,8 +60,8 @@ func TestPostgres(t *testing.T) { require.NoError(t, err, "invalid postgres port %q: %s", rawPort, err) } - newStorage := func() storage.Storage { - return newPostgresStorage(host, port) + newStorage := func(t *testing.T) storage.Storage { + return newPostgresStorage(t, host, port) } conformance.RunTests(t, newStorage) conformance.RunTransactionTests(t, newStorage) diff --git a/storage/ent/schema/authrequest.go b/storage/ent/schema/authrequest.go index 7d41e83082..2b75927b6f 100644 --- a/storage/ent/schema/authrequest.go +++ b/storage/ent/schema/authrequest.go @@ -27,7 +27,8 @@ create table auth_request expiry timestamp not null, claims_preferred_username text default '' not null, code_challenge text default '' not null, - code_challenge_method text default '' not null + code_challenge_method text default '' not null, + hmac_key blob ); */ @@ -86,6 +87,7 @@ func (AuthRequest) Fields() []ent.Field { field.Text("code_challenge_method"). SchemaType(textSchema). Default(""), + field.Bytes("hmac_key"), } } diff --git a/storage/ent/schema/keys.go b/storage/ent/schema/keys.go index ec5cd3f6bb..b8e56817b5 100644 --- a/storage/ent/schema/keys.go +++ b/storage/ent/schema/keys.go @@ -3,7 +3,7 @@ package schema import ( "entgo.io/ent" "entgo.io/ent/schema/field" - "gopkg.in/square/go-jose.v2" + "github.com/go-jose/go-jose/v4" "github.com/dexidp/dex/storage" ) diff --git a/storage/ent/sqlite.go b/storage/ent/sqlite.go index c0b442f400..8c5287ef50 100644 --- a/storage/ent/sqlite.go +++ b/storage/ent/sqlite.go @@ -3,12 +3,12 @@ package ent import ( "context" "crypto/sha256" + "log/slog" "strings" "entgo.io/ent/dialect/sql" _ "github.com/mattn/go-sqlite3" // Register sqlite driver. - "github.com/dexidp/dex/pkg/log" "github.com/dexidp/dex/storage" "github.com/dexidp/dex/storage/ent/client" "github.com/dexidp/dex/storage/ent/db" @@ -20,7 +20,7 @@ type SQLite3 struct { } // Open always returns a new in sqlite3 storage. -func (s *SQLite3) Open(logger log.Logger) (storage.Storage, error) { +func (s *SQLite3) Open(logger *slog.Logger) (storage.Storage, error) { logger.Debug("experimental ent-based storage driver is enabled") // Implicitly set foreign_keys pragma to "on" because it is required by ent diff --git a/storage/ent/sqlite_test.go b/storage/ent/sqlite_test.go index 301d769b4a..55c1b5c5d8 100644 --- a/storage/ent/sqlite_test.go +++ b/storage/ent/sqlite_test.go @@ -1,21 +1,15 @@ package ent import ( - "os" + "log/slog" "testing" - "github.com/sirupsen/logrus" - "github.com/dexidp/dex/storage" "github.com/dexidp/dex/storage/conformance" ) -func newSQLiteStorage() storage.Storage { - logger := &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, - } +func newSQLiteStorage(t *testing.T) storage.Storage { + logger := slog.New(slog.NewTextHandler(t.Output(), &slog.HandlerOptions{Level: slog.LevelDebug})) cfg := SQLite3{File: ":memory:"} s, err := cfg.Open(logger) diff --git a/storage/etcd/config.go b/storage/etcd/config.go index 7f1a7b4fb7..a8aee39aca 100644 --- a/storage/etcd/config.go +++ b/storage/etcd/config.go @@ -1,13 +1,13 @@ package etcd import ( + "log/slog" "time" "go.etcd.io/etcd/client/pkg/v3/transport" clientv3 "go.etcd.io/etcd/client/v3" "go.etcd.io/etcd/client/v3/namespace" - "github.com/dexidp/dex/pkg/log" "github.com/dexidp/dex/storage" ) @@ -34,11 +34,11 @@ type Etcd struct { } // Open creates a new storage implementation backed by Etcd -func (p *Etcd) Open(logger log.Logger) (storage.Storage, error) { +func (p *Etcd) Open(logger *slog.Logger) (storage.Storage, error) { return p.open(logger) } -func (p *Etcd) open(logger log.Logger) (*conn, error) { +func (p *Etcd) open(logger *slog.Logger) (*conn, error) { cfg := clientv3.Config{ Endpoints: p.Endpoints, DialTimeout: defaultDialTimeout, diff --git a/storage/etcd/etcd.go b/storage/etcd/etcd.go index 13e815ec8d..8ccf502f2e 100644 --- a/storage/etcd/etcd.go +++ b/storage/etcd/etcd.go @@ -4,12 +4,12 @@ import ( "context" "encoding/json" "fmt" + "log/slog" "strings" "time" clientv3 "go.etcd.io/etcd/client/v3" - "github.com/dexidp/dex/pkg/log" "github.com/dexidp/dex/storage" ) @@ -29,17 +29,19 @@ const ( defaultStorageTimeout = 5 * time.Second ) +var _ storage.Storage = (*conn)(nil) + type conn struct { db *clientv3.Client - logger log.Logger + logger *slog.Logger } func (c *conn) Close() error { return c.db.Close() } -func (c *conn) GarbageCollect(now time.Time) (result storage.GCResult, err error) { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) GarbageCollect(ctx context.Context, now time.Time) (result storage.GCResult, err error) { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() authRequests, err := c.listAuthRequests(ctx) if err != nil { @@ -50,7 +52,7 @@ func (c *conn) GarbageCollect(now time.Time) (result storage.GCResult, err error for _, authRequest := range authRequests { if now.After(authRequest.Expiry) { if err := c.deleteKey(ctx, keyID(authRequestPrefix, authRequest.ID)); err != nil { - c.logger.Errorf("failed to delete auth request: %v", err) + c.logger.Error("failed to delete auth request", "err", err) delErr = fmt.Errorf("failed to delete auth request: %v", err) } result.AuthRequests++ @@ -68,7 +70,7 @@ func (c *conn) GarbageCollect(now time.Time) (result storage.GCResult, err error for _, authCode := range authCodes { if now.After(authCode.Expiry) { if err := c.deleteKey(ctx, keyID(authCodePrefix, authCode.ID)); err != nil { - c.logger.Errorf("failed to delete auth code %v", err) + c.logger.Error("failed to delete auth code", "err", err) delErr = fmt.Errorf("failed to delete auth code: %v", err) } result.AuthCodes++ @@ -83,7 +85,7 @@ func (c *conn) GarbageCollect(now time.Time) (result storage.GCResult, err error for _, deviceRequest := range deviceRequests { if now.After(deviceRequest.Expiry) { if err := c.deleteKey(ctx, keyID(deviceRequestPrefix, deviceRequest.UserCode)); err != nil { - c.logger.Errorf("failed to delete device request %v", err) + c.logger.Error("failed to delete device request", "err", err) delErr = fmt.Errorf("failed to delete device request: %v", err) } result.DeviceRequests++ @@ -98,7 +100,7 @@ func (c *conn) GarbageCollect(now time.Time) (result storage.GCResult, err error for _, deviceToken := range deviceTokens { if now.After(deviceToken.Expiry) { if err := c.deleteKey(ctx, keyID(deviceTokenPrefix, deviceToken.DeviceCode)); err != nil { - c.logger.Errorf("failed to delete device token %v", err) + c.logger.Error("failed to delete device token", "err", err) delErr = fmt.Errorf("failed to delete device token: %v", err) } result.DeviceTokens++ @@ -107,14 +109,13 @@ func (c *conn) GarbageCollect(now time.Time) (result storage.GCResult, err error return result, delErr } -func (c *conn) CreateAuthRequest(a storage.AuthRequest) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) - defer cancel() +func (c *conn) CreateAuthRequest(ctx context.Context, a storage.AuthRequest) error { return c.txnCreate(ctx, keyID(authRequestPrefix, a.ID), fromStorageAuthRequest(a)) } -func (c *conn) GetAuthRequest(id string) (a storage.AuthRequest, err error) { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) GetAuthRequest(ctx context.Context, id string) (a storage.AuthRequest, err error) { + // TODO: Add this to other funcs?? + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() var req AuthRequest if err = c.getKey(ctx, keyID(authRequestPrefix, id), &req); err != nil { @@ -123,8 +124,8 @@ func (c *conn) GetAuthRequest(id string) (a storage.AuthRequest, err error) { return toStorageAuthRequest(req), nil } -func (c *conn) UpdateAuthRequest(id string, updater func(a storage.AuthRequest) (storage.AuthRequest, error)) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) UpdateAuthRequest(ctx context.Context, id string, updater func(a storage.AuthRequest) (storage.AuthRequest, error)) error { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() return c.txnUpdate(ctx, keyID(authRequestPrefix, id), func(currentValue []byte) ([]byte, error) { var current AuthRequest @@ -141,20 +142,18 @@ func (c *conn) UpdateAuthRequest(id string, updater func(a storage.AuthRequest) }) } -func (c *conn) DeleteAuthRequest(id string) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) DeleteAuthRequest(ctx context.Context, id string) error { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() return c.deleteKey(ctx, keyID(authRequestPrefix, id)) } -func (c *conn) CreateAuthCode(a storage.AuthCode) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) - defer cancel() +func (c *conn) CreateAuthCode(ctx context.Context, a storage.AuthCode) error { return c.txnCreate(ctx, keyID(authCodePrefix, a.ID), fromStorageAuthCode(a)) } -func (c *conn) GetAuthCode(id string) (a storage.AuthCode, err error) { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) GetAuthCode(ctx context.Context, id string) (a storage.AuthCode, err error) { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() var ac AuthCode err = c.getKey(ctx, keyID(authCodePrefix, id), &ac) @@ -164,20 +163,18 @@ func (c *conn) GetAuthCode(id string) (a storage.AuthCode, err error) { return a, err } -func (c *conn) DeleteAuthCode(id string) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) DeleteAuthCode(ctx context.Context, id string) error { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() return c.deleteKey(ctx, keyID(authCodePrefix, id)) } -func (c *conn) CreateRefresh(r storage.RefreshToken) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) - defer cancel() +func (c *conn) CreateRefresh(ctx context.Context, r storage.RefreshToken) error { return c.txnCreate(ctx, keyID(refreshTokenPrefix, r.ID), fromStorageRefreshToken(r)) } -func (c *conn) GetRefresh(id string) (r storage.RefreshToken, err error) { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) GetRefresh(ctx context.Context, id string) (r storage.RefreshToken, err error) { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() var token RefreshToken if err = c.getKey(ctx, keyID(refreshTokenPrefix, id), &token); err != nil { @@ -186,8 +183,8 @@ func (c *conn) GetRefresh(id string) (r storage.RefreshToken, err error) { return toStorageRefreshToken(token), nil } -func (c *conn) UpdateRefreshToken(id string, updater func(old storage.RefreshToken) (storage.RefreshToken, error)) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) UpdateRefreshToken(ctx context.Context, id string, updater func(old storage.RefreshToken) (storage.RefreshToken, error)) error { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() return c.txnUpdate(ctx, keyID(refreshTokenPrefix, id), func(currentValue []byte) ([]byte, error) { var current RefreshToken @@ -204,14 +201,14 @@ func (c *conn) UpdateRefreshToken(id string, updater func(old storage.RefreshTok }) } -func (c *conn) DeleteRefresh(id string) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) DeleteRefresh(ctx context.Context, id string) error { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() return c.deleteKey(ctx, keyID(refreshTokenPrefix, id)) } -func (c *conn) ListRefreshTokens() (tokens []storage.RefreshToken, err error) { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) ListRefreshTokens(ctx context.Context) (tokens []storage.RefreshToken, err error) { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() res, err := c.db.Get(ctx, refreshTokenPrefix, clientv3.WithPrefix()) if err != nil { @@ -227,21 +224,19 @@ func (c *conn) ListRefreshTokens() (tokens []storage.RefreshToken, err error) { return tokens, nil } -func (c *conn) CreateClient(cli storage.Client) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) - defer cancel() +func (c *conn) CreateClient(ctx context.Context, cli storage.Client) error { return c.txnCreate(ctx, keyID(clientPrefix, cli.ID), cli) } -func (c *conn) GetClient(id string) (cli storage.Client, err error) { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) GetClient(ctx context.Context, id string) (cli storage.Client, err error) { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() err = c.getKey(ctx, keyID(clientPrefix, id), &cli) return cli, err } -func (c *conn) UpdateClient(id string, updater func(old storage.Client) (storage.Client, error)) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) UpdateClient(ctx context.Context, id string, updater func(old storage.Client) (storage.Client, error)) error { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() return c.txnUpdate(ctx, keyID(clientPrefix, id), func(currentValue []byte) ([]byte, error) { var current storage.Client @@ -258,14 +253,14 @@ func (c *conn) UpdateClient(id string, updater func(old storage.Client) (storage }) } -func (c *conn) DeleteClient(id string) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) DeleteClient(ctx context.Context, id string) error { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() return c.deleteKey(ctx, keyID(clientPrefix, id)) } -func (c *conn) ListClients() (clients []storage.Client, err error) { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) ListClients(ctx context.Context) (clients []storage.Client, err error) { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() res, err := c.db.Get(ctx, clientPrefix, clientv3.WithPrefix()) if err != nil { @@ -281,21 +276,19 @@ func (c *conn) ListClients() (clients []storage.Client, err error) { return clients, nil } -func (c *conn) CreatePassword(p storage.Password) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) - defer cancel() +func (c *conn) CreatePassword(ctx context.Context, p storage.Password) error { return c.txnCreate(ctx, passwordPrefix+strings.ToLower(p.Email), p) } -func (c *conn) GetPassword(email string) (p storage.Password, err error) { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) GetPassword(ctx context.Context, email string) (p storage.Password, err error) { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() err = c.getKey(ctx, keyEmail(passwordPrefix, email), &p) return p, err } -func (c *conn) UpdatePassword(email string, updater func(p storage.Password) (storage.Password, error)) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) UpdatePassword(ctx context.Context, email string, updater func(p storage.Password) (storage.Password, error)) error { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() return c.txnUpdate(ctx, keyEmail(passwordPrefix, email), func(currentValue []byte) ([]byte, error) { var current storage.Password @@ -312,14 +305,14 @@ func (c *conn) UpdatePassword(email string, updater func(p storage.Password) (st }) } -func (c *conn) DeletePassword(email string) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) DeletePassword(ctx context.Context, email string) error { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() return c.deleteKey(ctx, keyEmail(passwordPrefix, email)) } -func (c *conn) ListPasswords() (passwords []storage.Password, err error) { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) ListPasswords(ctx context.Context) (passwords []storage.Password, err error) { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() res, err := c.db.Get(ctx, passwordPrefix, clientv3.WithPrefix()) if err != nil { @@ -335,14 +328,12 @@ func (c *conn) ListPasswords() (passwords []storage.Password, err error) { return passwords, nil } -func (c *conn) CreateOfflineSessions(s storage.OfflineSessions) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) - defer cancel() +func (c *conn) CreateOfflineSessions(ctx context.Context, s storage.OfflineSessions) error { return c.txnCreate(ctx, keySession(s.UserID, s.ConnID), fromStorageOfflineSessions(s)) } -func (c *conn) UpdateOfflineSessions(userID string, connID string, updater func(s storage.OfflineSessions) (storage.OfflineSessions, error)) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) UpdateOfflineSessions(ctx context.Context, userID string, connID string, updater func(s storage.OfflineSessions) (storage.OfflineSessions, error)) error { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() return c.txnUpdate(ctx, keySession(userID, connID), func(currentValue []byte) ([]byte, error) { var current OfflineSessions @@ -359,8 +350,8 @@ func (c *conn) UpdateOfflineSessions(userID string, connID string, updater func( }) } -func (c *conn) GetOfflineSessions(userID string, connID string) (s storage.OfflineSessions, err error) { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) GetOfflineSessions(ctx context.Context, userID string, connID string) (s storage.OfflineSessions, err error) { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() var os OfflineSessions if err = c.getKey(ctx, keySession(userID, connID), &os); err != nil { @@ -369,27 +360,25 @@ func (c *conn) GetOfflineSessions(userID string, connID string) (s storage.Offli return toStorageOfflineSessions(os), nil } -func (c *conn) DeleteOfflineSessions(userID string, connID string) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) DeleteOfflineSessions(ctx context.Context, userID string, connID string) error { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() return c.deleteKey(ctx, keySession(userID, connID)) } -func (c *conn) CreateConnector(connector storage.Connector) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) - defer cancel() +func (c *conn) CreateConnector(ctx context.Context, connector storage.Connector) error { return c.txnCreate(ctx, keyID(connectorPrefix, connector.ID), connector) } -func (c *conn) GetConnector(id string) (conn storage.Connector, err error) { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) GetConnector(ctx context.Context, id string) (conn storage.Connector, err error) { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() err = c.getKey(ctx, keyID(connectorPrefix, id), &conn) return conn, err } -func (c *conn) UpdateConnector(id string, updater func(s storage.Connector) (storage.Connector, error)) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) UpdateConnector(ctx context.Context, id string, updater func(s storage.Connector) (storage.Connector, error)) error { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() return c.txnUpdate(ctx, keyID(connectorPrefix, id), func(currentValue []byte) ([]byte, error) { var current storage.Connector @@ -406,14 +395,14 @@ func (c *conn) UpdateConnector(id string, updater func(s storage.Connector) (sto }) } -func (c *conn) DeleteConnector(id string) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) DeleteConnector(ctx context.Context, id string) error { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() return c.deleteKey(ctx, keyID(connectorPrefix, id)) } -func (c *conn) ListConnectors() (connectors []storage.Connector, err error) { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) ListConnectors(ctx context.Context) (connectors []storage.Connector, err error) { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() res, err := c.db.Get(ctx, connectorPrefix, clientv3.WithPrefix()) if err != nil { @@ -429,8 +418,8 @@ func (c *conn) ListConnectors() (connectors []storage.Connector, err error) { return connectors, nil } -func (c *conn) GetKeys() (keys storage.Keys, err error) { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) GetKeys(ctx context.Context) (keys storage.Keys, err error) { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() res, err := c.db.Get(ctx, keysName) if err != nil { @@ -442,8 +431,8 @@ func (c *conn) GetKeys() (keys storage.Keys, err error) { return keys, err } -func (c *conn) UpdateKeys(updater func(old storage.Keys) (storage.Keys, error)) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) UpdateKeys(ctx context.Context, updater func(old storage.Keys) (storage.Keys, error)) error { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() return c.txnUpdate(ctx, keysName, func(currentValue []byte) ([]byte, error) { var current storage.Keys @@ -568,17 +557,18 @@ func keySession(userID, connID string) string { return offlineSessionPrefix + strings.ToLower(userID+"|"+connID) } -func (c *conn) CreateDeviceRequest(d storage.DeviceRequest) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) - defer cancel() +func (c *conn) CreateDeviceRequest(ctx context.Context, d storage.DeviceRequest) error { return c.txnCreate(ctx, keyID(deviceRequestPrefix, d.UserCode), fromStorageDeviceRequest(d)) } -func (c *conn) GetDeviceRequest(userCode string) (r storage.DeviceRequest, err error) { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) GetDeviceRequest(ctx context.Context, userCode string) (r storage.DeviceRequest, err error) { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() - err = c.getKey(ctx, keyID(deviceRequestPrefix, userCode), &r) - return r, err + var dr DeviceRequest + if err = c.getKey(ctx, keyID(deviceRequestPrefix, userCode), &dr); err == nil { + r = toStorageDeviceRequest(dr) + } + return } func (c *conn) listDeviceRequests(ctx context.Context) (requests []DeviceRequest, err error) { @@ -596,14 +586,12 @@ func (c *conn) listDeviceRequests(ctx context.Context) (requests []DeviceRequest return requests, nil } -func (c *conn) CreateDeviceToken(t storage.DeviceToken) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) - defer cancel() +func (c *conn) CreateDeviceToken(ctx context.Context, t storage.DeviceToken) error { return c.txnCreate(ctx, keyID(deviceTokenPrefix, t.DeviceCode), fromStorageDeviceToken(t)) } -func (c *conn) GetDeviceToken(deviceCode string) (t storage.DeviceToken, err error) { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) GetDeviceToken(ctx context.Context, deviceCode string) (t storage.DeviceToken, err error) { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() var dt DeviceToken if err = c.getKey(ctx, keyID(deviceTokenPrefix, deviceCode), &dt); err == nil { @@ -627,8 +615,8 @@ func (c *conn) listDeviceTokens(ctx context.Context) (deviceTokens []DeviceToken return deviceTokens, nil } -func (c *conn) UpdateDeviceToken(deviceCode string, updater func(old storage.DeviceToken) (storage.DeviceToken, error)) error { - ctx, cancel := context.WithTimeout(context.Background(), defaultStorageTimeout) +func (c *conn) UpdateDeviceToken(ctx context.Context, deviceCode string, updater func(old storage.DeviceToken) (storage.DeviceToken, error)) error { + ctx, cancel := context.WithTimeout(ctx, defaultStorageTimeout) defer cancel() return c.txnUpdate(ctx, keyID(deviceTokenPrefix, deviceCode), func(currentValue []byte) ([]byte, error) { var current DeviceToken diff --git a/storage/etcd/etcd_test.go b/storage/etcd/etcd_test.go index 8a9af5c9d5..6783c25be7 100644 --- a/storage/etcd/etcd_test.go +++ b/storage/etcd/etcd_test.go @@ -3,13 +3,13 @@ package etcd import ( "context" "fmt" + "log/slog" "os" "runtime" "strings" "testing" "time" - "github.com/sirupsen/logrus" clientv3 "go.etcd.io/etcd/client/v3" "github.com/dexidp/dex/storage" @@ -55,12 +55,6 @@ func cleanDB(c *conn) error { return nil } -var logger = &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, -} - func TestEtcd(t *testing.T) { testEtcdEnv := "DEX_ETCD_ENDPOINTS" endpointsStr := os.Getenv(testEtcdEnv) @@ -70,10 +64,11 @@ func TestEtcd(t *testing.T) { } endpoints := strings.Split(endpointsStr, ",") - newStorage := func() storage.Storage { + newStorage := func(t *testing.T) storage.Storage { s := &Etcd{ Endpoints: endpoints, } + logger := slog.New(slog.NewTextHandler(t.Output(), &slog.HandlerOptions{Level: slog.LevelDebug})) conn, err := s.open(logger) if err != nil { fmt.Fprintln(os.Stdout, err) diff --git a/storage/etcd/types.go b/storage/etcd/types.go index 1174a2d201..b3756604dd 100644 --- a/storage/etcd/types.go +++ b/storage/etcd/types.go @@ -3,7 +3,7 @@ package etcd import ( "time" - jose "gopkg.in/square/go-jose.v2" + "github.com/go-jose/go-jose/v4" "github.com/dexidp/dex/storage" ) @@ -84,6 +84,8 @@ type AuthRequest struct { CodeChallenge string `json:"code_challenge,omitempty"` CodeChallengeMethod string `json:"code_challenge_method,omitempty"` + + HMACKey []byte `json:"hmac_key"` } func fromStorageAuthRequest(a storage.AuthRequest) AuthRequest { @@ -103,6 +105,7 @@ func fromStorageAuthRequest(a storage.AuthRequest) AuthRequest { ConnectorData: a.ConnectorData, CodeChallenge: a.PKCE.CodeChallenge, CodeChallengeMethod: a.PKCE.CodeChallengeMethod, + HMACKey: a.HMACKey, } } @@ -125,6 +128,7 @@ func toStorageAuthRequest(a AuthRequest) storage.AuthRequest { CodeChallenge: a.CodeChallenge, CodeChallengeMethod: a.CodeChallengeMethod, }, + HMACKey: a.HMACKey, } } @@ -273,6 +277,17 @@ func fromStorageDeviceRequest(d storage.DeviceRequest) DeviceRequest { } } +func toStorageDeviceRequest(d DeviceRequest) storage.DeviceRequest { + return storage.DeviceRequest{ + UserCode: d.UserCode, + DeviceCode: d.DeviceCode, + ClientID: d.ClientID, + ClientSecret: d.ClientSecret, + Scopes: d.Scopes, + Expiry: d.Expiry, + } +} + // DeviceToken is a mirrored struct from storage with JSON struct tags type DeviceToken struct { DeviceCode string `json:"device_code"` diff --git a/storage/health.go b/storage/health.go index 8a2f5a3d61..fe75a2da74 100644 --- a/storage/health.go +++ b/storage/health.go @@ -2,26 +2,28 @@ package storage import ( "context" + "crypto" "fmt" "time" ) // NewCustomHealthCheckFunc returns a new health check function. func NewCustomHealthCheckFunc(s Storage, now func() time.Time) func(context.Context) (details interface{}, err error) { - return func(_ context.Context) (details interface{}, err error) { + return func(ctx context.Context) (details interface{}, err error) { a := AuthRequest{ ID: NewID(), ClientID: NewID(), // Set a short expiry so if the delete fails this will be cleaned up quickly by garbage collection. - Expiry: now().Add(time.Minute), + Expiry: now().Add(time.Minute), + HMACKey: NewHMACKey(crypto.SHA256), } - if err := s.CreateAuthRequest(a); err != nil { + if err := s.CreateAuthRequest(ctx, a); err != nil { return nil, fmt.Errorf("create auth request: %v", err) } - if err := s.DeleteAuthRequest(a.ID); err != nil { + if err := s.DeleteAuthRequest(ctx, a.ID); err != nil { return nil, fmt.Errorf("delete auth request: %v", err) } diff --git a/storage/kubernetes/client.go b/storage/kubernetes/client.go index 57f21e00cd..4d66b8bcca 100644 --- a/storage/kubernetes/client.go +++ b/storage/kubernetes/client.go @@ -13,11 +13,13 @@ import ( "hash" "hash/fnv" "io" + "log/slog" "net" "net/http" "net/url" "os" "path" + "regexp" "strconv" "strings" "time" @@ -26,16 +28,26 @@ import ( "github.com/ghodss/yaml" "golang.org/x/net/http2" - "github.com/dexidp/dex/pkg/log" "github.com/dexidp/dex/storage" "github.com/dexidp/dex/storage/kubernetes/k8sapi" ) +const ( + serviceAccountPath = "/var/run/secrets/kubernetes.io/serviceaccount/" + serviceAccountTokenPath = serviceAccountPath + "token" + serviceAccountCAPath = serviceAccountPath + "ca.crt" + serviceAccountNamespacePath = serviceAccountPath + "namespace" + + kubernetesServiceHostENV = "KUBERNETES_SERVICE_HOST" + kubernetesServicePortENV = "KUBERNETES_SERVICE_PORT" + kubernetesPodNamespaceENV = "KUBERNETES_POD_NAMESPACE" +) + type client struct { client *http.Client baseURL string namespace string - logger log.Logger + logger *slog.Logger // Hash function to map IDs (which could span a large range) to Kubernetes names. // While this is not currently upgradable, it could be in the future. @@ -83,14 +95,27 @@ func offlineTokenName(userID string, connID string, h func() hash.Hash) string { return strings.TrimRight(encoding.EncodeToString(hash.Sum(nil)), "=") } +// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names +const kubeResourceMaxLen = 253 + +var kubeResourceNameRegex = regexp.MustCompile(`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`) + func (cli *client) urlForWithParams( apiVersion, namespace, resource, name string, params url.Values, -) string { +) (string, error) { basePath := "apis/" if apiVersion == "v1" { basePath = "api/" } + if name != "" && (len(name) > kubeResourceMaxLen || !kubeResourceNameRegex.MatchString(name)) { + // The actual name can be found in auth request or auth code objects and equals to the state value + return "", fmt.Errorf( + "invalid kubernetes resource name: must match the pattern %s and be no longer than %d characters", + kubeResourceNameRegex.String(), + kubeResourceMaxLen) + } + var p string if namespace != "" { p = path.Join(basePath, apiVersion, "namespaces", namespace, resource, name) @@ -105,13 +130,13 @@ func (cli *client) urlForWithParams( } if strings.HasSuffix(cli.baseURL, "/") { - return cli.baseURL + p + paramsSuffix + return cli.baseURL + p + paramsSuffix, nil } - return cli.baseURL + "/" + p + paramsSuffix + return cli.baseURL + "/" + p + paramsSuffix, nil } -func (cli *client) urlFor(apiVersion, namespace, resource, name string) string { +func (cli *client) urlFor(apiVersion, namespace, resource, name string) (string, error) { return cli.urlForWithParams(apiVersion, namespace, resource, name, url.Values{}) } @@ -191,13 +216,20 @@ func (cli *client) getURL(url string, v interface{}) error { } func (cli *client) getResource(apiVersion, namespace, resource, name string, v interface{}) error { - return cli.getURL(cli.urlFor(apiVersion, namespace, resource, name), v) + u, err := cli.urlFor(apiVersion, namespace, resource, name) + if err != nil { + return err + } + return cli.getURL(u, v) } -func (cli *client) listN(resource string, v interface{}, n int) error { +func (cli *client) listN(resource string, v interface{}, n int) error { //nolint:unparam // In practice, n is the gcResultLimit constant. params := url.Values{} params.Add("limit", fmt.Sprintf("%d", n)) - u := cli.urlForWithParams(cli.apiVersion, cli.namespace, resource, "", params) + u, err := cli.urlForWithParams(cli.apiVersion, cli.namespace, resource, "", params) + if err != nil { + return err + } return cli.getURL(u, v) } @@ -215,7 +247,10 @@ func (cli *client) postResource(apiVersion, namespace, resource string, v interf return fmt.Errorf("marshal object: %v", err) } - url := cli.urlFor(apiVersion, namespace, resource, "") + url, err := cli.urlFor(apiVersion, namespace, resource, "") + if err != nil { + return err + } resp, err := cli.client.Post(url, "application/json", bytes.NewReader(body)) if err != nil { return err @@ -244,7 +279,7 @@ func (cli *client) detectKubernetesVersion() error { clusterVersion, err := semver.NewVersion(version.GitVersion) if err != nil { - cli.logger.Warnf("cannot detect Kubernetes version (%s): %v", clusterVersion, err) + cli.logger.Warn("cannot detect Kubernetes version", "version", clusterVersion, "err", err) return nil } @@ -256,7 +291,10 @@ func (cli *client) detectKubernetesVersion() error { } func (cli *client) delete(resource, name string) error { - url := cli.urlFor(cli.apiVersion, cli.namespace, resource, name) + url, err := cli.urlFor(cli.apiVersion, cli.namespace, resource, name) + if err != nil { + return err + } req, err := http.NewRequest("DELETE", url, nil) if err != nil { return fmt.Errorf("create delete request: %v", err) @@ -295,7 +333,11 @@ func (cli *client) put(resource, name string, v interface{}) error { return fmt.Errorf("marshal object: %v", err) } - url := cli.urlFor(cli.apiVersion, cli.namespace, resource, name) + url, err := cli.urlFor(cli.apiVersion, cli.namespace, resource, name) + if err != nil { + return err + } + req, err := http.NewRequest("PUT", url, bytes.NewReader(body)) if err != nil { return fmt.Errorf("create patch request: %v", err) @@ -327,7 +369,7 @@ func defaultTLSConfig() *tls.Config { } } -func newClient(cluster k8sapi.Cluster, user k8sapi.AuthInfo, namespace string, logger log.Logger, inCluster bool) (*client, error) { +func newClient(cluster k8sapi.Cluster, user k8sapi.AuthInfo, namespace string, logger *slog.Logger, inCluster bool) (*client, error) { tlsConfig := defaultTLSConfig() data := func(b string, file string) ([]byte, error) { if b != "" { @@ -387,7 +429,7 @@ func newClient(cluster k8sapi.Cluster, user k8sapi.AuthInfo, namespace string, l apiVersion := "dex.coreos.com/v1" - logger.Infof("kubernetes client apiVersion = %s", apiVersion) + logger.Info("kubernetes client", "api_version", apiVersion) return &client{ client: &http.Client{ Transport: t, @@ -477,33 +519,27 @@ func getInClusterConfigNamespace(token, namespaceENV, namespacePath string) (str return "", fmt.Errorf("%v: trying to get namespace from file: %v", err, fileErr) } -func inClusterConfig() (k8sapi.Cluster, k8sapi.AuthInfo, string, error) { - const ( - serviceAccountPath = "/var/run/secrets/kubernetes.io/serviceaccount/" - serviceAccountTokenPath = serviceAccountPath + "token" - serviceAccountCAPath = serviceAccountPath + "ca.crt" - serviceAccountNamespacePath = serviceAccountPath + "namespace" - - kubernetesServiceHostENV = "KUBERNETES_SERVICE_HOST" - kubernetesServicePortENV = "KUBERNETES_SERVICE_PORT" - kubernetesPodNamespaceENV = "KUBERNETES_POD_NAMESPACE" - ) - - host, port := os.Getenv(kubernetesServiceHostENV), os.Getenv(kubernetesServicePortENV) +func getInClusterConnectOptions(host, port string) (k8sapi.Cluster, error) { if len(host) == 0 || len(port) == 0 { - return k8sapi.Cluster{}, k8sapi.AuthInfo{}, "", fmt.Errorf( + return k8sapi.Cluster{}, fmt.Errorf( "unable to load in-cluster configuration, %s and %s must be defined", kubernetesServiceHostENV, kubernetesServicePortENV, ) } - // we need to wrap IPv6 addresses in square brackets - // IPv4 also works with square brackets - host = "[" + host + "]" + cluster := k8sapi.Cluster{ - Server: "https://" + host + ":" + port, + Server: "https://" + net.JoinHostPort(host, port), CertificateAuthority: serviceAccountCAPath, } + return cluster, nil +} + +func inClusterConfig() (k8sapi.Cluster, k8sapi.AuthInfo, string, error) { + cluster, err := getInClusterConnectOptions(os.Getenv(kubernetesServiceHostENV), os.Getenv(kubernetesServicePortENV)) + if err != nil { + return cluster, k8sapi.AuthInfo{}, "", err + } token, err := os.ReadFile(serviceAccountTokenPath) if err != nil { diff --git a/storage/kubernetes/client_test.go b/storage/kubernetes/client_test.go index cfd04857b6..e57992f730 100644 --- a/storage/kubernetes/client_test.go +++ b/storage/kubernetes/client_test.go @@ -3,6 +3,7 @@ package kubernetes import ( "hash" "hash/fnv" + "log/slog" "net/http" "os" "path/filepath" @@ -10,7 +11,7 @@ import ( "testing" "time" - "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/dexidp/dex/storage/kubernetes/k8sapi" @@ -52,11 +53,7 @@ func TestOfflineTokenName(t *testing.T) { } func TestInClusterTransport(t *testing.T) { - logger := &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, - } + logger := slog.New(slog.DiscardHandler) user := k8sapi.AuthInfo{Token: "abc"} cli, err := newClient( @@ -220,6 +217,63 @@ func TestGetClusterConfigNamespace(t *testing.T) { } } +func TestGetInClusterConnectOptions(t *testing.T) { + type testCase struct { + name string + host string + port string + expectedURL string + expectError bool + } + + testCases := []testCase{ + { + name: "valid IPv4", + host: "10.1.1.1", + port: "443", + expectedURL: "https://10.1.1.1:443", + }, + { + name: "valid IPv6", + host: "fd00::1", + port: "8443", + expectedURL: "https://[fd00::1]:8443", + }, + { + name: "valid DNS name", + host: "kubernetes.default.svc", + port: "443", + expectedURL: "https://kubernetes.default.svc:443", + }, + { + name: "empty host", + host: "", + port: "443", + expectError: true, + }, + { + name: "empty port", + host: "127.0.0.1", + port: "", + expectError: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + cluster, err := getInClusterConnectOptions(tc.host, tc.port) + + if tc.expectError { + assert.Error(t, err) + return + } + require.NoError(t, err) + assert.Equal(t, tc.expectedURL, cluster.Server) + assert.Equal(t, "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt", cluster.CertificateAuthority) + }) + } +} + const serviceAccountToken = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZXgtdGVzdC1uYW1lc3BhY2UiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlY3JldC5uYW1lIjoiZG90aGVyb2JvdC1zZWNyZXQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZG90aGVyb2JvdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjQyYjJhOTRmLTk4MjAtMTFlNi1iZDc0LTJlZmQzOGYxMjYxYyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZXgtdGVzdC1uYW1lc3BhY2U6ZG90aGVyb2JvdCJ9.KViBpPwCiBwxDvAjYUUXoVvLVwqV011aLlYQpNtX12Bh8M-QAFch-3RWlo_SR00bcdFg_nZo9JKACYlF_jHMEsf__PaYms9r7vEaSg0jPfkqnL2WXZktzQRyLBr0n-bxeUrbwIWsKOAC0DfFB5nM8XoXljRmq8yAx8BAdmQp7MIFb4EOV9nYthhua6pjzYyaFSiDiYTjw7HtXOvoL8oepodJ3-37pUKS8vdBvnvUoqC4M1YAhkO5L36JF6KV_RfmG8GPEdNQfXotHcsR-3jKi1n8S5l7Xd-rhrGOhSGQizH3dORzo9GvBAhYeqbq1O-NLzm2EQUiMQayIUx7o4g3Kw" // The following program was used to generate the example token. Since we don't want to diff --git a/storage/kubernetes/lock.go b/storage/kubernetes/lock.go new file mode 100644 index 0000000000..c67380dcc0 --- /dev/null +++ b/storage/kubernetes/lock.go @@ -0,0 +1,124 @@ +package kubernetes + +import ( + "fmt" + "time" +) + +const ( + lockAnnotation = "dexidp.com/resource-lock" + lockTimeFormat = time.RFC3339 +) + +var ( + lockTimeout = 10 * time.Second + lockCheckPeriod = 100 * time.Millisecond +) + +// refreshTokenLock is an implementation of annotation-based optimistic locking. +// +// Refresh token contains data to refresh identity in external authentication system. +// There is a requirement that refresh should be called only once because of several reasons: +// - Some of OIDC providers could use the refresh token rotation feature which requires calling refresh only once. +// - Providers can limit the rate of requests to the token endpoint, which will lead to the error +// in case of many concurrent requests. +type refreshTokenLock struct { + cli *client + waitingState bool +} + +func newRefreshTokenLock(cli *client) *refreshTokenLock { + return &refreshTokenLock{cli: cli} +} + +func (l *refreshTokenLock) Lock(id string) error { + for i := 0; i <= 60; i++ { + ok, err := l.setLockAnnotation(id) + if err != nil { + return err + } + if !ok { + return nil + } + time.Sleep(lockCheckPeriod) + } + return fmt.Errorf("timeout waiting for refresh token %s lock", id) +} + +func (l *refreshTokenLock) Unlock(id string) { + if l.waitingState { + // Do not need to unlock for waiting goroutines, because the have not set it. + return + } + + r, err := l.cli.getRefreshToken(id) + if err != nil { + l.cli.logger.Debug("failed to get resource to release lock for refresh token", "token_id", id, "err", err) + return + } + + r.Annotations = nil + err = l.cli.put(resourceRefreshToken, r.ObjectMeta.Name, r) + if err != nil { + l.cli.logger.Debug("failed to release lock for refresh token", "token_id", id, "err", err) + } +} + +func (l *refreshTokenLock) setLockAnnotation(id string) (bool, error) { + r, err := l.cli.getRefreshToken(id) + if err != nil { + return false, err + } + + currentTime := time.Now() + lockData := map[string]string{ + lockAnnotation: currentTime.Add(lockTimeout).Format(lockTimeFormat), + } + + val, ok := r.Annotations[lockAnnotation] + if !ok { + if l.waitingState { + return false, nil + } + + r.Annotations = lockData + err := l.cli.put(resourceRefreshToken, r.ObjectMeta.Name, r) + if err == nil { + return false, nil + } + + if isKubernetesAPIConflictError(err) { + l.waitingState = true + return true, nil + } + return false, err + } + + until, err := time.Parse(lockTimeFormat, val) + if err != nil { + return false, fmt.Errorf("lock annotation value is malformed: %v", err) + } + + if !currentTime.After(until) { + // waiting for the lock to be released + l.waitingState = true + return true, nil + } + + // Lock time is out, lets break the lock and take the advantage + r.Annotations = lockData + + err = l.cli.put(resourceRefreshToken, r.ObjectMeta.Name, r) + if err == nil { + // break lock annotation + return false, nil + } + + l.cli.logger.Debug("break lock annotation", "error", err) + if isKubernetesAPIConflictError(err) { + l.waitingState = true + // after breaking error waiting for the lock to be released + return true, nil + } + return false, err +} diff --git a/storage/kubernetes/storage.go b/storage/kubernetes/storage.go index 033d3e2356..eae5b7a6de 100644 --- a/storage/kubernetes/storage.go +++ b/storage/kubernetes/storage.go @@ -4,12 +4,12 @@ import ( "context" "errors" "fmt" + "log/slog" "math/rand" "net/http" "strings" "time" - "github.com/dexidp/dex/pkg/log" "github.com/dexidp/dex/storage" "github.com/dexidp/dex/storage/kubernetes/k8sapi" ) @@ -40,6 +40,8 @@ const ( resourceDeviceToken = "devicetokens" ) +var _ storage.Storage = (*client)(nil) + const ( gcResultLimit = 500 ) @@ -51,7 +53,7 @@ type Config struct { } // Open returns a storage using Kubernetes third party resource. -func (c *Config) Open(logger log.Logger) (storage.Storage, error) { +func (c *Config) Open(logger *slog.Logger) (storage.Storage, error) { cli, err := c.open(logger, false) if err != nil { return nil, err @@ -64,7 +66,7 @@ func (c *Config) Open(logger log.Logger) (storage.Storage, error) { // // waitForResources controls if errors creating the resources cause this method to return // immediately (used during testing), or if the client will asynchronously retry. -func (c *Config) open(logger log.Logger, waitForResources bool) (*client, error) { +func (c *Config) open(logger *slog.Logger, waitForResources bool) (*client, error) { if c.InCluster && (c.KubeConfigFile != "") { return nil, errors.New("cannot specify both 'inCluster' and 'kubeConfigFile'") } @@ -153,12 +155,12 @@ func (cli *client) registerCustomResources() (ok bool) { r := definitions[i] var i interface{} - cli.logger.Infof("checking if custom resource %s has already been created...", r.ObjectMeta.Name) - if err := cli.list(r.Spec.Names.Plural, &i); err == nil { - cli.logger.Infof("The custom resource %s already available, skipping create", r.ObjectMeta.Name) + cli.logger.Info("checking if custom resource has already been created...", "object", r.ObjectMeta.Name) + if err := cli.listN(r.Spec.Names.Plural, &i, 1); err == nil { + cli.logger.Info("the custom resource already available, skipping create", "object", r.ObjectMeta.Name) continue } else { - cli.logger.Infof("failed to list custom resource %s, attempting to create: %v", r.ObjectMeta.Name, err) + cli.logger.Info("failed to list custom resource, attempting to create", "object", r.ObjectMeta.Name, "err", err) } err = cli.postResource(cli.crdAPIVersion, "", "customresourcedefinitions", r) @@ -167,17 +169,17 @@ func (cli *client) registerCustomResources() (ok bool) { if err != nil { switch err { case storage.ErrAlreadyExists: - cli.logger.Infof("custom resource already created %s", resourceName) + cli.logger.Info("custom resource already created", "object", resourceName) case storage.ErrNotFound: - cli.logger.Errorf("custom resources not found, please enable the respective API group") + cli.logger.Error("custom resources not found, please enable the respective API group") ok = false default: - cli.logger.Errorf("creating custom resource %s: %v", resourceName, err) + cli.logger.Error("creating custom resource", "object", resourceName, "err", err) ok = false } continue } - cli.logger.Errorf("create custom resource %s", resourceName) + cli.logger.Error("create custom resource", "object", resourceName) } return ok } @@ -195,7 +197,7 @@ func (cli *client) waitForCRDs(ctx context.Context) error { break } - cli.logger.Errorf("checking CRD: %v", err) + cli.logger.ErrorContext(ctx, "checking CRD", "err", err) select { case <-ctx.Done(): @@ -232,35 +234,35 @@ func (cli *client) Close() error { return nil } -func (cli *client) CreateAuthRequest(a storage.AuthRequest) error { +func (cli *client) CreateAuthRequest(ctx context.Context, a storage.AuthRequest) error { return cli.post(resourceAuthRequest, cli.fromStorageAuthRequest(a)) } -func (cli *client) CreateClient(c storage.Client) error { +func (cli *client) CreateClient(ctx context.Context, c storage.Client) error { return cli.post(resourceClient, cli.fromStorageClient(c)) } -func (cli *client) CreateAuthCode(c storage.AuthCode) error { +func (cli *client) CreateAuthCode(ctx context.Context, c storage.AuthCode) error { return cli.post(resourceAuthCode, cli.fromStorageAuthCode(c)) } -func (cli *client) CreatePassword(p storage.Password) error { +func (cli *client) CreatePassword(ctx context.Context, p storage.Password) error { return cli.post(resourcePassword, cli.fromStoragePassword(p)) } -func (cli *client) CreateRefresh(r storage.RefreshToken) error { +func (cli *client) CreateRefresh(ctx context.Context, r storage.RefreshToken) error { return cli.post(resourceRefreshToken, cli.fromStorageRefreshToken(r)) } -func (cli *client) CreateOfflineSessions(o storage.OfflineSessions) error { +func (cli *client) CreateOfflineSessions(ctx context.Context, o storage.OfflineSessions) error { return cli.post(resourceOfflineSessions, cli.fromStorageOfflineSessions(o)) } -func (cli *client) CreateConnector(c storage.Connector) error { +func (cli *client) CreateConnector(ctx context.Context, c storage.Connector) error { return cli.post(resourceConnector, cli.fromStorageConnector(c)) } -func (cli *client) GetAuthRequest(id string) (storage.AuthRequest, error) { +func (cli *client) GetAuthRequest(ctx context.Context, id string) (storage.AuthRequest, error) { var req AuthRequest if err := cli.get(resourceAuthRequest, id, &req); err != nil { return storage.AuthRequest{}, err @@ -268,7 +270,7 @@ func (cli *client) GetAuthRequest(id string) (storage.AuthRequest, error) { return toStorageAuthRequest(req), nil } -func (cli *client) GetAuthCode(id string) (storage.AuthCode, error) { +func (cli *client) GetAuthCode(ctx context.Context, id string) (storage.AuthCode, error) { var code AuthCode if err := cli.get(resourceAuthCode, id, &code); err != nil { return storage.AuthCode{}, err @@ -276,7 +278,7 @@ func (cli *client) GetAuthCode(id string) (storage.AuthCode, error) { return toStorageAuthCode(code), nil } -func (cli *client) GetClient(id string) (storage.Client, error) { +func (cli *client) GetClient(ctx context.Context, id string) (storage.Client, error) { c, err := cli.getClient(id) if err != nil { return storage.Client{}, err @@ -296,7 +298,7 @@ func (cli *client) getClient(id string) (Client, error) { return c, nil } -func (cli *client) GetPassword(email string) (storage.Password, error) { +func (cli *client) GetPassword(ctx context.Context, email string) (storage.Password, error) { p, err := cli.getPassword(email) if err != nil { return storage.Password{}, err @@ -318,7 +320,7 @@ func (cli *client) getPassword(email string) (Password, error) { return p, nil } -func (cli *client) GetKeys() (storage.Keys, error) { +func (cli *client) GetKeys(ctx context.Context) (storage.Keys, error) { var keys Keys if err := cli.get(resourceKeys, keysName, &keys); err != nil { return storage.Keys{}, err @@ -326,7 +328,7 @@ func (cli *client) GetKeys() (storage.Keys, error) { return toStorageKeys(keys), nil } -func (cli *client) GetRefresh(id string) (storage.RefreshToken, error) { +func (cli *client) GetRefresh(ctx context.Context, id string) (storage.RefreshToken, error) { r, err := cli.getRefreshToken(id) if err != nil { return storage.RefreshToken{}, err @@ -339,7 +341,7 @@ func (cli *client) getRefreshToken(id string) (r RefreshToken, err error) { return } -func (cli *client) GetOfflineSessions(userID string, connID string) (storage.OfflineSessions, error) { +func (cli *client) GetOfflineSessions(ctx context.Context, userID string, connID string) (storage.OfflineSessions, error) { o, err := cli.getOfflineSessions(userID, connID) if err != nil { return storage.OfflineSessions{}, err @@ -358,7 +360,7 @@ func (cli *client) getOfflineSessions(userID string, connID string) (o OfflineSe return o, nil } -func (cli *client) GetConnector(id string) (storage.Connector, error) { +func (cli *client) GetConnector(ctx context.Context, id string) (storage.Connector, error) { var c Connector if err := cli.get(resourceConnector, id, &c); err != nil { return storage.Connector{}, err @@ -366,15 +368,15 @@ func (cli *client) GetConnector(id string) (storage.Connector, error) { return toStorageConnector(c), nil } -func (cli *client) ListClients() ([]storage.Client, error) { +func (cli *client) ListClients(ctx context.Context) ([]storage.Client, error) { return nil, errors.New("not implemented") } -func (cli *client) ListRefreshTokens() ([]storage.RefreshToken, error) { +func (cli *client) ListRefreshTokens(ctx context.Context) ([]storage.RefreshToken, error) { return nil, errors.New("not implemented") } -func (cli *client) ListPasswords() (passwords []storage.Password, err error) { +func (cli *client) ListPasswords(ctx context.Context) (passwords []storage.Password, err error) { var passwordList PasswordList if err = cli.list(resourcePassword, &passwordList); err != nil { return passwords, fmt.Errorf("failed to list passwords: %v", err) @@ -393,7 +395,7 @@ func (cli *client) ListPasswords() (passwords []storage.Password, err error) { return } -func (cli *client) ListConnectors() (connectors []storage.Connector, err error) { +func (cli *client) ListConnectors(ctx context.Context) (connectors []storage.Connector, err error) { var connectorList ConnectorList if err = cli.list(resourceConnector, &connectorList); err != nil { return connectors, fmt.Errorf("failed to list connectors: %v", err) @@ -407,15 +409,15 @@ func (cli *client) ListConnectors() (connectors []storage.Connector, err error) return } -func (cli *client) DeleteAuthRequest(id string) error { +func (cli *client) DeleteAuthRequest(ctx context.Context, id string) error { return cli.delete(resourceAuthRequest, id) } -func (cli *client) DeleteAuthCode(code string) error { +func (cli *client) DeleteAuthCode(ctx context.Context, code string) error { return cli.delete(resourceAuthCode, code) } -func (cli *client) DeleteClient(id string) error { +func (cli *client) DeleteClient(ctx context.Context, id string) error { // Check for hash collision. c, err := cli.getClient(id) if err != nil { @@ -424,11 +426,11 @@ func (cli *client) DeleteClient(id string) error { return cli.delete(resourceClient, c.ObjectMeta.Name) } -func (cli *client) DeleteRefresh(id string) error { +func (cli *client) DeleteRefresh(ctx context.Context, id string) error { return cli.delete(resourceRefreshToken, id) } -func (cli *client) DeletePassword(email string) error { +func (cli *client) DeletePassword(ctx context.Context, email string) error { // Check for hash collision. p, err := cli.getPassword(email) if err != nil { @@ -437,7 +439,7 @@ func (cli *client) DeletePassword(email string) error { return cli.delete(resourcePassword, p.ObjectMeta.Name) } -func (cli *client) DeleteOfflineSessions(userID string, connID string) error { +func (cli *client) DeleteOfflineSessions(ctx context.Context, userID string, connID string) error { // Check for hash collision. o, err := cli.getOfflineSessions(userID, connID) if err != nil { @@ -446,16 +448,24 @@ func (cli *client) DeleteOfflineSessions(userID string, connID string) error { return cli.delete(resourceOfflineSessions, o.ObjectMeta.Name) } -func (cli *client) DeleteConnector(id string) error { +func (cli *client) DeleteConnector(ctx context.Context, id string) error { return cli.delete(resourceConnector, id) } -func (cli *client) UpdateRefreshToken(id string, updater func(old storage.RefreshToken) (storage.RefreshToken, error)) error { - return retryOnConflict(context.TODO(), func() error { +func (cli *client) UpdateRefreshToken(ctx context.Context, id string, updater func(old storage.RefreshToken) (storage.RefreshToken, error)) error { + lock := newRefreshTokenLock(cli) + + if err := lock.Lock(id); err != nil { + return err + } + defer lock.Unlock(id) + + return retryOnConflict(ctx, func() error { r, err := cli.getRefreshToken(id) if err != nil { return err } + updated, err := updater(toStorageRefreshToken(r)) if err != nil { return err @@ -464,11 +474,12 @@ func (cli *client) UpdateRefreshToken(id string, updater func(old storage.Refres newToken := cli.fromStorageRefreshToken(updated) newToken.ObjectMeta = r.ObjectMeta + return cli.put(resourceRefreshToken, r.ObjectMeta.Name, newToken) }) } -func (cli *client) UpdateClient(id string, updater func(old storage.Client) (storage.Client, error)) error { +func (cli *client) UpdateClient(ctx context.Context, id string, updater func(old storage.Client) (storage.Client, error)) error { c, err := cli.getClient(id) if err != nil { return err @@ -485,7 +496,7 @@ func (cli *client) UpdateClient(id string, updater func(old storage.Client) (sto return cli.put(resourceClient, c.ObjectMeta.Name, newClient) } -func (cli *client) UpdatePassword(email string, updater func(old storage.Password) (storage.Password, error)) error { +func (cli *client) UpdatePassword(ctx context.Context, email string, updater func(old storage.Password) (storage.Password, error)) error { p, err := cli.getPassword(email) if err != nil { return err @@ -502,8 +513,8 @@ func (cli *client) UpdatePassword(email string, updater func(old storage.Passwor return cli.put(resourcePassword, p.ObjectMeta.Name, newPassword) } -func (cli *client) UpdateOfflineSessions(userID string, connID string, updater func(old storage.OfflineSessions) (storage.OfflineSessions, error)) error { - return retryOnConflict(context.TODO(), func() error { +func (cli *client) UpdateOfflineSessions(ctx context.Context, userID string, connID string, updater func(old storage.OfflineSessions) (storage.OfflineSessions, error)) error { + return retryOnConflict(ctx, func() error { o, err := cli.getOfflineSessions(userID, connID) if err != nil { return err @@ -520,7 +531,7 @@ func (cli *client) UpdateOfflineSessions(userID string, connID string, updater f }) } -func (cli *client) UpdateKeys(updater func(old storage.Keys) (storage.Keys, error)) error { +func (cli *client) UpdateKeys(ctx context.Context, updater func(old storage.Keys) (storage.Keys, error)) error { firstUpdate := false var keys Keys if err := cli.get(resourceKeys, keysName, &keys); err != nil { @@ -545,7 +556,7 @@ func (cli *client) UpdateKeys(updater func(old storage.Keys) (storage.Keys, erro err = cli.post(resourceKeys, newKeys) if err != nil && errors.Is(err, storage.ErrAlreadyExists) { // We need to tolerate conflicts here in case of HA mode. - cli.logger.Debugf("Keys creation failed: %v. It is possible that keys have already been created by another dex instance.", err) + cli.logger.Debug("Keys creation failed. It is possible that keys have already been created by another dex instance.", "err", err) return errors.New("keys already created by another server instance") } @@ -558,14 +569,14 @@ func (cli *client) UpdateKeys(updater func(old storage.Keys) (storage.Keys, erro if isKubernetesAPIConflictError(err) { // We need to tolerate conflicts here in case of HA mode. // Dex instances run keys rotation at the same time because they use SigningKey.nextRotation CR field as a trigger. - cli.logger.Debugf("Keys rotation failed: %v. It is possible that keys have already been rotated by another dex instance.", err) + cli.logger.Debug("Keys rotation failed. It is possible that keys have already been rotated by another dex instance.", "err", err) return errors.New("keys already rotated by another server instance") } return err } -func (cli *client) UpdateAuthRequest(id string, updater func(a storage.AuthRequest) (storage.AuthRequest, error)) error { +func (cli *client) UpdateAuthRequest(ctx context.Context, id string, updater func(a storage.AuthRequest) (storage.AuthRequest, error)) error { var req AuthRequest err := cli.get(resourceAuthRequest, id, &req) if err != nil { @@ -582,8 +593,8 @@ func (cli *client) UpdateAuthRequest(id string, updater func(a storage.AuthReque return cli.put(resourceAuthRequest, id, newReq) } -func (cli *client) UpdateConnector(id string, updater func(a storage.Connector) (storage.Connector, error)) error { - return retryOnConflict(context.TODO(), func() error { +func (cli *client) UpdateConnector(ctx context.Context, id string, updater func(a storage.Connector) (storage.Connector, error)) error { + return retryOnConflict(ctx, func() error { var c Connector err := cli.get(resourceConnector, id, &c) if err != nil { @@ -601,7 +612,7 @@ func (cli *client) UpdateConnector(id string, updater func(a storage.Connector) }) } -func (cli *client) GarbageCollect(now time.Time) (result storage.GCResult, err error) { +func (cli *client) GarbageCollect(ctx context.Context, now time.Time) (result storage.GCResult, err error) { var authRequests AuthRequestList if err := cli.listN(resourceAuthRequest, &authRequests, gcResultLimit); err != nil { return result, fmt.Errorf("failed to list auth requests: %v", err) @@ -611,7 +622,7 @@ func (cli *client) GarbageCollect(now time.Time) (result storage.GCResult, err e for _, authRequest := range authRequests.AuthRequests { if now.After(authRequest.Expiry) { if err := cli.delete(resourceAuthRequest, authRequest.ObjectMeta.Name); err != nil { - cli.logger.Errorf("failed to delete auth request: %v", err) + cli.logger.Error("failed to delete auth request", "err", err) delErr = fmt.Errorf("failed to delete auth request: %v", err) } result.AuthRequests++ @@ -629,7 +640,7 @@ func (cli *client) GarbageCollect(now time.Time) (result storage.GCResult, err e for _, authCode := range authCodes.AuthCodes { if now.After(authCode.Expiry) { if err := cli.delete(resourceAuthCode, authCode.ObjectMeta.Name); err != nil { - cli.logger.Errorf("failed to delete auth code %v", err) + cli.logger.Error("failed to delete auth code", "err", err) delErr = fmt.Errorf("failed to delete auth code: %v", err) } result.AuthCodes++ @@ -644,7 +655,7 @@ func (cli *client) GarbageCollect(now time.Time) (result storage.GCResult, err e for _, deviceRequest := range deviceRequests.DeviceRequests { if now.After(deviceRequest.Expiry) { if err := cli.delete(resourceDeviceRequest, deviceRequest.ObjectMeta.Name); err != nil { - cli.logger.Errorf("failed to delete device request: %v", err) + cli.logger.Error("failed to delete device request", "err", err) delErr = fmt.Errorf("failed to delete device request: %v", err) } result.DeviceRequests++ @@ -659,7 +670,7 @@ func (cli *client) GarbageCollect(now time.Time) (result storage.GCResult, err e for _, deviceToken := range deviceTokens.DeviceTokens { if now.After(deviceToken.Expiry) { if err := cli.delete(resourceDeviceToken, deviceToken.ObjectMeta.Name); err != nil { - cli.logger.Errorf("failed to delete device token: %v", err) + cli.logger.Error("failed to delete device token", "err", err) delErr = fmt.Errorf("failed to delete device token: %v", err) } result.DeviceTokens++ @@ -672,11 +683,11 @@ func (cli *client) GarbageCollect(now time.Time) (result storage.GCResult, err e return result, delErr } -func (cli *client) CreateDeviceRequest(d storage.DeviceRequest) error { +func (cli *client) CreateDeviceRequest(ctx context.Context, d storage.DeviceRequest) error { return cli.post(resourceDeviceRequest, cli.fromStorageDeviceRequest(d)) } -func (cli *client) GetDeviceRequest(userCode string) (storage.DeviceRequest, error) { +func (cli *client) GetDeviceRequest(ctx context.Context, userCode string) (storage.DeviceRequest, error) { var req DeviceRequest if err := cli.get(resourceDeviceRequest, strings.ToLower(userCode), &req); err != nil { return storage.DeviceRequest{}, err @@ -684,11 +695,11 @@ func (cli *client) GetDeviceRequest(userCode string) (storage.DeviceRequest, err return toStorageDeviceRequest(req), nil } -func (cli *client) CreateDeviceToken(t storage.DeviceToken) error { +func (cli *client) CreateDeviceToken(ctx context.Context, t storage.DeviceToken) error { return cli.post(resourceDeviceToken, cli.fromStorageDeviceToken(t)) } -func (cli *client) GetDeviceToken(deviceCode string) (storage.DeviceToken, error) { +func (cli *client) GetDeviceToken(ctx context.Context, deviceCode string) (storage.DeviceToken, error) { var token DeviceToken if err := cli.get(resourceDeviceToken, deviceCode, &token); err != nil { return storage.DeviceToken{}, err @@ -701,8 +712,8 @@ func (cli *client) getDeviceToken(deviceCode string) (t DeviceToken, err error) return } -func (cli *client) UpdateDeviceToken(deviceCode string, updater func(old storage.DeviceToken) (storage.DeviceToken, error)) error { - return retryOnConflict(context.TODO(), func() error { +func (cli *client) UpdateDeviceToken(ctx context.Context, deviceCode string, updater func(old storage.DeviceToken) (storage.DeviceToken, error)) error { + return retryOnConflict(ctx, func() error { r, err := cli.getDeviceToken(deviceCode) if err != nil { return err diff --git a/storage/kubernetes/storage_test.go b/storage/kubernetes/storage_test.go index 828ff472cf..98ef25fa6a 100644 --- a/storage/kubernetes/storage_test.go +++ b/storage/kubernetes/storage_test.go @@ -5,14 +5,15 @@ import ( "crypto/tls" "errors" "fmt" + "log/slog" "net/http" "net/http/httptest" "os" "path/filepath" "strings" "testing" + "time" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -35,29 +36,28 @@ type StorageTestSuite struct { client *client } -func (s *StorageTestSuite) expandDir(dir string) string { +func expandDir(dir string) (string, error) { dir = strings.Trim(dir, `"`) if strings.HasPrefix(dir, "~/") { homedir, err := os.UserHomeDir() - s.Require().NoError(err) + if err != nil { + return "", err + } dir = filepath.Join(homedir, strings.TrimPrefix(dir, "~/")) } - return dir + return dir, nil } func (s *StorageTestSuite) SetupTest() { - kubeconfigPath := s.expandDir(os.Getenv(kubeconfigPathVariableName)) + kubeconfigPath, err := expandDir(os.Getenv(kubeconfigPathVariableName)) + s.Require().NoError(err) config := Config{ KubeConfigFile: kubeconfigPath, } - logger := &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, - } + logger := slog.New(slog.NewTextHandler(s.T().Output(), &slog.HandlerOptions{Level: slog.LevelDebug})) kubeClient, err := config.open(logger, true) s.Require().NoError(err) @@ -66,7 +66,7 @@ func (s *StorageTestSuite) SetupTest() { } func (s *StorageTestSuite) TestStorage() { - newStorage := func() storage.Storage { + newStorage := func(t *testing.T) storage.Storage { for _, resource := range []string{ resourceAuthCode, resourceAuthRequest, @@ -125,7 +125,11 @@ func TestURLFor(t *testing.T) { for _, test := range tests { c := &client{baseURL: test.baseURL} - got := c.urlFor(test.apiVersion, test.namespace, test.resource, test.name) + got, err := c.urlFor(test.apiVersion, test.namespace, test.resource, test.name) + if err != nil { + t.Errorf("got error: %v", err) + } + if got != test.want { t.Errorf("(&client{baseURL:%q}).urlFor(%q, %q, %q, %q): expected %q got %q", test.baseURL, @@ -216,7 +220,7 @@ func TestUpdateKeys(t *testing.T) { for _, test := range tests { client := newStatusCodesResponseTestClient(test.getResponseCode, test.actionResponseCode) - err := client.UpdateKeys(test.updater) + err := client.UpdateKeys(context.TODO(), test.updater) if err != nil { if !test.wantErr { t.Fatalf("Test %q: %v", test.name, err) @@ -245,11 +249,7 @@ func newStatusCodesResponseTestClient(getResponseCode, actionResponseCode int) * return &client{ client: &http.Client{Transport: tr}, baseURL: s.URL, - logger: &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, - }, + logger: slog.New(slog.DiscardHandler), } } @@ -292,3 +292,92 @@ func TestRetryOnConflict(t *testing.T) { }) } } + +func TestRefreshTokenLock(t *testing.T) { + ctx := context.Background() + if os.Getenv(kubeconfigPathVariableName) == "" { + t.Skipf("variable %q not set, skipping kubernetes storage tests\n", kubeconfigPathVariableName) + } + + kubeconfigPath, err := expandDir(os.Getenv(kubeconfigPathVariableName)) + require.NoError(t, err) + + config := Config{ + KubeConfigFile: kubeconfigPath, + } + + logger := slog.New(slog.DiscardHandler) + + kubeClient, err := config.open(logger, true) + require.NoError(t, err) + + lockCheckPeriod = time.Nanosecond + + // Creating a storage with an existing refresh token and offline session for the user. + id := storage.NewID() + r := storage.RefreshToken{ + ID: id, + Token: "bar", + Nonce: "foo", + ClientID: "client_id", + ConnectorID: "client_secret", + Scopes: []string{"openid", "email", "profile"}, + CreatedAt: time.Now().UTC().Round(time.Millisecond), + LastUsed: time.Now().UTC().Round(time.Millisecond), + Claims: storage.Claims{ + UserID: "1", + Username: "jane", + Email: "jane.doe@example.com", + EmailVerified: true, + Groups: []string{"a", "b"}, + }, + ConnectorData: []byte(`{"some":"data"}`), + } + + err = kubeClient.CreateRefresh(ctx, r) + require.NoError(t, err) + + t.Run("Timeout lock error", func(t *testing.T) { + err = kubeClient.UpdateRefreshToken(ctx, r.ID, func(r storage.RefreshToken) (storage.RefreshToken, error) { + r.Token = "update-result-1" + err := kubeClient.UpdateRefreshToken(ctx, r.ID, func(r storage.RefreshToken) (storage.RefreshToken, error) { + r.Token = "timeout-err" + return r, nil + }) + require.Equal(t, fmt.Errorf("timeout waiting for refresh token %s lock", r.ID), err) + return r, nil + }) + require.NoError(t, err) + + token, err := kubeClient.GetRefresh(context.TODO(), r.ID) + require.NoError(t, err) + require.Equal(t, "update-result-1", token.Token) + }) + + t.Run("Break the lock", func(t *testing.T) { + var lockBroken bool + lockTimeout = -time.Hour + + err = kubeClient.UpdateRefreshToken(ctx, r.ID, func(r storage.RefreshToken) (storage.RefreshToken, error) { + r.Token = "update-result-2" + if lockBroken { + return r, nil + } + + err := kubeClient.UpdateRefreshToken(ctx, r.ID, func(r storage.RefreshToken) (storage.RefreshToken, error) { + r.Token = "should-break-the-lock-and-finish-updating" + return r, nil + }) + require.NoError(t, err) + + lockBroken = true + return r, nil + }) + require.NoError(t, err) + + token, err := kubeClient.GetRefresh(context.TODO(), r.ID) + require.NoError(t, err) + // Because concurrent update breaks the lock, the final result will be the value of the first update + require.Equal(t, "update-result-2", token.Token) + }) +} diff --git a/storage/kubernetes/transport.go b/storage/kubernetes/transport.go index 5d39c27fba..9c3cd2baac 100644 --- a/storage/kubernetes/transport.go +++ b/storage/kubernetes/transport.go @@ -62,15 +62,17 @@ func wrapRoundTripper(base http.RoundTripper, user k8sapi.AuthInfo, inCluster bo } // renewTokenPeriod is the interval after which dex will read the token from a well-known file. -// By Kubernetes documentation, this interval should be at least one minute long. -// Kubernetes client-go v0.15+ uses 10 seconds long interval. -// Dex uses the reasonable value between these two. +// +// By Kubernetes documentation, this interval should be at least one minute long. +// Kubernetes client-go v0.15+ uses 10 seconds long interval. +// Dex uses the reasonable value between these two. const renewTokenPeriod = 30 * time.Second // inClusterTransportHelper is capable of safely updating the user token. -// BoundServiceAccountTokenVolume feature is enabled in Kubernetes >=1.21 by default. -// With this feature, the service account token in the pod becomes periodically updated. -// Therefore, Dex needs to re-read the token from the disk after some time to be sure that it uses the valid token. +// +// BoundServiceAccountTokenVolume feature is enabled in Kubernetes >=1.21 by default. +// With this feature, the service account token in the pod becomes periodically updated. +// Therefore, Dex needs to re-read the token from the disk after some time to be sure that it uses the valid token. type inClusterTransportHelper struct { mu sync.RWMutex info k8sapi.AuthInfo diff --git a/storage/kubernetes/types.go b/storage/kubernetes/types.go index 5149e3eec6..c126ddc087 100644 --- a/storage/kubernetes/types.go +++ b/storage/kubernetes/types.go @@ -4,7 +4,7 @@ import ( "strings" "time" - jose "gopkg.in/square/go-jose.v2" + "github.com/go-jose/go-jose/v4" "github.com/dexidp/dex/storage" "github.com/dexidp/dex/storage/kubernetes/k8sapi" @@ -356,6 +356,8 @@ type AuthRequest struct { CodeChallenge string `json:"code_challenge,omitempty"` CodeChallengeMethod string `json:"code_challenge_method,omitempty"` + + HMACKey []byte `json:"hmac_key"` } // AuthRequestList is a list of AuthRequests. @@ -384,6 +386,7 @@ func toStorageAuthRequest(req AuthRequest) storage.AuthRequest { CodeChallenge: req.CodeChallenge, CodeChallengeMethod: req.CodeChallengeMethod, }, + HMACKey: req.HMACKey, } return a } @@ -412,6 +415,7 @@ func (cli *client) fromStorageAuthRequest(a storage.AuthRequest) AuthRequest { Claims: fromStorageClaims(a.Claims), CodeChallenge: a.PKCE.CodeChallenge, CodeChallengeMethod: a.PKCE.CodeChallengeMethod, + HMACKey: a.HMACKey, } return req } diff --git a/storage/memory/memory.go b/storage/memory/memory.go index a940665714..eff75e716d 100644 --- a/storage/memory/memory.go +++ b/storage/memory/memory.go @@ -2,16 +2,19 @@ package memory import ( + "context" + "log/slog" "strings" "sync" "time" - "github.com/dexidp/dex/pkg/log" "github.com/dexidp/dex/storage" ) +var _ storage.Storage = (*memStorage)(nil) + // New returns an in memory storage. -func New(logger log.Logger) storage.Storage { +func New(logger *slog.Logger) storage.Storage { return &memStorage{ clients: make(map[string]storage.Client), authCodes: make(map[string]storage.AuthCode), @@ -33,7 +36,7 @@ type Config struct { // The in memory implementation has no config. } // Open always returns a new in memory storage. -func (c *Config) Open(logger log.Logger) (storage.Storage, error) { +func (c *Config) Open(logger *slog.Logger) (storage.Storage, error) { return New(logger), nil } @@ -52,7 +55,7 @@ type memStorage struct { keys storage.Keys - logger log.Logger + logger *slog.Logger } type offlineSessionID struct { @@ -68,7 +71,7 @@ func (s *memStorage) tx(f func()) { func (s *memStorage) Close() error { return nil } -func (s *memStorage) GarbageCollect(now time.Time) (result storage.GCResult, err error) { +func (s *memStorage) GarbageCollect(ctx context.Context, now time.Time) (result storage.GCResult, err error) { s.tx(func() { for id, a := range s.authCodes { if now.After(a.Expiry) { @@ -98,7 +101,7 @@ func (s *memStorage) GarbageCollect(now time.Time) (result storage.GCResult, err return result, nil } -func (s *memStorage) CreateClient(c storage.Client) (err error) { +func (s *memStorage) CreateClient(ctx context.Context, c storage.Client) (err error) { s.tx(func() { if _, ok := s.clients[c.ID]; ok { err = storage.ErrAlreadyExists @@ -109,7 +112,7 @@ func (s *memStorage) CreateClient(c storage.Client) (err error) { return } -func (s *memStorage) CreateAuthCode(c storage.AuthCode) (err error) { +func (s *memStorage) CreateAuthCode(ctx context.Context, c storage.AuthCode) (err error) { s.tx(func() { if _, ok := s.authCodes[c.ID]; ok { err = storage.ErrAlreadyExists @@ -120,7 +123,7 @@ func (s *memStorage) CreateAuthCode(c storage.AuthCode) (err error) { return } -func (s *memStorage) CreateRefresh(r storage.RefreshToken) (err error) { +func (s *memStorage) CreateRefresh(ctx context.Context, r storage.RefreshToken) (err error) { s.tx(func() { if _, ok := s.refreshTokens[r.ID]; ok { err = storage.ErrAlreadyExists @@ -131,7 +134,7 @@ func (s *memStorage) CreateRefresh(r storage.RefreshToken) (err error) { return } -func (s *memStorage) CreateAuthRequest(a storage.AuthRequest) (err error) { +func (s *memStorage) CreateAuthRequest(ctx context.Context, a storage.AuthRequest) (err error) { s.tx(func() { if _, ok := s.authReqs[a.ID]; ok { err = storage.ErrAlreadyExists @@ -142,7 +145,7 @@ func (s *memStorage) CreateAuthRequest(a storage.AuthRequest) (err error) { return } -func (s *memStorage) CreatePassword(p storage.Password) (err error) { +func (s *memStorage) CreatePassword(ctx context.Context, p storage.Password) (err error) { lowerEmail := strings.ToLower(p.Email) s.tx(func() { if _, ok := s.passwords[lowerEmail]; ok { @@ -154,7 +157,7 @@ func (s *memStorage) CreatePassword(p storage.Password) (err error) { return } -func (s *memStorage) CreateOfflineSessions(o storage.OfflineSessions) (err error) { +func (s *memStorage) CreateOfflineSessions(ctx context.Context, o storage.OfflineSessions) (err error) { id := offlineSessionID{ userID: o.UserID, connID: o.ConnID, @@ -169,7 +172,7 @@ func (s *memStorage) CreateOfflineSessions(o storage.OfflineSessions) (err error return } -func (s *memStorage) CreateConnector(connector storage.Connector) (err error) { +func (s *memStorage) CreateConnector(ctx context.Context, connector storage.Connector) (err error) { s.tx(func() { if _, ok := s.connectors[connector.ID]; ok { err = storage.ErrAlreadyExists @@ -180,7 +183,7 @@ func (s *memStorage) CreateConnector(connector storage.Connector) (err error) { return } -func (s *memStorage) GetAuthCode(id string) (c storage.AuthCode, err error) { +func (s *memStorage) GetAuthCode(ctx context.Context, id string) (c storage.AuthCode, err error) { s.tx(func() { var ok bool if c, ok = s.authCodes[id]; !ok { @@ -191,7 +194,7 @@ func (s *memStorage) GetAuthCode(id string) (c storage.AuthCode, err error) { return } -func (s *memStorage) GetPassword(email string) (p storage.Password, err error) { +func (s *memStorage) GetPassword(ctx context.Context, email string) (p storage.Password, err error) { email = strings.ToLower(email) s.tx(func() { var ok bool @@ -202,7 +205,7 @@ func (s *memStorage) GetPassword(email string) (p storage.Password, err error) { return } -func (s *memStorage) GetClient(id string) (client storage.Client, err error) { +func (s *memStorage) GetClient(ctx context.Context, id string) (client storage.Client, err error) { s.tx(func() { var ok bool if client, ok = s.clients[id]; !ok { @@ -212,12 +215,12 @@ func (s *memStorage) GetClient(id string) (client storage.Client, err error) { return } -func (s *memStorage) GetKeys() (keys storage.Keys, err error) { +func (s *memStorage) GetKeys(ctx context.Context) (keys storage.Keys, err error) { s.tx(func() { keys = s.keys }) return } -func (s *memStorage) GetRefresh(id string) (tok storage.RefreshToken, err error) { +func (s *memStorage) GetRefresh(ctx context.Context, id string) (tok storage.RefreshToken, err error) { s.tx(func() { var ok bool if tok, ok = s.refreshTokens[id]; !ok { @@ -228,7 +231,7 @@ func (s *memStorage) GetRefresh(id string) (tok storage.RefreshToken, err error) return } -func (s *memStorage) GetAuthRequest(id string) (req storage.AuthRequest, err error) { +func (s *memStorage) GetAuthRequest(ctx context.Context, id string) (req storage.AuthRequest, err error) { s.tx(func() { var ok bool if req, ok = s.authReqs[id]; !ok { @@ -239,7 +242,7 @@ func (s *memStorage) GetAuthRequest(id string) (req storage.AuthRequest, err err return } -func (s *memStorage) GetOfflineSessions(userID string, connID string) (o storage.OfflineSessions, err error) { +func (s *memStorage) GetOfflineSessions(ctx context.Context, userID string, connID string) (o storage.OfflineSessions, err error) { id := offlineSessionID{ userID: userID, connID: connID, @@ -254,7 +257,7 @@ func (s *memStorage) GetOfflineSessions(userID string, connID string) (o storage return } -func (s *memStorage) GetConnector(id string) (connector storage.Connector, err error) { +func (s *memStorage) GetConnector(ctx context.Context, id string) (connector storage.Connector, err error) { s.tx(func() { var ok bool if connector, ok = s.connectors[id]; !ok { @@ -264,7 +267,7 @@ func (s *memStorage) GetConnector(id string) (connector storage.Connector, err e return } -func (s *memStorage) ListClients() (clients []storage.Client, err error) { +func (s *memStorage) ListClients(ctx context.Context) (clients []storage.Client, err error) { s.tx(func() { for _, client := range s.clients { clients = append(clients, client) @@ -273,7 +276,7 @@ func (s *memStorage) ListClients() (clients []storage.Client, err error) { return } -func (s *memStorage) ListRefreshTokens() (tokens []storage.RefreshToken, err error) { +func (s *memStorage) ListRefreshTokens(ctx context.Context) (tokens []storage.RefreshToken, err error) { s.tx(func() { for _, refresh := range s.refreshTokens { tokens = append(tokens, refresh) @@ -282,7 +285,7 @@ func (s *memStorage) ListRefreshTokens() (tokens []storage.RefreshToken, err err return } -func (s *memStorage) ListPasswords() (passwords []storage.Password, err error) { +func (s *memStorage) ListPasswords(ctx context.Context) (passwords []storage.Password, err error) { s.tx(func() { for _, password := range s.passwords { passwords = append(passwords, password) @@ -291,7 +294,7 @@ func (s *memStorage) ListPasswords() (passwords []storage.Password, err error) { return } -func (s *memStorage) ListConnectors() (conns []storage.Connector, err error) { +func (s *memStorage) ListConnectors(ctx context.Context) (conns []storage.Connector, err error) { s.tx(func() { for _, c := range s.connectors { conns = append(conns, c) @@ -300,7 +303,7 @@ func (s *memStorage) ListConnectors() (conns []storage.Connector, err error) { return } -func (s *memStorage) DeletePassword(email string) (err error) { +func (s *memStorage) DeletePassword(ctx context.Context, email string) (err error) { email = strings.ToLower(email) s.tx(func() { if _, ok := s.passwords[email]; !ok { @@ -312,7 +315,7 @@ func (s *memStorage) DeletePassword(email string) (err error) { return } -func (s *memStorage) DeleteClient(id string) (err error) { +func (s *memStorage) DeleteClient(ctx context.Context, id string) (err error) { s.tx(func() { if _, ok := s.clients[id]; !ok { err = storage.ErrNotFound @@ -323,7 +326,7 @@ func (s *memStorage) DeleteClient(id string) (err error) { return } -func (s *memStorage) DeleteRefresh(id string) (err error) { +func (s *memStorage) DeleteRefresh(ctx context.Context, id string) (err error) { s.tx(func() { if _, ok := s.refreshTokens[id]; !ok { err = storage.ErrNotFound @@ -334,7 +337,7 @@ func (s *memStorage) DeleteRefresh(id string) (err error) { return } -func (s *memStorage) DeleteAuthCode(id string) (err error) { +func (s *memStorage) DeleteAuthCode(ctx context.Context, id string) (err error) { s.tx(func() { if _, ok := s.authCodes[id]; !ok { err = storage.ErrNotFound @@ -345,7 +348,7 @@ func (s *memStorage) DeleteAuthCode(id string) (err error) { return } -func (s *memStorage) DeleteAuthRequest(id string) (err error) { +func (s *memStorage) DeleteAuthRequest(ctx context.Context, id string) (err error) { s.tx(func() { if _, ok := s.authReqs[id]; !ok { err = storage.ErrNotFound @@ -356,7 +359,7 @@ func (s *memStorage) DeleteAuthRequest(id string) (err error) { return } -func (s *memStorage) DeleteOfflineSessions(userID string, connID string) (err error) { +func (s *memStorage) DeleteOfflineSessions(ctx context.Context, userID string, connID string) (err error) { id := offlineSessionID{ userID: userID, connID: connID, @@ -371,7 +374,7 @@ func (s *memStorage) DeleteOfflineSessions(userID string, connID string) (err er return } -func (s *memStorage) DeleteConnector(id string) (err error) { +func (s *memStorage) DeleteConnector(ctx context.Context, id string) (err error) { s.tx(func() { if _, ok := s.connectors[id]; !ok { err = storage.ErrNotFound @@ -382,7 +385,7 @@ func (s *memStorage) DeleteConnector(id string) (err error) { return } -func (s *memStorage) UpdateClient(id string, updater func(old storage.Client) (storage.Client, error)) (err error) { +func (s *memStorage) UpdateClient(ctx context.Context, id string, updater func(old storage.Client) (storage.Client, error)) (err error) { s.tx(func() { client, ok := s.clients[id] if !ok { @@ -396,7 +399,7 @@ func (s *memStorage) UpdateClient(id string, updater func(old storage.Client) (s return } -func (s *memStorage) UpdateKeys(updater func(old storage.Keys) (storage.Keys, error)) (err error) { +func (s *memStorage) UpdateKeys(ctx context.Context, updater func(old storage.Keys) (storage.Keys, error)) (err error) { s.tx(func() { var keys storage.Keys if keys, err = updater(s.keys); err == nil { @@ -406,7 +409,7 @@ func (s *memStorage) UpdateKeys(updater func(old storage.Keys) (storage.Keys, er return } -func (s *memStorage) UpdateAuthRequest(id string, updater func(old storage.AuthRequest) (storage.AuthRequest, error)) (err error) { +func (s *memStorage) UpdateAuthRequest(ctx context.Context, id string, updater func(old storage.AuthRequest) (storage.AuthRequest, error)) (err error) { s.tx(func() { req, ok := s.authReqs[id] if !ok { @@ -420,7 +423,7 @@ func (s *memStorage) UpdateAuthRequest(id string, updater func(old storage.AuthR return } -func (s *memStorage) UpdatePassword(email string, updater func(p storage.Password) (storage.Password, error)) (err error) { +func (s *memStorage) UpdatePassword(ctx context.Context, email string, updater func(p storage.Password) (storage.Password, error)) (err error) { email = strings.ToLower(email) s.tx(func() { req, ok := s.passwords[email] @@ -435,7 +438,7 @@ func (s *memStorage) UpdatePassword(email string, updater func(p storage.Passwor return } -func (s *memStorage) UpdateRefreshToken(id string, updater func(p storage.RefreshToken) (storage.RefreshToken, error)) (err error) { +func (s *memStorage) UpdateRefreshToken(ctx context.Context, id string, updater func(p storage.RefreshToken) (storage.RefreshToken, error)) (err error) { s.tx(func() { r, ok := s.refreshTokens[id] if !ok { @@ -449,7 +452,7 @@ func (s *memStorage) UpdateRefreshToken(id string, updater func(p storage.Refres return } -func (s *memStorage) UpdateOfflineSessions(userID string, connID string, updater func(o storage.OfflineSessions) (storage.OfflineSessions, error)) (err error) { +func (s *memStorage) UpdateOfflineSessions(ctx context.Context, userID string, connID string, updater func(o storage.OfflineSessions) (storage.OfflineSessions, error)) (err error) { id := offlineSessionID{ userID: userID, connID: connID, @@ -467,7 +470,7 @@ func (s *memStorage) UpdateOfflineSessions(userID string, connID string, updater return } -func (s *memStorage) UpdateConnector(id string, updater func(c storage.Connector) (storage.Connector, error)) (err error) { +func (s *memStorage) UpdateConnector(ctx context.Context, id string, updater func(c storage.Connector) (storage.Connector, error)) (err error) { s.tx(func() { r, ok := s.connectors[id] if !ok { @@ -481,7 +484,7 @@ func (s *memStorage) UpdateConnector(id string, updater func(c storage.Connector return } -func (s *memStorage) CreateDeviceRequest(d storage.DeviceRequest) (err error) { +func (s *memStorage) CreateDeviceRequest(ctx context.Context, d storage.DeviceRequest) (err error) { s.tx(func() { if _, ok := s.deviceRequests[d.UserCode]; ok { err = storage.ErrAlreadyExists @@ -492,7 +495,7 @@ func (s *memStorage) CreateDeviceRequest(d storage.DeviceRequest) (err error) { return } -func (s *memStorage) GetDeviceRequest(userCode string) (req storage.DeviceRequest, err error) { +func (s *memStorage) GetDeviceRequest(ctx context.Context, userCode string) (req storage.DeviceRequest, err error) { s.tx(func() { var ok bool if req, ok = s.deviceRequests[userCode]; !ok { @@ -503,7 +506,7 @@ func (s *memStorage) GetDeviceRequest(userCode string) (req storage.DeviceReques return } -func (s *memStorage) CreateDeviceToken(t storage.DeviceToken) (err error) { +func (s *memStorage) CreateDeviceToken(ctx context.Context, t storage.DeviceToken) (err error) { s.tx(func() { if _, ok := s.deviceTokens[t.DeviceCode]; ok { err = storage.ErrAlreadyExists @@ -514,7 +517,7 @@ func (s *memStorage) CreateDeviceToken(t storage.DeviceToken) (err error) { return } -func (s *memStorage) GetDeviceToken(deviceCode string) (t storage.DeviceToken, err error) { +func (s *memStorage) GetDeviceToken(ctx context.Context, deviceCode string) (t storage.DeviceToken, err error) { s.tx(func() { var ok bool if t, ok = s.deviceTokens[deviceCode]; !ok { @@ -525,7 +528,7 @@ func (s *memStorage) GetDeviceToken(deviceCode string) (t storage.DeviceToken, e return } -func (s *memStorage) UpdateDeviceToken(deviceCode string, updater func(p storage.DeviceToken) (storage.DeviceToken, error)) (err error) { +func (s *memStorage) UpdateDeviceToken(ctx context.Context, deviceCode string, updater func(p storage.DeviceToken) (storage.DeviceToken, error)) (err error) { s.tx(func() { r, ok := s.deviceTokens[deviceCode] if !ok { diff --git a/storage/memory/memory_test.go b/storage/memory/memory_test.go index 84a8826ef2..e6e8232f68 100644 --- a/storage/memory/memory_test.go +++ b/storage/memory/memory_test.go @@ -1,23 +1,17 @@ package memory import ( - "os" + "log/slog" "testing" - "github.com/sirupsen/logrus" - "github.com/dexidp/dex/storage" "github.com/dexidp/dex/storage/conformance" ) func TestStorage(t *testing.T) { - logger := &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, - } + newStorage := func(t *testing.T) storage.Storage { + logger := slog.New(slog.NewTextHandler(t.Output(), &slog.HandlerOptions{Level: slog.LevelDebug})) - newStorage := func() storage.Storage { return New(logger) } conformance.RunTests(t, newStorage) diff --git a/storage/memory/static_test.go b/storage/memory/static_test.go index 8513e0ee89..49e0b28496 100644 --- a/storage/memory/static_test.go +++ b/storage/memory/static_test.go @@ -1,29 +1,25 @@ package memory import ( + "context" "fmt" - "os" + "log/slog" "strings" "testing" - "github.com/sirupsen/logrus" - "github.com/dexidp/dex/storage" ) func TestStaticClients(t *testing.T) { - logger := &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, - } + ctx := context.Background() + logger := slog.New(slog.DiscardHandler) backing := New(logger) c1 := storage.Client{ID: "foo", Secret: "foo_secret"} c2 := storage.Client{ID: "bar", Secret: "bar_secret"} c3 := storage.Client{ID: "spam", Secret: "spam_secret"} - backing.CreateClient(c1) + backing.CreateClient(ctx, c1) s := storage.WithStaticClients(backing, []storage.Client{c2}) tests := []struct { @@ -34,14 +30,14 @@ func TestStaticClients(t *testing.T) { { name: "get client from static storage", action: func() error { - _, err := s.GetClient(c2.ID) + _, err := s.GetClient(ctx, c2.ID) return err }, }, { name: "get client from backing storage", action: func() error { - _, err := s.GetClient(c1.ID) + _, err := s.GetClient(ctx, c1.ID) return err }, }, @@ -52,7 +48,7 @@ func TestStaticClients(t *testing.T) { c.Secret = "new_" + c.Secret return c, nil } - return s.UpdateClient(c2.ID, updater) + return s.UpdateClient(ctx, c2.ID, updater) }, wantErr: true, }, @@ -63,13 +59,13 @@ func TestStaticClients(t *testing.T) { c.Secret = "new_" + c.Secret return c, nil } - return s.UpdateClient(c1.ID, updater) + return s.UpdateClient(ctx, c1.ID, updater) }, }, { name: "list clients", action: func() error { - clients, err := s.ListClients() + clients, err := s.ListClients(ctx) if err != nil { return err } @@ -82,7 +78,7 @@ func TestStaticClients(t *testing.T) { { name: "create client", action: func() error { - return s.CreateClient(c3) + return s.CreateClient(ctx, c3) }, }, } @@ -99,11 +95,8 @@ func TestStaticClients(t *testing.T) { } func TestStaticPasswords(t *testing.T) { - logger := &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, - } + ctx := context.Background() + logger := slog.New(slog.DiscardHandler) backing := New(logger) p1 := storage.Password{Email: "foo@example.com", Username: "foo_secret"} @@ -111,7 +104,7 @@ func TestStaticPasswords(t *testing.T) { p3 := storage.Password{Email: "spam@example.com", Username: "spam_secret"} p4 := storage.Password{Email: "Spam@example.com", Username: "Spam_secret"} - backing.CreatePassword(p1) + backing.CreatePassword(ctx, p1) s := storage.WithStaticPasswords(backing, []storage.Password{p2}, logger) tests := []struct { @@ -122,21 +115,21 @@ func TestStaticPasswords(t *testing.T) { { name: "get password from static storage", action: func() error { - _, err := s.GetPassword(p2.Email) + _, err := s.GetPassword(ctx, p2.Email) return err }, }, { name: "get password from backing storage", action: func() error { - _, err := s.GetPassword(p1.Email) + _, err := s.GetPassword(ctx, p1.Email) return err }, }, { name: "get password from static storage with casing", action: func() error { - _, err := s.GetPassword(strings.ToUpper(p2.Email)) + _, err := s.GetPassword(ctx, strings.ToUpper(p2.Email)) return err }, }, @@ -147,7 +140,7 @@ func TestStaticPasswords(t *testing.T) { p.Username = "new_" + p.Username return p, nil } - return s.UpdatePassword(p2.Email, updater) + return s.UpdatePassword(ctx, p2.Email, updater) }, wantErr: true, }, @@ -158,23 +151,23 @@ func TestStaticPasswords(t *testing.T) { p.Username = "new_" + p.Username return p, nil } - return s.UpdatePassword(p1.Email, updater) + return s.UpdatePassword(ctx, p1.Email, updater) }, }, { name: "create passwords", action: func() error { - if err := s.CreatePassword(p4); err != nil { + if err := s.CreatePassword(ctx, p4); err != nil { return err } - return s.CreatePassword(p3) + return s.CreatePassword(ctx, p3) }, wantErr: true, }, { name: "get password", action: func() error { - p, err := s.GetPassword(p4.Email) + p, err := s.GetPassword(ctx, p4.Email) if err != nil { return err } @@ -187,7 +180,7 @@ func TestStaticPasswords(t *testing.T) { { name: "list passwords", action: func() error { - passwords, err := s.ListPasswords() + passwords, err := s.ListPasswords(ctx) if err != nil { return err } @@ -211,11 +204,8 @@ func TestStaticPasswords(t *testing.T) { } func TestStaticConnectors(t *testing.T) { - logger := &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, - } + ctx := context.Background() + logger := slog.New(slog.DiscardHandler) backing := New(logger) config1 := []byte(`{"issuer": "https://accounts.google.com"}`) @@ -226,7 +216,7 @@ func TestStaticConnectors(t *testing.T) { c2 := storage.Connector{ID: storage.NewID(), Type: "ldap", Name: "ldap", ResourceVersion: "1", Config: config2} c3 := storage.Connector{ID: storage.NewID(), Type: "saml", Name: "saml", ResourceVersion: "1", Config: config3} - backing.CreateConnector(c1) + backing.CreateConnector(ctx, c1) s := storage.WithStaticConnectors(backing, []storage.Connector{c2}) tests := []struct { @@ -237,14 +227,14 @@ func TestStaticConnectors(t *testing.T) { { name: "get connector from static storage", action: func() error { - _, err := s.GetConnector(c2.ID) + _, err := s.GetConnector(ctx, c2.ID) return err }, }, { name: "get connector from backing storage", action: func() error { - _, err := s.GetConnector(c1.ID) + _, err := s.GetConnector(ctx, c1.ID) return err }, }, @@ -255,7 +245,7 @@ func TestStaticConnectors(t *testing.T) { c.Name = "New" return c, nil } - return s.UpdateConnector(c2.ID, updater) + return s.UpdateConnector(ctx, c2.ID, updater) }, wantErr: true, }, @@ -266,13 +256,13 @@ func TestStaticConnectors(t *testing.T) { c.Name = "New" return c, nil } - return s.UpdateConnector(c1.ID, updater) + return s.UpdateConnector(ctx, c1.ID, updater) }, }, { name: "list connectors", action: func() error { - connectors, err := s.ListConnectors() + connectors, err := s.ListConnectors(ctx) if err != nil { return err } @@ -285,7 +275,7 @@ func TestStaticConnectors(t *testing.T) { { name: "create connector", action: func() error { - return s.CreateConnector(c3) + return s.CreateConnector(ctx, c3) }, }, } diff --git a/storage/sql/config.go b/storage/sql/config.go index 1aedf04cae..222b263aaf 100644 --- a/storage/sql/config.go +++ b/storage/sql/config.go @@ -5,6 +5,7 @@ import ( "crypto/x509" "database/sql" "fmt" + "log/slog" "net" "os" "regexp" @@ -15,7 +16,6 @@ import ( "github.com/go-sql-driver/mysql" "github.com/lib/pq" - "github.com/dexidp/dex/pkg/log" "github.com/dexidp/dex/storage" ) @@ -31,7 +31,6 @@ const ( mysqlErrUnknownSysVar = 1193 ) -// nolint const ( // postgres SSL modes pgSSLDisable = "disable" @@ -40,7 +39,6 @@ const ( pgSSLVerifyFull = "verify-full" ) -// nolint const ( // MySQL SSL modes mysqlSSLTrue = "true" @@ -84,7 +82,7 @@ type Postgres struct { } // Open creates a new storage implementation backed by Postgres. -func (p *Postgres) Open(logger log.Logger) (storage.Storage, error) { +func (p *Postgres) Open(logger *slog.Logger) (storage.Storage, error) { conn, err := p.open(logger) if err != nil { return nil, err @@ -164,7 +162,7 @@ func (p *Postgres) createDataSourceName() string { return strings.Join(parameters, " ") } -func (p *Postgres) open(logger log.Logger) (*conn, error) { +func (p *Postgres) open(logger *slog.Logger) (*conn, error) { dataSourceName := p.createDataSourceName() db, err := sql.Open("postgres", dataSourceName) @@ -216,7 +214,7 @@ type MySQL struct { } // Open creates a new storage implementation backed by MySQL. -func (s *MySQL) Open(logger log.Logger) (storage.Storage, error) { +func (s *MySQL) Open(logger *slog.Logger) (storage.Storage, error) { conn, err := s.open(logger) if err != nil { return nil, err @@ -224,7 +222,7 @@ func (s *MySQL) Open(logger log.Logger) (storage.Storage, error) { return conn, nil } -func (s *MySQL) open(logger log.Logger) (*conn, error) { +func (s *MySQL) open(logger *slog.Logger) (*conn, error) { cfg := mysql.Config{ User: s.User, Passwd: s.Password, @@ -274,7 +272,7 @@ func (s *MySQL) open(logger log.Logger) (*conn, error) { } if s.MaxIdleConns == 0 { - /*Override default behaviour to fix https://github.com/dexidp/dex/issues/1608*/ + /*Override default behavior to fix https://github.com/dexidp/dex/issues/1608*/ db.SetMaxIdleConns(0) } else { db.SetMaxIdleConns(s.MaxIdleConns) diff --git a/storage/sql/config_test.go b/storage/sql/config_test.go index 1178728c1a..93a593ea3c 100644 --- a/storage/sql/config_test.go +++ b/storage/sql/config_test.go @@ -2,15 +2,13 @@ package sql import ( "fmt" + "log/slog" "os" "runtime" "strconv" "testing" "time" - "github.com/sirupsen/logrus" - - "github.com/dexidp/dex/pkg/log" "github.com/dexidp/dex/storage" "github.com/dexidp/dex/storage/conformance" ) @@ -48,24 +46,19 @@ func cleanDB(c *conn) error { return nil } -var logger = &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, -} - type opener interface { - open(logger log.Logger) (*conn, error) + open(logger *slog.Logger) (*conn, error) } func testDB(t *testing.T, o opener, withTransactions bool) { // t.Fatal has a bad habit of not actually printing the error - fatal := func(i interface{}) { + fatal := func(i any) { fmt.Fprintln(os.Stdout, i) t.Fatal(i) } - newStorage := func() storage.Storage { + newStorage := func(t *testing.T) storage.Storage { + logger := slog.New(slog.NewTextHandler(t.Output(), &slog.HandlerOptions{Level: slog.LevelDebug})) conn, err := o.open(logger) if err != nil { fatal(err) diff --git a/storage/sql/crud.go b/storage/sql/crud.go index ac67bf288c..a9ca38167d 100644 --- a/storage/sql/crud.go +++ b/storage/sql/crud.go @@ -1,6 +1,7 @@ package sql import ( + "context" "database/sql" "database/sql/driver" "encoding/json" @@ -21,19 +22,18 @@ const keysRowID = "keys" // encoder wraps the underlying value in a JSON marshaler which is automatically // called by the database/sql package. // -// s := []string{"planes", "bears"} -// err := db.Exec(`insert into t1 (id, things) values (1, $1)`, encoder(s)) -// if err != nil { -// // handle error -// } -// -// var r []byte -// err = db.QueryRow(`select things from t1 where id = 1;`).Scan(&r) -// if err != nil { -// // handle error -// } -// fmt.Printf("%s\n", r) // ["planes","bears"] +// s := []string{"planes", "bears"} +// err := db.Exec(`insert into t1 (id, things) values (1, $1)`, encoder(s)) +// if err != nil { +// // handle error +// } // +// var r []byte +// err = db.QueryRow(`select things from t1 where id = 1;`).Scan(&r) +// if err != nil { +// // handle error +// } +// fmt.Printf("%s\n", r) // ["planes","bears"] func encoder(i interface{}) driver.Valuer { return jsonEncoder{i} } @@ -84,7 +84,9 @@ type scanner interface { Scan(dest ...interface{}) error } -func (c *conn) GarbageCollect(now time.Time) (storage.GCResult, error) { +var _ storage.Storage = (*conn)(nil) + +func (c *conn) GarbageCollect(ctc context.Context, now time.Time) (storage.GCResult, error) { result := storage.GCResult{} r, err := c.Exec(`delete from auth_request where expiry < $1`, now) @@ -122,7 +124,7 @@ func (c *conn) GarbageCollect(now time.Time) (storage.GCResult, error) { return result, err } -func (c *conn) CreateAuthRequest(a storage.AuthRequest) error { +func (c *conn) CreateAuthRequest(ctx context.Context, a storage.AuthRequest) error { _, err := c.Exec(` insert into auth_request ( id, client_id, response_types, scopes, redirect_uri, nonce, state, @@ -131,10 +133,11 @@ func (c *conn) CreateAuthRequest(a storage.AuthRequest) error { claims_email, claims_email_verified, claims_groups, connector_id, connector_data, expiry, - code_challenge, code_challenge_method + code_challenge, code_challenge_method, + hmac_key ) values ( - $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20 + $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21 ); `, a.ID, a.ClientID, encoder(a.ResponseTypes), encoder(a.Scopes), a.RedirectURI, a.Nonce, a.State, @@ -144,6 +147,7 @@ func (c *conn) CreateAuthRequest(a storage.AuthRequest) error { a.ConnectorID, a.ConnectorData, a.Expiry, a.PKCE.CodeChallenge, a.PKCE.CodeChallengeMethod, + a.HMACKey, ) if err != nil { if c.alreadyExistsCheck(err) { @@ -154,9 +158,9 @@ func (c *conn) CreateAuthRequest(a storage.AuthRequest) error { return nil } -func (c *conn) UpdateAuthRequest(id string, updater func(a storage.AuthRequest) (storage.AuthRequest, error)) error { +func (c *conn) UpdateAuthRequest(ctx context.Context, id string, updater func(a storage.AuthRequest) (storage.AuthRequest, error)) error { return c.ExecTx(func(tx *trans) error { - r, err := getAuthRequest(tx, id) + r, err := getAuthRequest(ctx, tx, id) if err != nil { return err } @@ -175,8 +179,9 @@ func (c *conn) UpdateAuthRequest(id string, updater func(a storage.AuthRequest) claims_groups = $14, connector_id = $15, connector_data = $16, expiry = $17, - code_challenge = $18, code_challenge_method = $19 - where id = $20; + code_challenge = $18, code_challenge_method = $19, + hmac_key = $20 + where id = $21; `, a.ClientID, encoder(a.ResponseTypes), encoder(a.Scopes), a.RedirectURI, a.Nonce, a.State, a.ForceApprovalPrompt, a.LoggedIn, @@ -185,7 +190,7 @@ func (c *conn) UpdateAuthRequest(id string, updater func(a storage.AuthRequest) encoder(a.Claims.Groups), a.ConnectorID, a.ConnectorData, a.Expiry, - a.PKCE.CodeChallenge, a.PKCE.CodeChallengeMethod, + a.PKCE.CodeChallenge, a.PKCE.CodeChallengeMethod, a.HMACKey, r.ID, ) if err != nil { @@ -195,11 +200,11 @@ func (c *conn) UpdateAuthRequest(id string, updater func(a storage.AuthRequest) }) } -func (c *conn) GetAuthRequest(id string) (storage.AuthRequest, error) { - return getAuthRequest(c, id) +func (c *conn) GetAuthRequest(ctx context.Context, id string) (storage.AuthRequest, error) { + return getAuthRequest(ctx, c, id) } -func getAuthRequest(q querier, id string) (a storage.AuthRequest, err error) { +func getAuthRequest(ctx context.Context, q querier, id string) (a storage.AuthRequest, err error) { err = q.QueryRow(` select id, client_id, response_types, scopes, redirect_uri, nonce, state, @@ -207,7 +212,7 @@ func getAuthRequest(q querier, id string) (a storage.AuthRequest, err error) { claims_user_id, claims_username, claims_preferred_username, claims_email, claims_email_verified, claims_groups, connector_id, connector_data, expiry, - code_challenge, code_challenge_method + code_challenge, code_challenge_method, hmac_key from auth_request where id = $1; `, id).Scan( &a.ID, &a.ClientID, decoder(&a.ResponseTypes), decoder(&a.Scopes), &a.RedirectURI, &a.Nonce, &a.State, @@ -216,7 +221,7 @@ func getAuthRequest(q querier, id string) (a storage.AuthRequest, err error) { &a.Claims.Email, &a.Claims.EmailVerified, decoder(&a.Claims.Groups), &a.ConnectorID, &a.ConnectorData, &a.Expiry, - &a.PKCE.CodeChallenge, &a.PKCE.CodeChallengeMethod, + &a.PKCE.CodeChallenge, &a.PKCE.CodeChallengeMethod, &a.HMACKey, ) if err != nil { if err == sql.ErrNoRows { @@ -227,7 +232,7 @@ func getAuthRequest(q querier, id string) (a storage.AuthRequest, err error) { return a, nil } -func (c *conn) CreateAuthCode(a storage.AuthCode) error { +func (c *conn) CreateAuthCode(ctx context.Context, a storage.AuthCode) error { _, err := c.Exec(` insert into auth_code ( id, client_id, scopes, nonce, redirect_uri, @@ -253,7 +258,7 @@ func (c *conn) CreateAuthCode(a storage.AuthCode) error { return nil } -func (c *conn) GetAuthCode(id string) (a storage.AuthCode, err error) { +func (c *conn) GetAuthCode(ctx context.Context, id string) (a storage.AuthCode, err error) { err = c.QueryRow(` select id, client_id, scopes, nonce, redirect_uri, @@ -278,7 +283,7 @@ func (c *conn) GetAuthCode(id string) (a storage.AuthCode, err error) { return a, nil } -func (c *conn) CreateRefresh(r storage.RefreshToken) error { +func (c *conn) CreateRefresh(ctx context.Context, r storage.RefreshToken) error { _, err := c.Exec(` insert into refresh_token ( id, client_id, scopes, nonce, @@ -305,9 +310,9 @@ func (c *conn) CreateRefresh(r storage.RefreshToken) error { return nil } -func (c *conn) UpdateRefreshToken(id string, updater func(old storage.RefreshToken) (storage.RefreshToken, error)) error { +func (c *conn) UpdateRefreshToken(ctx context.Context, id string, updater func(old storage.RefreshToken) (storage.RefreshToken, error)) error { return c.ExecTx(func(tx *trans) error { - r, err := getRefresh(tx, id) + r, err := getRefresh(ctx, tx, id) if err != nil { return err } @@ -349,11 +354,11 @@ func (c *conn) UpdateRefreshToken(id string, updater func(old storage.RefreshTok }) } -func (c *conn) GetRefresh(id string) (storage.RefreshToken, error) { - return getRefresh(c, id) +func (c *conn) GetRefresh(ctx context.Context, id string) (storage.RefreshToken, error) { + return getRefresh(ctx, c, id) } -func getRefresh(q querier, id string) (storage.RefreshToken, error) { +func getRefresh(ctx context.Context, q querier, id string) (storage.RefreshToken, error) { return scanRefresh(q.QueryRow(` select id, client_id, scopes, nonce, @@ -366,7 +371,7 @@ func getRefresh(q querier, id string) (storage.RefreshToken, error) { `, id)) } -func (c *conn) ListRefreshTokens() ([]storage.RefreshToken, error) { +func (c *conn) ListRefreshTokens(ctx context.Context) ([]storage.RefreshToken, error) { rows, err := c.Query(` select id, client_id, scopes, nonce, @@ -413,12 +418,12 @@ func scanRefresh(s scanner) (r storage.RefreshToken, err error) { return r, nil } -func (c *conn) UpdateKeys(updater func(old storage.Keys) (storage.Keys, error)) error { +func (c *conn) UpdateKeys(ctx context.Context, updater func(old storage.Keys) (storage.Keys, error)) error { return c.ExecTx(func(tx *trans) error { firstUpdate := false // TODO(ericchiang): errors may cause a transaction be rolled back by the SQL // server. Test this, and consider adding a COUNT() command beforehand. - old, err := getKeys(tx) + old, err := getKeys(ctx, tx) if err != nil { if err != storage.ErrNotFound { return fmt.Errorf("get keys: %v", err) @@ -466,11 +471,11 @@ func (c *conn) UpdateKeys(updater func(old storage.Keys) (storage.Keys, error)) }) } -func (c *conn) GetKeys() (keys storage.Keys, err error) { - return getKeys(c) +func (c *conn) GetKeys(ctx context.Context) (keys storage.Keys, err error) { + return getKeys(ctx, c) } -func getKeys(q querier) (keys storage.Keys, err error) { +func getKeys(ctx context.Context, q querier) (keys storage.Keys, err error) { err = q.QueryRow(` select verification_keys, signing_key, signing_key_pub, next_rotation @@ -489,9 +494,9 @@ func getKeys(q querier) (keys storage.Keys, err error) { return keys, nil } -func (c *conn) UpdateClient(id string, updater func(old storage.Client) (storage.Client, error)) error { +func (c *conn) UpdateClient(ctx context.Context, id string, updater func(old storage.Client) (storage.Client, error)) error { return c.ExecTx(func(tx *trans) error { - cli, err := getClient(tx, id) + cli, err := getClient(ctx, tx, id) if err != nil { return err } @@ -519,7 +524,7 @@ func (c *conn) UpdateClient(id string, updater func(old storage.Client) (storage }) } -func (c *conn) CreateClient(cli storage.Client) error { +func (c *conn) CreateClient(ctx context.Context, cli storage.Client) error { _, err := c.Exec(` insert into client ( id, secret, redirect_uris, trusted_peers, public, name, logo_url @@ -538,7 +543,7 @@ func (c *conn) CreateClient(cli storage.Client) error { return nil } -func getClient(q querier, id string) (storage.Client, error) { +func getClient(ctx context.Context, q querier, id string) (storage.Client, error) { return scanClient(q.QueryRow(` select id, secret, redirect_uris, trusted_peers, public, name, logo_url @@ -546,11 +551,11 @@ func getClient(q querier, id string) (storage.Client, error) { `, id)) } -func (c *conn) GetClient(id string) (storage.Client, error) { - return getClient(c, id) +func (c *conn) GetClient(ctx context.Context, id string) (storage.Client, error) { + return getClient(ctx, c, id) } -func (c *conn) ListClients() ([]storage.Client, error) { +func (c *conn) ListClients(ctx context.Context) ([]storage.Client, error) { rows, err := c.Query(` select id, secret, redirect_uris, trusted_peers, public, name, logo_url @@ -589,7 +594,7 @@ func scanClient(s scanner) (cli storage.Client, err error) { return cli, nil } -func (c *conn) CreatePassword(p storage.Password) error { +func (c *conn) CreatePassword(ctx context.Context, p storage.Password) error { p.Email = strings.ToLower(p.Email) _, err := c.Exec(` insert into password ( @@ -610,9 +615,9 @@ func (c *conn) CreatePassword(p storage.Password) error { return nil } -func (c *conn) UpdatePassword(email string, updater func(p storage.Password) (storage.Password, error)) error { +func (c *conn) UpdatePassword(ctx context.Context, email string, updater func(p storage.Password) (storage.Password, error)) error { return c.ExecTx(func(tx *trans) error { - p, err := getPassword(tx, email) + p, err := getPassword(ctx, tx, email) if err != nil { return err } @@ -636,11 +641,11 @@ func (c *conn) UpdatePassword(email string, updater func(p storage.Password) (st }) } -func (c *conn) GetPassword(email string) (storage.Password, error) { - return getPassword(c, email) +func (c *conn) GetPassword(ctx context.Context, email string) (storage.Password, error) { + return getPassword(ctx, c, email) } -func getPassword(q querier, email string) (p storage.Password, err error) { +func getPassword(ctx context.Context, q querier, email string) (p storage.Password, err error) { return scanPassword(q.QueryRow(` select email, hash, username, user_id @@ -648,7 +653,7 @@ func getPassword(q querier, email string) (p storage.Password, err error) { `, strings.ToLower(email))) } -func (c *conn) ListPasswords() ([]storage.Password, error) { +func (c *conn) ListPasswords(ctx context.Context) ([]storage.Password, error) { rows, err := c.Query(` select email, hash, username, user_id @@ -686,7 +691,7 @@ func scanPassword(s scanner) (p storage.Password, err error) { return p, nil } -func (c *conn) CreateOfflineSessions(s storage.OfflineSessions) error { +func (c *conn) CreateOfflineSessions(ctx context.Context, s storage.OfflineSessions) error { _, err := c.Exec(` insert into offline_session ( user_id, conn_id, refresh, connector_data @@ -706,9 +711,9 @@ func (c *conn) CreateOfflineSessions(s storage.OfflineSessions) error { return nil } -func (c *conn) UpdateOfflineSessions(userID string, connID string, updater func(s storage.OfflineSessions) (storage.OfflineSessions, error)) error { +func (c *conn) UpdateOfflineSessions(ctx context.Context, userID string, connID string, updater func(s storage.OfflineSessions) (storage.OfflineSessions, error)) error { return c.ExecTx(func(tx *trans) error { - s, err := getOfflineSessions(tx, userID, connID) + s, err := getOfflineSessions(ctx, tx, userID, connID) if err != nil { return err } @@ -733,11 +738,11 @@ func (c *conn) UpdateOfflineSessions(userID string, connID string, updater func( }) } -func (c *conn) GetOfflineSessions(userID string, connID string) (storage.OfflineSessions, error) { - return getOfflineSessions(c, userID, connID) +func (c *conn) GetOfflineSessions(ctx context.Context, userID string, connID string) (storage.OfflineSessions, error) { + return getOfflineSessions(ctx, c, userID, connID) } -func getOfflineSessions(q querier, userID string, connID string) (storage.OfflineSessions, error) { +func getOfflineSessions(ctx context.Context, q querier, userID string, connID string) (storage.OfflineSessions, error) { return scanOfflineSessions(q.QueryRow(` select user_id, conn_id, refresh, connector_data @@ -759,7 +764,7 @@ func scanOfflineSessions(s scanner) (o storage.OfflineSessions, err error) { return o, nil } -func (c *conn) CreateConnector(connector storage.Connector) error { +func (c *conn) CreateConnector(ctx context.Context, connector storage.Connector) error { _, err := c.Exec(` insert into connector ( id, type, name, resource_version, config @@ -779,9 +784,9 @@ func (c *conn) CreateConnector(connector storage.Connector) error { return nil } -func (c *conn) UpdateConnector(id string, updater func(s storage.Connector) (storage.Connector, error)) error { +func (c *conn) UpdateConnector(ctx context.Context, id string, updater func(s storage.Connector) (storage.Connector, error)) error { return c.ExecTx(func(tx *trans) error { - connector, err := getConnector(tx, id) + connector, err := getConnector(ctx, tx, id) if err != nil { return err } @@ -808,11 +813,11 @@ func (c *conn) UpdateConnector(id string, updater func(s storage.Connector) (sto }) } -func (c *conn) GetConnector(id string) (storage.Connector, error) { - return getConnector(c, id) +func (c *conn) GetConnector(ctx context.Context, id string) (storage.Connector, error) { + return getConnector(ctx, c, id) } -func getConnector(q querier, id string) (storage.Connector, error) { +func getConnector(ctx context.Context, q querier, id string) (storage.Connector, error) { return scanConnector(q.QueryRow(` select id, type, name, resource_version, config @@ -834,7 +839,7 @@ func scanConnector(s scanner) (c storage.Connector, err error) { return c, nil } -func (c *conn) ListConnectors() ([]storage.Connector, error) { +func (c *conn) ListConnectors(ctx context.Context) ([]storage.Connector, error) { rows, err := c.Query(` select id, type, name, resource_version, config @@ -859,16 +864,31 @@ func (c *conn) ListConnectors() ([]storage.Connector, error) { return connectors, nil } -func (c *conn) DeleteAuthRequest(id string) error { return c.delete("auth_request", "id", id) } -func (c *conn) DeleteAuthCode(id string) error { return c.delete("auth_code", "id", id) } -func (c *conn) DeleteClient(id string) error { return c.delete("client", "id", id) } -func (c *conn) DeleteRefresh(id string) error { return c.delete("refresh_token", "id", id) } -func (c *conn) DeletePassword(email string) error { +func (c *conn) DeleteAuthRequest(ctx context.Context, id string) error { + return c.delete("auth_request", "id", id) +} + +func (c *conn) DeleteAuthCode(ctx context.Context, id string) error { + return c.delete("auth_code", "id", id) +} + +func (c *conn) DeleteClient(ctx context.Context, id string) error { + return c.delete("client", "id", id) +} + +func (c *conn) DeleteRefresh(ctx context.Context, id string) error { + return c.delete("refresh_token", "id", id) +} + +func (c *conn) DeletePassword(ctx context.Context, email string) error { return c.delete("password", "email", strings.ToLower(email)) } -func (c *conn) DeleteConnector(id string) error { return c.delete("connector", "id", id) } -func (c *conn) DeleteOfflineSessions(userID string, connID string) error { +func (c *conn) DeleteConnector(ctx context.Context, id string) error { + return c.delete("connector", "id", id) +} + +func (c *conn) DeleteOfflineSessions(ctx context.Context, userID string, connID string) error { result, err := c.Exec(`delete from offline_session where user_id = $1 AND conn_id = $2`, userID, connID) if err != nil { return fmt.Errorf("delete offline_session: user_id = %s, conn_id = %s", userID, connID) @@ -905,7 +925,7 @@ func (c *conn) delete(table, field, id string) error { return nil } -func (c *conn) CreateDeviceRequest(d storage.DeviceRequest) error { +func (c *conn) CreateDeviceRequest(ctx context.Context, d storage.DeviceRequest) error { _, err := c.Exec(` insert into device_request ( user_code, device_code, client_id, client_secret, scopes, expiry @@ -924,7 +944,7 @@ func (c *conn) CreateDeviceRequest(d storage.DeviceRequest) error { return nil } -func (c *conn) CreateDeviceToken(t storage.DeviceToken) error { +func (c *conn) CreateDeviceToken(ctx context.Context, t storage.DeviceToken) error { _, err := c.Exec(` insert into device_token ( device_code, status, token, expiry, last_request, poll_interval, code_challenge, code_challenge_method @@ -943,11 +963,11 @@ func (c *conn) CreateDeviceToken(t storage.DeviceToken) error { return nil } -func (c *conn) GetDeviceRequest(userCode string) (storage.DeviceRequest, error) { - return getDeviceRequest(c, userCode) +func (c *conn) GetDeviceRequest(ctx context.Context, userCode string) (storage.DeviceRequest, error) { + return getDeviceRequest(ctx, c, userCode) } -func getDeviceRequest(q querier, userCode string) (d storage.DeviceRequest, err error) { +func getDeviceRequest(ctx context.Context, q querier, userCode string) (d storage.DeviceRequest, err error) { err = q.QueryRow(` select device_code, client_id, client_secret, scopes, expiry @@ -965,11 +985,11 @@ func getDeviceRequest(q querier, userCode string) (d storage.DeviceRequest, err return d, nil } -func (c *conn) GetDeviceToken(deviceCode string) (storage.DeviceToken, error) { - return getDeviceToken(c, deviceCode) +func (c *conn) GetDeviceToken(ctx context.Context, deviceCode string) (storage.DeviceToken, error) { + return getDeviceToken(ctx, c, deviceCode) } -func getDeviceToken(q querier, deviceCode string) (a storage.DeviceToken, err error) { +func getDeviceToken(ctx context.Context, q querier, deviceCode string) (a storage.DeviceToken, err error) { err = q.QueryRow(` select status, token, expiry, last_request, poll_interval, code_challenge, code_challenge_method @@ -987,9 +1007,9 @@ func getDeviceToken(q querier, deviceCode string) (a storage.DeviceToken, err er return a, nil } -func (c *conn) UpdateDeviceToken(deviceCode string, updater func(old storage.DeviceToken) (storage.DeviceToken, error)) error { +func (c *conn) UpdateDeviceToken(ctx context.Context, deviceCode string, updater func(old storage.DeviceToken) (storage.DeviceToken, error)) error { return c.ExecTx(func(tx *trans) error { - r, err := getDeviceToken(tx, deviceCode) + r, err := getDeviceToken(ctx, tx, deviceCode) if err != nil { return err } @@ -999,7 +1019,7 @@ func (c *conn) UpdateDeviceToken(deviceCode string, updater func(old storage.Dev _, err = tx.Exec(` update device_token set - status = $1, + status = $1, token = $2, last_request = $3, poll_interval = $4, diff --git a/storage/sql/migrate.go b/storage/sql/migrate.go index 57720e17f1..83e9c20d94 100644 --- a/storage/sql/migrate.go +++ b/storage/sql/migrate.go @@ -291,4 +291,11 @@ var migrations = []migration{ add column code_challenge_method text not null default '';`, }, }, + { + stmts: []string{ + ` + alter table auth_request + add column hmac_key bytea;`, + }, + }, } diff --git a/storage/sql/migrate_test.go b/storage/sql/migrate_test.go index 4b77eb2fbe..707da5433a 100644 --- a/storage/sql/migrate_test.go +++ b/storage/sql/migrate_test.go @@ -5,11 +5,10 @@ package sql import ( "database/sql" - "os" + "log/slog" "testing" sqlite3 "github.com/mattn/go-sqlite3" - "github.com/sirupsen/logrus" ) func TestMigrate(t *testing.T) { @@ -19,11 +18,7 @@ func TestMigrate(t *testing.T) { } defer db.Close() - logger := &logrus.Logger{ - Out: os.Stderr, - Formatter: &logrus.TextFormatter{DisableColors: true}, - Level: logrus.DebugLevel, - } + logger := slog.New(slog.DiscardHandler) errCheck := func(err error) bool { sqlErr, ok := err.(sqlite3.Error) diff --git a/storage/sql/postgres_test.go b/storage/sql/postgres_test.go index 3e5f8a8f65..085c068a93 100644 --- a/storage/sql/postgres_test.go +++ b/storage/sql/postgres_test.go @@ -4,6 +4,7 @@ package sql import ( + "log/slog" "os" "strconv" "testing" @@ -40,6 +41,7 @@ func TestPostgresTunables(t *testing.T) { t.Run("with nothing set, uses defaults", func(t *testing.T) { cfg := *baseCfg + logger := slog.New(slog.NewTextHandler(t.Output(), &slog.HandlerOptions{Level: slog.LevelDebug})) c, err := cfg.open(logger) if err != nil { t.Fatalf("error opening connector: %s", err.Error()) @@ -53,6 +55,7 @@ func TestPostgresTunables(t *testing.T) { t.Run("with something set, uses that", func(t *testing.T) { cfg := *baseCfg cfg.MaxOpenConns = 101 + logger := slog.New(slog.NewTextHandler(t.Output(), &slog.HandlerOptions{Level: slog.LevelDebug})) c, err := cfg.open(logger) if err != nil { t.Fatalf("error opening connector: %s", err.Error()) diff --git a/storage/sql/sql.go b/storage/sql/sql.go index 0a29216936..d671021fca 100644 --- a/storage/sql/sql.go +++ b/storage/sql/sql.go @@ -3,14 +3,13 @@ package sql import ( "database/sql" + "log/slog" "regexp" "time" // import third party drivers _ "github.com/lib/pq" _ "github.com/mattn/go-sqlite3" - - "github.com/dexidp/dex/pkg/log" ) // flavor represents a specific SQL implementation, and is used to translate query strings @@ -131,7 +130,7 @@ func (c *conn) translateArgs(args []interface{}) []interface{} { type conn struct { db *sql.DB flavor *flavor - logger log.Logger + logger *slog.Logger alreadyExistsCheck func(err error) bool } diff --git a/storage/sql/sqlite.go b/storage/sql/sqlite.go index 43df671a7c..2d29e607dc 100644 --- a/storage/sql/sqlite.go +++ b/storage/sql/sqlite.go @@ -6,10 +6,10 @@ package sql import ( "database/sql" "fmt" + "log/slog" sqlite3 "github.com/mattn/go-sqlite3" - "github.com/dexidp/dex/pkg/log" "github.com/dexidp/dex/storage" ) @@ -20,7 +20,7 @@ type SQLite3 struct { } // Open creates a new storage implementation backed by SQLite3 -func (s *SQLite3) Open(logger log.Logger) (storage.Storage, error) { +func (s *SQLite3) Open(logger *slog.Logger) (storage.Storage, error) { conn, err := s.open(logger) if err != nil { return nil, err @@ -28,7 +28,7 @@ func (s *SQLite3) Open(logger log.Logger) (storage.Storage, error) { return conn, nil } -func (s *SQLite3) open(logger log.Logger) (*conn, error) { +func (s *SQLite3) open(logger *slog.Logger) (*conn, error) { db, err := sql.Open("sqlite3", s.File) if err != nil { return nil, err diff --git a/storage/sql/sqlite_no_cgo.go b/storage/sql/sqlite_no_cgo.go new file mode 100644 index 0000000000..80d1410825 --- /dev/null +++ b/storage/sql/sqlite_no_cgo.go @@ -0,0 +1,19 @@ +//go:build !cgo +// +build !cgo + +// This is a stub for the no CGO compilation (CGO_ENABLED=0) + +package sql + +import ( + "fmt" + "log/slog" + + "github.com/dexidp/dex/storage" +) + +type SQLite3 struct{} + +func (s *SQLite3) Open(logger *slog.Logger) (storage.Storage, error) { + return nil, fmt.Errorf("SQLite storage is not available: binary compiled without CGO support. Recompile with CGO_ENABLED=1 or use a different storage backend.") +} diff --git a/storage/static.go b/storage/static.go index 806b61f9cd..386b2b2883 100644 --- a/storage/static.go +++ b/storage/static.go @@ -1,10 +1,10 @@ package storage import ( + "context" "errors" + "log/slog" "strings" - - "github.com/dexidp/dex/pkg/log" ) // Tests for this code are in the "memory" package, since this package doesn't @@ -31,11 +31,11 @@ func WithStaticClients(s Storage, staticClients []Client) Storage { return staticClientsStorage{s, staticClients, clientsByID} } -func (s staticClientsStorage) GetClient(id string) (Client, error) { +func (s staticClientsStorage) GetClient(ctx context.Context, id string) (Client, error) { if client, ok := s.clientsByID[id]; ok { return client, nil } - return s.Storage.GetClient(id) + return s.Storage.GetClient(ctx, id) } func (s staticClientsStorage) isStatic(id string) bool { @@ -43,8 +43,8 @@ func (s staticClientsStorage) isStatic(id string) bool { return ok } -func (s staticClientsStorage) ListClients() ([]Client, error) { - clients, err := s.Storage.ListClients() +func (s staticClientsStorage) ListClients(ctx context.Context) ([]Client, error) { + clients, err := s.Storage.ListClients(ctx) if err != nil { return nil, err } @@ -60,25 +60,25 @@ func (s staticClientsStorage) ListClients() ([]Client, error) { return append(clients[:n], s.clients...), nil } -func (s staticClientsStorage) CreateClient(c Client) error { +func (s staticClientsStorage) CreateClient(ctx context.Context, c Client) error { if s.isStatic(c.ID) { return errors.New("static clients: read-only cannot create client") } - return s.Storage.CreateClient(c) + return s.Storage.CreateClient(ctx, c) } -func (s staticClientsStorage) DeleteClient(id string) error { +func (s staticClientsStorage) DeleteClient(ctx context.Context, id string) error { if s.isStatic(id) { return errors.New("static clients: read-only cannot delete client") } - return s.Storage.DeleteClient(id) + return s.Storage.DeleteClient(ctx, id) } -func (s staticClientsStorage) UpdateClient(id string, updater func(old Client) (Client, error)) error { +func (s staticClientsStorage) UpdateClient(ctx context.Context, id string, updater func(old Client) (Client, error)) error { if s.isStatic(id) { return errors.New("static clients: read-only cannot update client") } - return s.Storage.UpdateClient(id, updater) + return s.Storage.UpdateClient(ctx, id, updater) } type staticPasswordsStorage struct { @@ -89,17 +89,17 @@ type staticPasswordsStorage struct { // A map of passwords that is indexed by lower-case email ids passwordsByEmail map[string]Password - logger log.Logger + logger *slog.Logger } // WithStaticPasswords returns a storage with a read-only set of passwords. -func WithStaticPasswords(s Storage, staticPasswords []Password, logger log.Logger) Storage { +func WithStaticPasswords(s Storage, staticPasswords []Password, logger *slog.Logger) Storage { passwordsByEmail := make(map[string]Password, len(staticPasswords)) for _, p := range staticPasswords { // Enable case insensitive email comparison. lowerEmail := strings.ToLower(p.Email) if _, ok := passwordsByEmail[lowerEmail]; ok { - logger.Errorf("Attempting to create StaticPasswords with the same email id: %s", p.Email) + logger.Error("attempting to create StaticPasswords with the same email id", "email", p.Email) } passwordsByEmail[lowerEmail] = p } @@ -112,18 +112,18 @@ func (s staticPasswordsStorage) isStatic(email string) bool { return ok } -func (s staticPasswordsStorage) GetPassword(email string) (Password, error) { +func (s staticPasswordsStorage) GetPassword(ctx context.Context, email string) (Password, error) { // TODO(ericchiang): BLAH. We really need to figure out how to handle // lower cased emails better. email = strings.ToLower(email) if password, ok := s.passwordsByEmail[email]; ok { return password, nil } - return s.Storage.GetPassword(email) + return s.Storage.GetPassword(ctx, email) } -func (s staticPasswordsStorage) ListPasswords() ([]Password, error) { - passwords, err := s.Storage.ListPasswords() +func (s staticPasswordsStorage) ListPasswords(ctx context.Context) ([]Password, error) { + passwords, err := s.Storage.ListPasswords(ctx) if err != nil { return nil, err } @@ -140,25 +140,25 @@ func (s staticPasswordsStorage) ListPasswords() ([]Password, error) { return append(passwords[:n], s.passwords...), nil } -func (s staticPasswordsStorage) CreatePassword(p Password) error { +func (s staticPasswordsStorage) CreatePassword(ctx context.Context, p Password) error { if s.isStatic(p.Email) { return errors.New("static passwords: read-only cannot create password") } - return s.Storage.CreatePassword(p) + return s.Storage.CreatePassword(ctx, p) } -func (s staticPasswordsStorage) DeletePassword(email string) error { +func (s staticPasswordsStorage) DeletePassword(ctx context.Context, email string) error { if s.isStatic(email) { return errors.New("static passwords: read-only cannot delete password") } - return s.Storage.DeletePassword(email) + return s.Storage.DeletePassword(ctx, email) } -func (s staticPasswordsStorage) UpdatePassword(email string, updater func(old Password) (Password, error)) error { +func (s staticPasswordsStorage) UpdatePassword(ctx context.Context, email string, updater func(old Password) (Password, error)) error { if s.isStatic(email) { return errors.New("static passwords: read-only cannot update password") } - return s.Storage.UpdatePassword(email, updater) + return s.Storage.UpdatePassword(ctx, email, updater) } // staticConnectorsStorage represents a storage with read-only set of connectors. @@ -185,15 +185,15 @@ func (s staticConnectorsStorage) isStatic(id string) bool { return ok } -func (s staticConnectorsStorage) GetConnector(id string) (Connector, error) { +func (s staticConnectorsStorage) GetConnector(ctx context.Context, id string) (Connector, error) { if connector, ok := s.connectorsByID[id]; ok { return connector, nil } - return s.Storage.GetConnector(id) + return s.Storage.GetConnector(ctx, id) } -func (s staticConnectorsStorage) ListConnectors() ([]Connector, error) { - connectors, err := s.Storage.ListConnectors() +func (s staticConnectorsStorage) ListConnectors(ctx context.Context) ([]Connector, error) { + connectors, err := s.Storage.ListConnectors(ctx) if err != nil { return nil, err } @@ -210,23 +210,23 @@ func (s staticConnectorsStorage) ListConnectors() ([]Connector, error) { return append(connectors[:n], s.connectors...), nil } -func (s staticConnectorsStorage) CreateConnector(c Connector) error { +func (s staticConnectorsStorage) CreateConnector(ctx context.Context, c Connector) error { if s.isStatic(c.ID) { return errors.New("static connectors: read-only cannot create connector") } - return s.Storage.CreateConnector(c) + return s.Storage.CreateConnector(ctx, c) } -func (s staticConnectorsStorage) DeleteConnector(id string) error { +func (s staticConnectorsStorage) DeleteConnector(ctx context.Context, id string) error { if s.isStatic(id) { return errors.New("static connectors: read-only cannot delete connector") } - return s.Storage.DeleteConnector(id) + return s.Storage.DeleteConnector(ctx, id) } -func (s staticConnectorsStorage) UpdateConnector(id string, updater func(old Connector) (Connector, error)) error { +func (s staticConnectorsStorage) UpdateConnector(ctx context.Context, id string, updater func(old Connector) (Connector, error)) error { if s.isStatic(id) { return errors.New("static connectors: read-only cannot update connector") } - return s.Storage.UpdateConnector(id, updater) + return s.Storage.UpdateConnector(ctx, id, updater) } diff --git a/storage/storage.go b/storage/storage.go index af39228a74..574b0a5a5e 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -1,6 +1,8 @@ package storage import ( + "context" + "crypto" "crypto/rand" "encoding/base32" "errors" @@ -9,7 +11,7 @@ import ( "strings" "time" - jose "gopkg.in/square/go-jose.v2" + "github.com/go-jose/go-jose/v4" ) var ( @@ -47,6 +49,11 @@ func newSecureID(len int) string { return string(buff[0]%26+'a') + strings.TrimRight(encoding.EncodeToString(buff[1:]), "=") } +// NewHMACKey returns a random key which can be used in the computation of an HMAC +func NewHMACKey(h crypto.Hash) []byte { + return []byte(newSecureID(h.Size())) +} + // GCResult returns the number of objects deleted by garbage collection. type GCResult struct { AuthRequests int64 @@ -70,42 +77,42 @@ type Storage interface { Close() error // TODO(ericchiang): Let the storages set the IDs of these objects. - CreateAuthRequest(a AuthRequest) error - CreateClient(c Client) error - CreateAuthCode(c AuthCode) error - CreateRefresh(r RefreshToken) error - CreatePassword(p Password) error - CreateOfflineSessions(s OfflineSessions) error - CreateConnector(c Connector) error - CreateDeviceRequest(d DeviceRequest) error - CreateDeviceToken(d DeviceToken) error + CreateAuthRequest(ctx context.Context, a AuthRequest) error + CreateClient(ctx context.Context, c Client) error + CreateAuthCode(ctx context.Context, c AuthCode) error + CreateRefresh(ctx context.Context, r RefreshToken) error + CreatePassword(ctx context.Context, p Password) error + CreateOfflineSessions(ctx context.Context, s OfflineSessions) error + CreateConnector(ctx context.Context, c Connector) error + CreateDeviceRequest(ctx context.Context, d DeviceRequest) error + CreateDeviceToken(ctx context.Context, d DeviceToken) error // TODO(ericchiang): return (T, bool, error) so we can indicate not found // requests that way instead of using ErrNotFound. - GetAuthRequest(id string) (AuthRequest, error) - GetAuthCode(id string) (AuthCode, error) - GetClient(id string) (Client, error) - GetKeys() (Keys, error) - GetRefresh(id string) (RefreshToken, error) - GetPassword(email string) (Password, error) - GetOfflineSessions(userID string, connID string) (OfflineSessions, error) - GetConnector(id string) (Connector, error) - GetDeviceRequest(userCode string) (DeviceRequest, error) - GetDeviceToken(deviceCode string) (DeviceToken, error) - - ListClients() ([]Client, error) - ListRefreshTokens() ([]RefreshToken, error) - ListPasswords() ([]Password, error) - ListConnectors() ([]Connector, error) + GetAuthRequest(ctx context.Context, id string) (AuthRequest, error) + GetAuthCode(ctx context.Context, id string) (AuthCode, error) + GetClient(ctx context.Context, id string) (Client, error) + GetKeys(ctx context.Context) (Keys, error) + GetRefresh(ctx context.Context, id string) (RefreshToken, error) + GetPassword(ctx context.Context, email string) (Password, error) + GetOfflineSessions(ctx context.Context, userID string, connID string) (OfflineSessions, error) + GetConnector(ctx context.Context, id string) (Connector, error) + GetDeviceRequest(ctx context.Context, userCode string) (DeviceRequest, error) + GetDeviceToken(ctx context.Context, deviceCode string) (DeviceToken, error) + + ListClients(ctx context.Context) ([]Client, error) + ListRefreshTokens(ctx context.Context) ([]RefreshToken, error) + ListPasswords(ctx context.Context) ([]Password, error) + ListConnectors(ctx context.Context) ([]Connector, error) // Delete methods MUST be atomic. - DeleteAuthRequest(id string) error - DeleteAuthCode(code string) error - DeleteClient(id string) error - DeleteRefresh(id string) error - DeletePassword(email string) error - DeleteOfflineSessions(userID string, connID string) error - DeleteConnector(id string) error + DeleteAuthRequest(ctx context.Context, id string) error + DeleteAuthCode(ctx context.Context, code string) error + DeleteClient(ctx context.Context, id string) error + DeleteRefresh(ctx context.Context, id string) error + DeletePassword(ctx context.Context, email string) error + DeleteOfflineSessions(ctx context.Context, userID string, connID string) error + DeleteConnector(ctx context.Context, id string) error // Update methods take a function for updating an object then performs that update within // a transaction. "updater" functions may be called multiple times by a single update call. @@ -121,25 +128,25 @@ type Storage interface { // // update failed, handle error // } // - UpdateClient(id string, updater func(old Client) (Client, error)) error - UpdateKeys(updater func(old Keys) (Keys, error)) error - UpdateAuthRequest(id string, updater func(a AuthRequest) (AuthRequest, error)) error - UpdateRefreshToken(id string, updater func(r RefreshToken) (RefreshToken, error)) error - UpdatePassword(email string, updater func(p Password) (Password, error)) error - UpdateOfflineSessions(userID string, connID string, updater func(s OfflineSessions) (OfflineSessions, error)) error - UpdateConnector(id string, updater func(c Connector) (Connector, error)) error - UpdateDeviceToken(deviceCode string, updater func(t DeviceToken) (DeviceToken, error)) error + UpdateClient(ctx context.Context, id string, updater func(old Client) (Client, error)) error + UpdateKeys(ctx context.Context, updater func(old Keys) (Keys, error)) error + UpdateAuthRequest(ctx context.Context, id string, updater func(a AuthRequest) (AuthRequest, error)) error + UpdateRefreshToken(ctx context.Context, id string, updater func(r RefreshToken) (RefreshToken, error)) error + UpdatePassword(ctx context.Context, email string, updater func(p Password) (Password, error)) error + UpdateOfflineSessions(ctx context.Context, userID string, connID string, updater func(s OfflineSessions) (OfflineSessions, error)) error + UpdateConnector(ctx context.Context, id string, updater func(c Connector) (Connector, error)) error + UpdateDeviceToken(ctx context.Context, deviceCode string, updater func(t DeviceToken) (DeviceToken, error)) error // GarbageCollect deletes all expired AuthCodes, // AuthRequests, DeviceRequests, and DeviceTokens. - GarbageCollect(now time.Time) (GCResult, error) + GarbageCollect(ctx context.Context, now time.Time) (GCResult, error) } // Client represents an OAuth2 client. // // For further reading see: -// * Trusted peers: https://developers.google.com/identity/protocols/CrossClientAuth -// * Public clients: https://developers.google.com/api-client-library/python/auth/installed-app +// - Trusted peers: https://developers.google.com/identity/protocols/CrossClientAuth +// - Public clients: https://developers.google.com/api-client-library/python/auth/installed-app type Client struct { // Client ID and secret used to identify the client. ID string `json:"id" yaml:"id"` @@ -223,6 +230,9 @@ type AuthRequest struct { // PKCE CodeChallenge and CodeChallengeMethod PKCE PKCE + + // HMACKey is used when generating an AuthRequest-specific HMAC + HMACKey []byte } // AuthCode represents a code which can be exchanged for an OAuth2 token response. @@ -308,7 +318,7 @@ type RefreshTokenRef struct { // OfflineSessions objects are sessions pertaining to users with refresh tokens. type OfflineSessions struct { - // UserID of an end user who has logged in to the server. + // UserID of an end user who has logged into the server. UserID string // The ID of the connector used to login the user. @@ -359,6 +369,10 @@ type Connector struct { ResourceVersion string `json:"resourceVersion"` // Config holds all the configuration information specific to the connector type. Since there // no generic struct we can use for this purpose, it is stored as a byte stream. + // + // NOTE: This is a bug. The JSON tag should be `config`. + // However, fixing this requires migrating Kubernetes objects for all previously created connectors, + // or making Dex reading both tags and act accordingly. Config []byte `json:"email"` } diff --git a/web/robots.txt b/web/robots.txt new file mode 100644 index 0000000000..1f53798bb4 --- /dev/null +++ b/web/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / diff --git a/web/static/img/gitea-icon.svg b/web/static/img/gitea-icon.svg new file mode 100644 index 0000000000..afeeacb77c --- /dev/null +++ b/web/static/img/gitea-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/static/main.css b/web/static/main.css index 0ce2c2530b..f5c61d7f39 100644 --- a/web/static/main.css +++ b/web/static/main.css @@ -32,6 +32,11 @@ body { outline: none; } +.dex-btn:disabled { + cursor: not-allowed; + opacity: 0.5; +} + .dex-btn-icon { background-position: center; background-repeat: no-repeat; @@ -53,6 +58,11 @@ body { background-image: url(../static/img/email-icon.svg); } +.dex-btn-icon--gitea { + background-color: #F5F5F5; + background-image: url(../static/img/gitea-icon.svg); +} + .dex-btn-icon--github { background-color: #F5F5F5; background-image: url(../static/img/github-icon.svg); diff --git a/web/templates/device.html b/web/templates/device.html index 674cbdc32f..944861c773 100644 --- a/web/templates/device.html +++ b/web/templates/device.html @@ -2,7 +2,7 @@

Enter User Code

-
+
{{ if( .UserCode )}} diff --git a/web/templates/password.html b/web/templates/password.html index 8c77b26e98..3e1c2ed2da 100644 --- a/web/templates/password.html +++ b/web/templates/password.html @@ -32,4 +32,12 @@

Log in to Your Account

{{ end }}
+ + + {{ template "footer.html" . }} diff --git a/web/web.go b/web/web.go index c5ff751490..0c7e9873a7 100644 --- a/web/web.go +++ b/web/web.go @@ -5,7 +5,7 @@ import ( "io/fs" ) -//go:embed static/* templates/* themes/* +//go:embed static/* templates/* themes/* robots.txt var files embed.FS // FS returns a filesystem with the default web assets.