mirror of
https://github.com/netbirdio/dex.git
synced 2026-05-22 18:43:53 -07:00
@@ -23,7 +23,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -35,13 +35,13 @@ jobs:
|
||||
publish_results: true
|
||||
|
||||
- name: Upload results as artifact
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.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
|
||||
uses: github/codeql-action/upload-sarif@c10b8064de6f491fea524254123dbe5e09572f13 # v3.29.5
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
@@ -51,19 +51,21 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
fetch-tags: true
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
|
||||
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
|
||||
|
||||
- name: Set up Syft
|
||||
uses: anchore/sbom-action/download-syft@8e94d75ddd33f69f691467e42275782e4bfefe84 # v0.20.9
|
||||
uses: anchore/sbom-action/download-syft@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0
|
||||
|
||||
- name: Install cosign
|
||||
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
|
||||
uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1
|
||||
|
||||
- name: Set image name
|
||||
id: image-name
|
||||
@@ -71,7 +73,7 @@ jobs:
|
||||
|
||||
- name: Gather build metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@318604b99e75e41977312d83839a89be02ca4893 # v5.9.0
|
||||
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
|
||||
with:
|
||||
images: |
|
||||
${{ steps.image-name.outputs.value }}
|
||||
@@ -90,6 +92,12 @@ jobs:
|
||||
labels: |
|
||||
org.opencontainers.image.documentation=https://dexidp.io/docs/
|
||||
|
||||
# Multiple exporters are not supported yet
|
||||
# See https://github.com/moby/buildkit/pull/2760
|
||||
- name: Get version from git-version script
|
||||
id: version
|
||||
run: echo "value=$(bash ./scripts/git-version)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Multiple exporters are not supported yet
|
||||
# See https://github.com/moby/buildkit/pull/2760
|
||||
- name: Determine build output
|
||||
@@ -101,7 +109,7 @@ jobs:
|
||||
if_false: type=oci,dest=image.tar
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
@@ -109,7 +117,7 @@ jobs:
|
||||
if: inputs.publish
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
@@ -117,17 +125,18 @@ jobs:
|
||||
|
||||
- name: Build and push image
|
||||
id: build
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
build-args: |
|
||||
BASE_IMAGE=${{ matrix.variant }}
|
||||
VERSION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }}
|
||||
VERSION=${{ steps.version.outputs.value }}
|
||||
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 }}
|
||||
labels: |
|
||||
${{ steps.meta.outputs.labels }}
|
||||
# cache-from: type=gha
|
||||
# cache-to: type=gha,mode=max
|
||||
outputs: ${{ steps.build-output.outputs.value }}
|
||||
@@ -154,10 +163,21 @@ jobs:
|
||||
# path: image.tar
|
||||
|
||||
- name: Extract OCI tarball
|
||||
id: extract-oci
|
||||
run: |
|
||||
mkdir -p image
|
||||
tar -xf image.tar -C image
|
||||
|
||||
image_name=$(jq -r '.manifests[0].annotations["io.containerd.image.name"]' image/index.json)
|
||||
image_tag=$(jq -r '.manifests[0].annotations["org.opencontainers.image.ref.name"]' image/index.json)
|
||||
|
||||
echo "Copying $image_tag -> $image_name"
|
||||
skopeo copy "oci:image:$image_tag" "docker-daemon:$image_name"
|
||||
|
||||
echo "value=$image_name" >> "$GITHUB_OUTPUT"
|
||||
if: ${{ !inputs.publish }}
|
||||
|
||||
|
||||
# - name: List tags
|
||||
# run: skopeo --insecure-policy list-tags oci:image
|
||||
#
|
||||
@@ -177,20 +197,28 @@ jobs:
|
||||
|
||||
# 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
|
||||
# uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.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
|
||||
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
|
||||
with:
|
||||
subject-name: ghcr.io/${{ github.repository }}
|
||||
subject-digest: ${{ steps.build.outputs.digest }}
|
||||
push-to-registry: true
|
||||
if: inputs.publish
|
||||
|
||||
- name: Prepare image fs for scanning
|
||||
run: |
|
||||
image_ref=${{ steps.extract-oci.outputs.value != '' && steps.extract-oci.outputs.value || steps.image-ref.outputs.value }}
|
||||
docker export $(docker create --rm $image_ref) -o docker-image.tar
|
||||
|
||||
mkdir -p docker-image
|
||||
tar -xf docker-image.tar -C docker-image
|
||||
|
||||
## 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
|
||||
@@ -198,25 +226,25 @@ jobs:
|
||||
run: echo "date=$(date +%Y-%m-%d)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Restore trivy cache
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||
with:
|
||||
path: cache/db
|
||||
key: trivy-cache-${{ steps.date.outputs.date }}
|
||||
restore-keys: trivy-cache-
|
||||
|
||||
- name: Run Trivy vulnerability scanner
|
||||
uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # 0.33.1
|
||||
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # 0.35.0
|
||||
with:
|
||||
input: image
|
||||
input: docker-image
|
||||
format: sarif
|
||||
output: trivy-results.sarif
|
||||
scan-type: "fs"
|
||||
scan-type: "rootfs"
|
||||
scan-ref: "."
|
||||
cache-dir: "./cache"
|
||||
# Disable skipping trivy cache for now
|
||||
# env:
|
||||
# TRIVY_SKIP_DB_UPDATE: true
|
||||
# TRIVY_SKIP_JAVA_DB_UPDATE: true
|
||||
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
|
||||
@@ -224,8 +252,11 @@ jobs:
|
||||
- name: change permissions for trivy.db
|
||||
run: sudo chmod 0644 ./cache/db/trivy.db
|
||||
|
||||
- name: Check Trivy sarif
|
||||
run: cat trivy-results.sarif
|
||||
|
||||
- name: Upload Trivy scan results as artifact
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: "[${{ github.job }}] Trivy scan results"
|
||||
path: trivy-results.sarif
|
||||
@@ -233,6 +264,6 @@ jobs:
|
||||
overwrite: true
|
||||
|
||||
- name: Upload Trivy scan results to GitHub Security tab
|
||||
uses: github/codeql-action/upload-sarif@014f16e7ab1402f30e7c3329d33797e7948572db # v3.29.5
|
||||
uses: github/codeql-action/upload-sarif@c10b8064de6f491fea524254123dbe5e09572f13 # v3.29.5
|
||||
with:
|
||||
sarif_file: trivy-results.sarif
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check minimum labels
|
||||
uses: mheap/github-action-required-labels@8afbe8ae6ab7647d0c9f0cfa7c2f939650d22509 # v5.5
|
||||
uses: mheap/github-action-required-labels@0ac283b4e65c1fb28ce6079dea5546ceca98ccbe # v5.5
|
||||
with:
|
||||
mode: minimum
|
||||
count: 1
|
||||
|
||||
@@ -48,6 +48,24 @@ jobs:
|
||||
- 3306
|
||||
options: --health-cmd "mysql -proot -e \"show databases;\"" --health-interval 10s --health-timeout 5s --health-retries 5
|
||||
|
||||
mysql8:
|
||||
image: mysql:8.0
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
MYSQL_DATABASE: dex
|
||||
ports:
|
||||
- 3306
|
||||
options: --health-cmd "mysql -proot -e \"show databases;\"" --health-interval 10s --health-timeout 5s --health-retries 5
|
||||
|
||||
mysql8-ent:
|
||||
image: mysql:8.0
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
MYSQL_DATABASE: dex
|
||||
ports:
|
||||
- 3306
|
||||
options: --health-cmd "mysql -proot -e \"show databases;\"" --health-interval 10s --health-timeout 5s --health-retries 5
|
||||
|
||||
etcd:
|
||||
image: gcr.io/etcd-development/etcd:v3.5.0
|
||||
ports:
|
||||
@@ -64,12 +82,30 @@ jobs:
|
||||
- 35357
|
||||
options: --health-cmd "curl --fail http://localhost:5000/v3" --health-interval 10s --health-timeout 5s --health-retries 5
|
||||
|
||||
vault:
|
||||
image: hashicorp/vault:1.21
|
||||
ports:
|
||||
- 8200
|
||||
env:
|
||||
VAULT_DEV_ROOT_TOKEN_ID: root-token
|
||||
VAULT_DEV_LISTEN_ADDRESS: "0.0.0.0:8200"
|
||||
options: --health-cmd "vault status -address=http://localhost:8200 || exit 1" --health-interval 10s --health-timeout 5s --health-retries 5
|
||||
|
||||
openbao:
|
||||
image: quay.io/openbao/openbao:2.5
|
||||
ports:
|
||||
- 8210
|
||||
env:
|
||||
BAO_DEV_ROOT_TOKEN_ID: root-token
|
||||
BAO_DEV_LISTEN_ADDRESS: "0.0.0.0:8210"
|
||||
options: --health-cmd "bao status -address=http://localhost:8210 || exit 1" --health-interval 10s --health-timeout 5s --health-retries 5
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
|
||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
||||
with:
|
||||
go-version: "1.25"
|
||||
|
||||
@@ -86,7 +122,7 @@ jobs:
|
||||
run: docker compose -f docker-compose.test.yaml up -d
|
||||
|
||||
- name: Create kind cluster
|
||||
uses: helm/kind-action@92086f6be054225fa813e0a4b13787fc9088faab # v1.13.0
|
||||
uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # v1.14.0
|
||||
with:
|
||||
version: "v0.17.0"
|
||||
node_image: "kindest/node:v1.25.3@sha256:cd248d1438192f7814fbca8fede13cfe5b9918746dfa12583976158a834fd5c5"
|
||||
@@ -106,6 +142,18 @@ jobs:
|
||||
DEX_MYSQL_ENT_HOST: 127.0.0.1
|
||||
DEX_MYSQL_ENT_PORT: ${{ job.services.mysql-ent.ports[3306] }}
|
||||
|
||||
DEX_MYSQL8_DATABASE: dex
|
||||
DEX_MYSQL8_USER: root
|
||||
DEX_MYSQL8_PASSWORD: root
|
||||
DEX_MYSQL8_HOST: 127.0.0.1
|
||||
DEX_MYSQL8_PORT: ${{ job.services.mysql8.ports[3306] }}
|
||||
|
||||
DEX_MYSQL8_ENT_DATABASE: dex
|
||||
DEX_MYSQL8_ENT_USER: root
|
||||
DEX_MYSQL8_ENT_PASSWORD: root
|
||||
DEX_MYSQL8_ENT_HOST: 127.0.0.1
|
||||
DEX_MYSQL8_ENT_PORT: ${{ job.services.mysql8-ent.ports[3306] }}
|
||||
|
||||
DEX_POSTGRES_DATABASE: postgres
|
||||
DEX_POSTGRES_USER: postgres
|
||||
DEX_POSTGRES_PASSWORD: postgres
|
||||
@@ -129,6 +177,11 @@ jobs:
|
||||
DEX_KEYSTONE_ADMIN_USER: demo
|
||||
DEX_KEYSTONE_ADMIN_PASS: DEMO_PASS
|
||||
|
||||
DEX_VAULT_ADDR: http://localhost:${{ job.services.vault.ports[8200] }}
|
||||
DEX_VAULT_TOKEN: root-token
|
||||
DEX_OPENBAO_ADDR: http://localhost:${{ job.services.openbao.ports[8210] }}
|
||||
DEX_OPENBAO_TOKEN: root-token
|
||||
|
||||
DEX_KUBERNETES_CONFIG_PATH: ~/.kube/config
|
||||
|
||||
lint:
|
||||
@@ -137,10 +190,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
|
||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
||||
with:
|
||||
go-version: "1.25"
|
||||
|
||||
@@ -172,7 +225,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Dependency Review
|
||||
uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2
|
||||
uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0
|
||||
|
||||
@@ -7,6 +7,9 @@ on:
|
||||
- cron: '0 0 * * *' # Run daily at midnight UTC
|
||||
workflow_dispatch: # Allow manual triggering
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
update-trivy-db:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -33,7 +36,7 @@ jobs:
|
||||
rm javadb.tar.gz
|
||||
|
||||
- name: Cache DBs
|
||||
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||
with:
|
||||
path: ${{ github.workspace }}/.cache/trivy
|
||||
key: cache-trivy-${{ steps.date.outputs.date }}
|
||||
|
||||
@@ -6,3 +6,4 @@
|
||||
/docker-compose.override.yaml
|
||||
/var/
|
||||
/vendor/
|
||||
*.db
|
||||
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
# Contributing to Dex
|
||||
|
||||
Dex is [Apache 2.0 licensed](LICENSE) and accepts contributions via GitHub pull requests.
|
||||
This document outlines how to contribute to the project.
|
||||
|
||||
- [Code of Conduct](#code-of-conduct)
|
||||
- [Finding something to work on](#finding-something-to-work-on)
|
||||
- [Setting up a development environment](#setting-up-a-development-environment)
|
||||
- [Making changes](#making-changes)
|
||||
- [Running the example app](#running-the-example-app)
|
||||
- [Committing your changes](#committing-your-changes)
|
||||
- [Submitting a pull request](#submitting-a-pull-request)
|
||||
- [Enhancement proposals](#enhancement-proposals)
|
||||
- [Getting help](#getting-help)
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
This project follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
|
||||
|
||||
## Finding something to work on
|
||||
|
||||
If you have a bug fix or a small improvement, go ahead and open a pull request.
|
||||
|
||||
For larger changes, please open a [discussion](https://github.com/dexidp/dex/discussions/new?category=Ideas) first
|
||||
to align with the community and avoid unnecessary work. Major features or significant architectural
|
||||
changes should go through the [Enhancement Proposal](#enhancement-proposals) process.
|
||||
|
||||
If you're looking for something to work on, check:
|
||||
|
||||
- Issues labeled with [good first issue](https://github.com/dexidp/dex/labels/good%20first%20issue)
|
||||
- Issues labeled with [help wanted](https://github.com/dexidp/dex/labels/help%20wanted)
|
||||
|
||||
Please comment on the issue to claim it before starting work to avoid duplicated efforts.
|
||||
|
||||
## Setting up a development environment
|
||||
|
||||
For the best developer experience, install [Nix](https://builtwithnix.org/) and [direnv](https://direnv.net/).
|
||||
This will automatically set up all required tools (Go, golangci-lint, protobuf compiler, kind, etc.).
|
||||
|
||||
Alternatively, you can set up the environment manually:
|
||||
|
||||
1. Install [Go](https://go.dev/doc/install) (see the version in [go.mod](go.mod)).
|
||||
2. Install [Docker](https://docs.docker.com/get-started/).
|
||||
3. Install development dependencies:
|
||||
|
||||
```shell
|
||||
make deps
|
||||
```
|
||||
|
||||
This installs `golangci-lint`, `gotestsum`, `protoc`, `protoc-gen-go`, `protoc-gen-go-grpc`, and `kind`.
|
||||
|
||||
You can also [use Gitpod](https://gitpod.io/#https://github.com/dexidp/dex) for a ready-to-code cloud environment.
|
||||
|
||||
## Making changes
|
||||
|
||||
Run `make help` to see all available commands. The key ones for contributors:
|
||||
|
||||
```shell
|
||||
make deps # Install development dependencies
|
||||
make build # Build Dex binaries
|
||||
make testall # Run all tests (includes race detection)
|
||||
make lint # Run linter
|
||||
make generate # Regenerate protobuf, ent, and go mod tidy
|
||||
```
|
||||
|
||||
## Running the example app
|
||||
|
||||
To test the login flow locally, run Dex with the dev config and the example OIDC client app.
|
||||
|
||||
**Terminal 1** — start Dex:
|
||||
|
||||
```shell
|
||||
make build
|
||||
./bin/dex serve config.dev.yaml
|
||||
```
|
||||
|
||||
**Terminal 2** — start the example app:
|
||||
|
||||
```shell
|
||||
make examples
|
||||
./bin/example-app
|
||||
```
|
||||
|
||||
Open http://127.0.0.1:5555 in your browser, click "Login", and authenticate with:
|
||||
|
||||
- **Email:** `admin@example.com`
|
||||
- **Password:** `password`
|
||||
|
||||
After successful login, the example app displays the ID token claims returned by Dex.
|
||||
|
||||
## Committing your changes
|
||||
|
||||
The project follows [Conventional Commits](https://www.conventionalcommits.org/) style:
|
||||
|
||||
```
|
||||
<type>[optional scope]: <description>
|
||||
|
||||
[optional body]
|
||||
|
||||
Signed-off-by: First Last <email@example.com>
|
||||
```
|
||||
|
||||
Common types: `feat`, `fix`, `build`, `chore`, `docs`, `refactor`, `test`.
|
||||
|
||||
Examples from the project:
|
||||
|
||||
```
|
||||
feat: use protobuf for session cookie (#4675)
|
||||
fix: non-constant format string in call to newRedirectedErr (#4671)
|
||||
build(deps): bump github/codeql-action from 4.33.0 to 4.34.1 (#4679)
|
||||
```
|
||||
|
||||
### Developer Certificate of Origin
|
||||
|
||||
As a CNCF project, Dex requires all contributors to sign the [Developer Certificate of Origin (DCO)](https://developercertificate.org/).
|
||||
This certifies that you have the right to submit your contribution under the project's open source license.
|
||||
|
||||
You must add a `Signed-off-by` line to every commit. Use git's `-s` flag to do this automatically:
|
||||
|
||||
```shell
|
||||
git commit -s -m "feat: add new feature"
|
||||
```
|
||||
|
||||
The DCO check will fail on pull requests with unsigned commits.
|
||||
|
||||
## Submitting a pull request
|
||||
|
||||
1. Fork the repository and create your branch from `master`.
|
||||
2. Make your changes, following the guidelines above.
|
||||
3. Ensure all tests pass (`make testall`) and the linter is clean (`make lint`).
|
||||
4. Ensure generated code is up to date (`make generate`).
|
||||
5. Push your branch and open a pull request.
|
||||
|
||||
When opening a pull request:
|
||||
|
||||
- Fill in the [pull request template](.github/PULL_REQUEST_TEMPLATE.md) with an overview and explanation of the change.
|
||||
- After opening a PR, a maintainer will add least one [release note label](https://github.com/dexidp/dex/labels?q=release-note) to the PR.
|
||||
Valid labels include: `kind/feature`, `kind/enhancement`, `kind/bug`, `release-note/new-feature`,
|
||||
`release-note/enhancement`, `release-note/bug-fix`, `release-note/breaking-change`,
|
||||
`release-note/deprecation`, `release-note/ignore`, `area/dependencies`, `release-note/dependency-update`.
|
||||
- If the PR is still in progress, use GitHub's [Draft PR](https://github.blog/2019-02-14-introducing-draft-pull-requests/) feature.
|
||||
|
||||
All CI checks (tests, linting, DCO, release label) must pass before the PR can be merged.
|
||||
|
||||
## Enhancement proposals
|
||||
|
||||
Significant features or architectural changes require a [Dex Enhancement Proposal (DEP)](docs/enhancements/README.md).
|
||||
|
||||
The process:
|
||||
|
||||
1. Search existing [issues](https://github.com/dexidp/dex/issues), [discussions](https://github.com/dexidp/dex/discussions), and [DEPs](https://github.com/dexidp/dex/tree/master/docs/enhancements).
|
||||
2. Open a [discussion](https://github.com/dexidp/dex/discussions/new?category=Ideas) to get initial feedback.
|
||||
3. Fork the repo and copy the [DEP template](docs/enhancements/_title-YYYY-MM-DD-#issue.md) with an appropriate name.
|
||||
4. Fill in all sections and submit a PR for review.
|
||||
|
||||
## Getting help
|
||||
|
||||
- For bugs and feature requests, file an [issue](https://github.com/dexidp/dex/issues).
|
||||
- For general discussion, open a [discussion](https://github.com/dexidp/dex/discussions) or join [#dexidp](https://cloud-native.slack.com/messages/dexidp) on the CNCF Slack.
|
||||
- Mailing list (as a backup): [dex-dev](https://groups.google.com/forum/#!forum/dex-dev).
|
||||
- For security vulnerabilities, see the [security policy](.github/SECURITY.md).
|
||||
+15
-7
@@ -2,7 +2,7 @@ ARG BASE_IMAGE=alpine
|
||||
|
||||
FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.9.0@sha256:c64defb9ed5a91eacb37f96ccc3d4cd72521c4bd18d5442905b95e2226b0e707 AS xx
|
||||
|
||||
FROM --platform=$BUILDPLATFORM golang:1.25.5-alpine3.22@sha256:3587db7cc96576822c606d119729370dbf581931c5f43ac6d3fa03ab4ed85a10 AS builder
|
||||
FROM --platform=$BUILDPLATFORM golang:1.26.1-alpine3.22@sha256:07e91d24f6330432729082bb580983181809e0a48f0f38ecde26868d4568c6ac AS builder
|
||||
|
||||
COPY --from=xx / /
|
||||
|
||||
@@ -35,27 +35,31 @@ RUN make release-binary
|
||||
|
||||
RUN xx-verify /go/bin/dex && xx-verify /go/bin/docker-entrypoint
|
||||
|
||||
FROM alpine:3.23.0@sha256:51183f2cfa6320055da30872f211093f9ff1d3cf06f39a0bdb212314c5dc7375 AS stager
|
||||
FROM alpine:3.23.3@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659 AS stager
|
||||
|
||||
RUN mkdir -p /var/dex
|
||||
RUN mkdir -p /etc/dex
|
||||
COPY config.docker.yaml /etc/dex/
|
||||
|
||||
FROM alpine:3.23.0@sha256:51183f2cfa6320055da30872f211093f9ff1d3cf06f39a0bdb212314c5dc7375 AS gomplate
|
||||
FROM alpine:3.23.3@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659 AS gomplate
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
ARG TARGETVARIANT
|
||||
|
||||
ENV GOMPLATE_VERSION=v4.3.3
|
||||
ENV GOMPLATE_VERSION=v5.0.0
|
||||
|
||||
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.23.0@sha256:51183f2cfa6320055da30872f211093f9ff1d3cf06f39a0bdb212314c5dc7375 AS alpine
|
||||
FROM gcr.io/distroless/static-debian12:nonroot@sha256:2b7c93f6d6648c11f0e80a48558c8f77885eb0445213b8e69a6a0d7c89fc6ae4 AS distroless
|
||||
FROM alpine:3.23.3@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659 AS alpine
|
||||
|
||||
FROM alpine AS user-setup
|
||||
RUN addgroup -g 1001 -S dex && adduser -u 1001 -S -G dex -D -H -s /sbin/nologin dex
|
||||
|
||||
FROM gcr.io/distroless/static-debian13:nonroot@sha256:e3f945647ffb95b5839c07038d64f9811adf17308b9121d8a2b87b6a22a80a39 AS distroless
|
||||
|
||||
FROM $BASE_IMAGE
|
||||
|
||||
@@ -66,6 +70,10 @@ FROM $BASE_IMAGE
|
||||
# See https://go.dev/src/crypto/x509/root_linux.go for Go root CA bundle locations.
|
||||
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
|
||||
|
||||
# Ensure the dex user/group exist before setting ownership or switching to them.
|
||||
COPY --from=user-setup /etc/passwd /etc/passwd
|
||||
COPY --from=user-setup /etc/group /etc/group
|
||||
|
||||
COPY --from=stager --chown=1001:1001 /var/dex /var/dex
|
||||
COPY --from=stager --chown=1001:1001 /etc/dex /etc/dex
|
||||
|
||||
@@ -79,7 +87,7 @@ COPY --from=builder /usr/local/src/dex/web /srv/dex/web
|
||||
|
||||
COPY --from=gomplate /usr/local/bin/gomplate /usr/local/bin/gomplate
|
||||
|
||||
USER 1001:1001
|
||||
USER dex:dex
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/docker-entrypoint"]
|
||||
CMD ["dex", "serve", "/etc/dex/config.docker.yaml"]
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
Joel Speed <Joel.speed@hotmail.co.uk> (@JoelSpeed)
|
||||
Maksim Nabokikh <max.nabokih@gmail.com> (@nabokihms)
|
||||
Mark Sagi-Kazar <mark.sagikazar@gmail.com> (@sagikazarmark)
|
||||
Nandor Kracser <bonifaido@gmail.com> (@bonifaido)
|
||||
Rithu John <rithujohn191@gmail.com> (@rithujohn191)
|
||||
Stephen Augustus <foo@auggie.dev> (@justaugustus)
|
||||
@@ -0,0 +1,25 @@
|
||||
# Dex Maintainers
|
||||
|
||||
The current Maintainers Group for the Dex Project consists of:
|
||||
|
||||
| Name | GitHub | Employer | Responsibilities |
|
||||
| ---- | ------ | -------- | ---------------- |
|
||||
| Maksim Nabokikh | [@nabokihms](https://github.com/nabokihms) | [Palark GmbH](https://palark.de/) | ALL |
|
||||
| Márk Sági-Kazár | [@sagikazarmark](https://github.com/sagikazarmark) | <!-- TODO: employer --> | ALL |
|
||||
|
||||
This list must be kept in sync with the [CNCF Project Maintainers list](https://github.com/cncf/foundation/blob/master/project-maintainers.csv).
|
||||
|
||||
<!-- TODO (nabokihms): Add the Governance
|
||||
See [the project Governance](./GOVERNANCE.md) for how maintainers are selected and replaced.
|
||||
-->
|
||||
|
||||
## Emeritus Maintainers
|
||||
|
||||
We are grateful to our former maintainers for their contributions to the Dex project.
|
||||
|
||||
- [@ericchiang](https://github.com/ericchiang) - Eric Chiang
|
||||
- [@JoelSpeed](https://github.com/JoelSpeed) - Joel Speed
|
||||
- [@bonifaido](https://github.com/bonifaido) - Nandor Kracser
|
||||
- [@rithujohn191](https://github.com/rithujohn191) - Rithu John
|
||||
- [@justaugustus](https://github.com/justaugustus) - Stephen Augustus
|
||||
- [@srenatus](https://github.com/srenatus) - Stephan Renatus
|
||||
@@ -35,6 +35,10 @@ build: bin/dex ## Build Dex binaries.
|
||||
|
||||
examples: bin/grpc-client bin/example-app ## Build example app.
|
||||
|
||||
.PHONY: update-gomplate
|
||||
update-gomplate: ## Check and update gomplate version in Dockerfile.
|
||||
@./scripts/update-gomplate
|
||||
|
||||
.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).
|
||||
@@ -123,12 +127,28 @@ verify-go-mod: go-mod-tidy ## Check that go.mod and go.sum formatted according t
|
||||
|
||||
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 ./...
|
||||
# Detect if we're running in GitHub Actions
|
||||
ifdef GITHUB_ACTIONS
|
||||
GOTESTSUM_FORMAT = github-actions
|
||||
else
|
||||
GOTESTSUM_FORMAT = testname
|
||||
GOTESTSUM_FORMAT_ICONS = hivis
|
||||
endif
|
||||
|
||||
testrace: ## Test go code and check for possible race conditions.
|
||||
@go test -v --race ./...
|
||||
.PHONY: test testrace testall
|
||||
test: bin/gotestsum ## Test go code.
|
||||
ifdef GOTESTSUM_FORMAT_ICONS
|
||||
@gotestsum --format $(GOTESTSUM_FORMAT) --format-icons $(GOTESTSUM_FORMAT_ICONS) -- -v ./...
|
||||
else
|
||||
@gotestsum --format $(GOTESTSUM_FORMAT) -- -v ./...
|
||||
endif
|
||||
|
||||
testrace: bin/gotestsum ## Test go code and check for possible race conditions.
|
||||
ifdef GOTESTSUM_FORMAT_ICONS
|
||||
@gotestsum --format $(GOTESTSUM_FORMAT) --format-icons $(GOTESTSUM_FORMAT_ICONS) -- -v --race ./...
|
||||
else
|
||||
@gotestsum --format $(GOTESTSUM_FORMAT) -- -v --race ./...
|
||||
endif
|
||||
|
||||
testall: testrace ## Run all tests for go code.
|
||||
|
||||
|
||||
+185
-163
@@ -23,16 +23,17 @@ const (
|
||||
|
||||
// Client represents an OAuth2 client.
|
||||
type Client struct {
|
||||
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
|
||||
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"`
|
||||
AllowedConnectors []string `protobuf:"bytes,8,rep,name=allowed_connectors,json=allowedConnectors,proto3" json:"allowed_connectors,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Client) Reset() {
|
||||
@@ -114,6 +115,13 @@ func (x *Client) GetLogoUrl() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Client) GetAllowedConnectors() []string {
|
||||
if x != nil {
|
||||
return x.AllowedConnectors
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateClientReq is a request to make a client.
|
||||
type CreateClientReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
@@ -305,14 +313,15 @@ func (x *DeleteClientResp) GetNotFound() bool {
|
||||
|
||||
// UpdateClientReq is a request to update an existing client.
|
||||
type UpdateClientReq 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"`
|
||||
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
|
||||
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"`
|
||||
AllowedConnectors []string `protobuf:"bytes,6,rep,name=allowed_connectors,json=allowedConnectors,proto3" json:"allowed_connectors,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *UpdateClientReq) Reset() {
|
||||
@@ -380,6 +389,13 @@ func (x *UpdateClientReq) GetLogoUrl() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *UpdateClientReq) GetAllowedConnectors() []string {
|
||||
if x != nil {
|
||||
return x.AllowedConnectors
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateClientResp returns the response from updating a client.
|
||||
type UpdateClientResp struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
@@ -1326,7 +1342,7 @@ var File_api_api_proto protoreflect.FileDescriptor
|
||||
|
||||
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,
|
||||
0x03, 0x61, 0x70, 0x69, 0x22, 0xf0, 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,
|
||||
0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x64, 0x69, 0x72,
|
||||
@@ -1338,155 +1354,161 @@ var file_api_api_proto_rawDesc = string([]byte{
|
||||
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, 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, 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,
|
||||
0x07, 0x6c, 0x6f, 0x67, 0x6f, 0x55, 0x72, 0x6c, 0x12, 0x2d, 0x0a, 0x12, 0x61, 0x6c, 0x6c, 0x6f,
|
||||
0x77, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x08,
|
||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x43, 0x6f, 0x6e,
|
||||
0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 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, 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,
|
||||
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, 0xc9, 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,
|
||||
0x12, 0x2d, 0x0a, 0x12, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x6e,
|
||||
0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x61, 0x6c,
|
||||
0x6c, 0x6f, 0x77, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 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, 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, 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,
|
||||
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, 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, 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, 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, 0x2f, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x6f, 0x73,
|
||||
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,
|
||||
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, 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, 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, 0x2f, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x6f, 0x73, 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 (
|
||||
|
||||
@@ -14,6 +14,7 @@ message Client {
|
||||
bool public = 5;
|
||||
string name = 6;
|
||||
string logo_url = 7;
|
||||
repeated string allowed_connectors = 8;
|
||||
}
|
||||
|
||||
// CreateClientReq is a request to make a client.
|
||||
@@ -45,6 +46,7 @@ message UpdateClientReq {
|
||||
repeated string trusted_peers = 3;
|
||||
string name = 4;
|
||||
string logo_url = 5;
|
||||
repeated string allowed_connectors = 6;
|
||||
}
|
||||
|
||||
// UpdateClientResp returns the response from updating a client.
|
||||
|
||||
+565
-426
File diff suppressed because it is too large
Load Diff
@@ -14,6 +14,8 @@ message Client {
|
||||
bool public = 5;
|
||||
string name = 6;
|
||||
string logo_url = 7;
|
||||
repeated string allowed_connectors = 8;
|
||||
repeated string sso_shared_with = 9;
|
||||
}
|
||||
|
||||
// ClientInfo represents an OAuth2 client without sensitive information.
|
||||
@@ -24,6 +26,8 @@ message ClientInfo {
|
||||
bool public = 4;
|
||||
string name = 5;
|
||||
string logo_url = 6;
|
||||
repeated string allowed_connectors = 7;
|
||||
repeated string sso_shared_with = 8;
|
||||
}
|
||||
|
||||
// GetClientReq is a request to retrieve client details.
|
||||
@@ -66,6 +70,8 @@ message UpdateClientReq {
|
||||
repeated string trusted_peers = 3;
|
||||
string name = 4;
|
||||
string logo_url = 5;
|
||||
repeated string allowed_connectors = 6;
|
||||
repeated string sso_shared_with = 7;
|
||||
}
|
||||
|
||||
// UpdateClientResp returns the response from updating a client.
|
||||
@@ -140,6 +146,7 @@ message Connector {
|
||||
string type = 2;
|
||||
string name = 3;
|
||||
bytes config = 4;
|
||||
repeated string grant_types = 5;
|
||||
}
|
||||
|
||||
// CreateConnectorReq is a request to make a connector.
|
||||
@@ -152,6 +159,12 @@ message CreateConnectorResp {
|
||||
bool already_exists = 1;
|
||||
}
|
||||
|
||||
// GrantTypes wraps a list of grant types to distinguish between
|
||||
// "not specified" (no update) and "empty list" (unrestricted).
|
||||
message GrantTypes {
|
||||
repeated string grant_types = 1;
|
||||
}
|
||||
|
||||
// UpdateConnectorReq is a request to modify an existing connector.
|
||||
message UpdateConnectorReq {
|
||||
// The id used to lookup the connector. This field cannot be modified
|
||||
@@ -159,6 +172,10 @@ message UpdateConnectorReq {
|
||||
string new_type = 2;
|
||||
string new_name = 3;
|
||||
bytes new_config = 4;
|
||||
// If set, updates the connector's allowed grant types.
|
||||
// An empty grant_types list means unrestricted (all grant types allowed).
|
||||
// If not set (null), grant types are not modified.
|
||||
GrantTypes new_grant_types = 5;
|
||||
}
|
||||
|
||||
// UpdateConnectorResp returns the response from modifying an existing connector.
|
||||
|
||||
+7
-7
@@ -1,15 +1,15 @@
|
||||
module github.com/dexidp/dex/api/v2
|
||||
|
||||
go 1.24.0
|
||||
go 1.25.0
|
||||
|
||||
require (
|
||||
google.golang.org/grpc v1.77.0
|
||||
google.golang.org/protobuf v1.36.10
|
||||
google.golang.org/grpc v1.79.3
|
||||
google.golang.org/protobuf v1.36.11
|
||||
)
|
||||
|
||||
require (
|
||||
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
|
||||
golang.org/x/net v0.52.0 // indirect
|
||||
golang.org/x/sys v0.42.0 // indirect
|
||||
golang.org/x/text v0.35.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 // indirect
|
||||
)
|
||||
|
||||
+24
-22
@@ -1,3 +1,5 @@
|
||||
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/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=
|
||||
@@ -10,27 +12,27 @@ 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=
|
||||
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
||||
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
|
||||
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
|
||||
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
|
||||
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
|
||||
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
|
||||
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
|
||||
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
|
||||
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
|
||||
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
|
||||
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=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 h1:ndE4FoJqsIceKP2oYSnUZqhTdYufCYYkqwtFzfrhI7w=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
|
||||
google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
|
||||
+298
-31
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@@ -10,10 +11,12 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
|
||||
"github.com/dexidp/dex/pkg/featureflags"
|
||||
"github.com/dexidp/dex/server"
|
||||
"github.com/dexidp/dex/server/signer"
|
||||
"github.com/dexidp/dex/storage"
|
||||
"github.com/dexidp/dex/storage/ent"
|
||||
"github.com/dexidp/dex/storage/etcd"
|
||||
@@ -22,6 +25,15 @@ import (
|
||||
"github.com/dexidp/dex/storage/sql"
|
||||
)
|
||||
|
||||
func configUnmarshaller(b []byte, v interface{}) error {
|
||||
if !featureflags.ConfigDisallowUnknownFields.Enabled() {
|
||||
return json.Unmarshal(b, v)
|
||||
}
|
||||
dec := json.NewDecoder(bytes.NewReader(b))
|
||||
dec.DisallowUnknownFields()
|
||||
return dec.Decode(v)
|
||||
}
|
||||
|
||||
// Config is the config format for the main application.
|
||||
type Config struct {
|
||||
Issuer string `json:"issuer"`
|
||||
@@ -35,6 +47,9 @@ type Config struct {
|
||||
|
||||
Frontend server.WebConfig `json:"frontend"`
|
||||
|
||||
// Signer configuration controls signing of JWT tokens issued by Dex.
|
||||
Signer Signer `json:"signer"`
|
||||
|
||||
// StaticConnectors are user defined connectors specified in the ConfigMap
|
||||
// Write operations, like updating a connector, will fail.
|
||||
StaticConnectors []Connector `json:"connectors"`
|
||||
@@ -51,6 +66,23 @@ type Config struct {
|
||||
// querying the storage. Cannot be specified without enabling a passwords
|
||||
// database.
|
||||
StaticPasswords []password `json:"staticPasswords"`
|
||||
|
||||
// Sessions holds authentication session configuration.
|
||||
// Requires DEX_SESSIONS_ENABLED=true feature flag.
|
||||
Sessions *Sessions `json:"sessions"`
|
||||
|
||||
// MFA holds multi-factor authentication configuration.
|
||||
MFA MFAConfig `json:"mfa"`
|
||||
}
|
||||
|
||||
// MFAConfig holds multi-factor authentication settings.
|
||||
type MFAConfig struct {
|
||||
// Authenticators defines MFA providers available for clients to reference.
|
||||
Authenticators []MFAAuthenticator `json:"authenticators"`
|
||||
|
||||
// DefaultMFAChain is the default ordered list of authenticator IDs applied
|
||||
// to clients that don't specify their own mfaChain. Empty means no MFA by default.
|
||||
DefaultMFAChain []string `json:"defaultMFAChain"`
|
||||
}
|
||||
|
||||
// Validate the configuration
|
||||
@@ -85,9 +117,63 @@ func (c Config) Validate() error {
|
||||
checkErrors = append(checkErrors, check.errMsg)
|
||||
}
|
||||
}
|
||||
|
||||
if len(checkErrors) != 0 {
|
||||
return fmt.Errorf("invalid Config:\n\t-\t%s", strings.Join(checkErrors, "\n\t-\t"))
|
||||
}
|
||||
|
||||
if c.Sessions != nil && !featureflags.SessionsEnabled.Enabled() {
|
||||
return fmt.Errorf("sessions config requires sessions to be enabled (DEX_SESSIONS_ENABLED=true)")
|
||||
}
|
||||
|
||||
if err := c.validateMFA(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Config) validateMFA() error {
|
||||
mfa := c.MFA
|
||||
if len(mfa.Authenticators) == 0 && len(mfa.DefaultMFAChain) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !featureflags.SessionsEnabled.Enabled() {
|
||||
return fmt.Errorf("mfa requires sessions to be enabled (DEX_SESSIONS_ENABLED=true)")
|
||||
}
|
||||
|
||||
knownTypes := map[string]bool{"TOTP": true, "WebAuthn": true}
|
||||
ids := make(map[string]bool, len(mfa.Authenticators))
|
||||
|
||||
for _, auth := range mfa.Authenticators {
|
||||
if auth.ID == "" {
|
||||
return fmt.Errorf("mfa.authenticators: authenticator must have an id")
|
||||
}
|
||||
if ids[auth.ID] {
|
||||
return fmt.Errorf("mfa.authenticators: duplicate authenticator id %q", auth.ID)
|
||||
}
|
||||
ids[auth.ID] = true
|
||||
|
||||
if !knownTypes[auth.Type] {
|
||||
return fmt.Errorf("mfa.authenticators: unknown type %q for authenticator %q", auth.Type, auth.ID)
|
||||
}
|
||||
}
|
||||
|
||||
for _, authID := range mfa.DefaultMFAChain {
|
||||
if !ids[authID] {
|
||||
return fmt.Errorf("mfa.defaultMFAChain: references unknown authenticator %q", authID)
|
||||
}
|
||||
}
|
||||
|
||||
for _, client := range c.StaticClients {
|
||||
for _, authID := range client.MFAChain {
|
||||
if !ids[authID] {
|
||||
return fmt.Errorf("staticClients: client %q references unknown MFA authenticator %q", client.ID, authID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -95,19 +181,27 @@ type password storage.Password
|
||||
|
||||
func (p *password) UnmarshalJSON(b []byte) error {
|
||||
var data struct {
|
||||
Email string `json:"email"`
|
||||
Username string `json:"username"`
|
||||
UserID string `json:"userID"`
|
||||
Hash string `json:"hash"`
|
||||
HashFromEnv string `json:"hashFromEnv"`
|
||||
Email string `json:"email"`
|
||||
Username string `json:"username"`
|
||||
Name string `json:"name"`
|
||||
PreferredUsername string `json:"preferredUsername"`
|
||||
EmailVerified *bool `json:"emailVerified"`
|
||||
UserID string `json:"userID"`
|
||||
Hash string `json:"hash"`
|
||||
HashFromEnv string `json:"hashFromEnv"`
|
||||
Groups []string `json:"groups"`
|
||||
}
|
||||
if err := json.Unmarshal(b, &data); err != nil {
|
||||
if err := configUnmarshaller(b, &data); err != nil {
|
||||
return err
|
||||
}
|
||||
*p = password(storage.Password{
|
||||
Email: data.Email,
|
||||
Username: data.Username,
|
||||
UserID: data.UserID,
|
||||
Email: data.Email,
|
||||
Username: data.Username,
|
||||
Name: data.Name,
|
||||
PreferredUsername: data.PreferredUsername,
|
||||
EmailVerified: data.EmailVerified,
|
||||
UserID: data.UserID,
|
||||
Groups: data.Groups,
|
||||
})
|
||||
if len(data.Hash) == 0 && len(data.HashFromEnv) > 0 {
|
||||
data.Hash = os.Getenv(data.HashFromEnv)
|
||||
@@ -149,6 +243,16 @@ type OAuth2 struct {
|
||||
AlwaysShowLoginScreen bool `json:"alwaysShowLoginScreen"`
|
||||
// This is the connector that can be used for password grant
|
||||
PasswordConnector string `json:"passwordConnector"`
|
||||
// PKCE configuration
|
||||
PKCE PKCE `json:"pkce"`
|
||||
}
|
||||
|
||||
// PKCE holds the PKCE (Proof Key for Code Exchange) configuration.
|
||||
type PKCE struct {
|
||||
// If true, PKCE is required for all authorization code flows.
|
||||
Enforce bool `json:"enforce"`
|
||||
// Supported code challenge methods. Defaults to ["S256", "plain"].
|
||||
CodeChallengeMethodsSupported []string `json:"codeChallengeMethodsSupported"`
|
||||
}
|
||||
|
||||
// Web is the config format for the HTTP server.
|
||||
@@ -275,12 +379,12 @@ var (
|
||||
_ StorageConfig = (*ent.MySQL)(nil)
|
||||
)
|
||||
|
||||
func getORMBasedSQLStorage(normal, entBased StorageConfig) func() StorageConfig {
|
||||
func getORMBasedSQLStorage(normal, entBased func() StorageConfig) func() StorageConfig {
|
||||
return func() StorageConfig {
|
||||
if featureflags.EntEnabled.Enabled() {
|
||||
return entBased
|
||||
return entBased()
|
||||
}
|
||||
return normal
|
||||
return normal()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,9 +413,9 @@ var storages = map[string]func() StorageConfig{
|
||||
"etcd": func() StorageConfig { return new(etcd.Etcd) },
|
||||
"kubernetes": func() StorageConfig { return new(kubernetes.Config) },
|
||||
"memory": func() StorageConfig { return new(memory.Config) },
|
||||
"sqlite3": getORMBasedSQLStorage(&sql.SQLite3{}, &ent.SQLite3{}),
|
||||
"postgres": getORMBasedSQLStorage(&sql.Postgres{}, &ent.Postgres{}),
|
||||
"mysql": getORMBasedSQLStorage(&sql.MySQL{}, &ent.MySQL{}),
|
||||
"sqlite3": getORMBasedSQLStorage(func() StorageConfig { return new(sql.SQLite3) }, func() StorageConfig { return new(ent.SQLite3) }),
|
||||
"postgres": getORMBasedSQLStorage(func() StorageConfig { return new(sql.Postgres) }, func() StorageConfig { return new(ent.Postgres) }),
|
||||
"mysql": getORMBasedSQLStorage(func() StorageConfig { return new(sql.MySQL) }, func() StorageConfig { return new(ent.MySQL) }),
|
||||
}
|
||||
|
||||
// UnmarshalJSON allows Storage to implement the unmarshaler interface to
|
||||
@@ -321,7 +425,7 @@ func (s *Storage) UnmarshalJSON(b []byte) error {
|
||||
Type string `json:"type"`
|
||||
Config json.RawMessage `json:"config"`
|
||||
}
|
||||
if err := json.Unmarshal(b, &store); err != nil {
|
||||
if err := configUnmarshaller(b, &store); err != nil {
|
||||
return fmt.Errorf("parse storage: %v", err)
|
||||
}
|
||||
f, ok := storages[store.Type]
|
||||
@@ -334,7 +438,7 @@ func (s *Storage) UnmarshalJSON(b []byte) error {
|
||||
data := []byte(store.Config)
|
||||
if featureflags.ExpandEnv.Enabled() {
|
||||
var rawMap map[string]interface{}
|
||||
if err := json.Unmarshal(store.Config, &rawMap); err != nil {
|
||||
if err := configUnmarshaller(store.Config, &rawMap); err != nil {
|
||||
return fmt.Errorf("unmarshal config for env expansion: %v", err)
|
||||
}
|
||||
|
||||
@@ -351,7 +455,7 @@ func (s *Storage) UnmarshalJSON(b []byte) error {
|
||||
data = expandedData
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(data, storageConfig); err != nil {
|
||||
if err := configUnmarshaller(data, storageConfig); err != nil {
|
||||
return fmt.Errorf("parse storage config: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -362,6 +466,90 @@ func (s *Storage) UnmarshalJSON(b []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Signer holds app's signer configuration.
|
||||
type Signer struct {
|
||||
Type string `json:"type"`
|
||||
Config SignerConfig `json:"config"`
|
||||
}
|
||||
|
||||
// SignerConfig is a configuration that can create a signer.
|
||||
type SignerConfig interface{}
|
||||
|
||||
var (
|
||||
_ SignerConfig = (*signer.LocalConfig)(nil)
|
||||
_ SignerConfig = (*signer.VaultConfig)(nil)
|
||||
)
|
||||
|
||||
var signerConfigs = map[string]func() SignerConfig{
|
||||
"local": func() SignerConfig { return new(signer.LocalConfig) },
|
||||
"vault": func() SignerConfig { return new(signer.VaultConfig) },
|
||||
}
|
||||
|
||||
// UnmarshalJSON allows Signer to implement the unmarshaler interface to
|
||||
// dynamically determine the type of the signer config.
|
||||
func (s *Signer) UnmarshalJSON(b []byte) error {
|
||||
var signerData struct {
|
||||
Type string `json:"type"`
|
||||
Config json.RawMessage `json:"config"`
|
||||
}
|
||||
if err := json.Unmarshal(b, &signerData); err != nil {
|
||||
return fmt.Errorf("parse signer: %v", err)
|
||||
}
|
||||
|
||||
f, ok := signerConfigs[signerData.Type]
|
||||
if !ok {
|
||||
return fmt.Errorf("unknown signer type %q", signerData.Type)
|
||||
}
|
||||
|
||||
signerConfig := f()
|
||||
if len(signerData.Config) != 0 {
|
||||
data := []byte(signerData.Config)
|
||||
if featureflags.ExpandEnv.Enabled() {
|
||||
var rawMap map[string]interface{}
|
||||
if err := json.Unmarshal(signerData.Config, &rawMap); err != nil {
|
||||
return fmt.Errorf("unmarshal config for env expansion: %v", err)
|
||||
}
|
||||
|
||||
// Recursively expand environment variables in the map
|
||||
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, signerConfig); err != nil {
|
||||
return fmt.Errorf("parse signer config: %v", err)
|
||||
}
|
||||
}
|
||||
if localConfig, ok := signerConfig.(*signer.LocalConfig); ok {
|
||||
if err := normalizeLocalSignerConfig(localConfig); err != nil {
|
||||
return fmt.Errorf("parse signer config: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
*s = Signer{
|
||||
Type: signerData.Type,
|
||||
Config: signerConfig,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func normalizeLocalSignerConfig(c *signer.LocalConfig) error {
|
||||
if c.Algorithm == "" {
|
||||
c.Algorithm = jose.RS256
|
||||
return nil
|
||||
}
|
||||
if c.Algorithm == jose.RS256 || c.Algorithm == jose.ES256 {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unsupported local signer algorithm %q", c.Algorithm)
|
||||
}
|
||||
|
||||
// Connector is a magical type that can unmarshal YAML dynamically. The
|
||||
// Type field determines the connector type, which is then customized for Config.
|
||||
type Connector struct {
|
||||
@@ -369,7 +557,8 @@ type Connector struct {
|
||||
Name string `json:"name"`
|
||||
ID string `json:"id"`
|
||||
|
||||
Config server.ConnectorConfig `json:"config"`
|
||||
Config server.ConnectorConfig `json:"config"`
|
||||
GrantTypes []string `json:"grantTypes"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON allows Connector to implement the unmarshaler interface to
|
||||
@@ -380,9 +569,10 @@ func (c *Connector) UnmarshalJSON(b []byte) error {
|
||||
Name string `json:"name"`
|
||||
ID string `json:"id"`
|
||||
|
||||
Config json.RawMessage `json:"config"`
|
||||
Config json.RawMessage `json:"config"`
|
||||
GrantTypes []string `json:"grantTypes"`
|
||||
}
|
||||
if err := json.Unmarshal(b, &conn); err != nil {
|
||||
if err := configUnmarshaller(b, &conn); err != nil {
|
||||
return fmt.Errorf("parse connector: %v", err)
|
||||
}
|
||||
f, ok := server.ConnectorsConfig[conn.Type]
|
||||
@@ -395,7 +585,7 @@ func (c *Connector) UnmarshalJSON(b []byte) error {
|
||||
data := []byte(conn.Config)
|
||||
if featureflags.ExpandEnv.Enabled() {
|
||||
var rawMap map[string]interface{}
|
||||
if err := json.Unmarshal(conn.Config, &rawMap); err != nil {
|
||||
if err := configUnmarshaller(conn.Config, &rawMap); err != nil {
|
||||
return fmt.Errorf("unmarshal config for env expansion: %v", err)
|
||||
}
|
||||
|
||||
@@ -412,16 +602,17 @@ func (c *Connector) UnmarshalJSON(b []byte) error {
|
||||
data = expandedData
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(data, connConfig); err != nil {
|
||||
if err := configUnmarshaller(data, connConfig); err != nil {
|
||||
return fmt.Errorf("parse connector config: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
*c = Connector{
|
||||
Type: conn.Type,
|
||||
Name: conn.Name,
|
||||
ID: conn.ID,
|
||||
Config: connConfig,
|
||||
Type: conn.Type,
|
||||
Name: conn.Name,
|
||||
ID: conn.ID,
|
||||
Config: connConfig,
|
||||
GrantTypes: conn.GrantTypes,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -434,10 +625,11 @@ func ToStorageConnector(c Connector) (storage.Connector, error) {
|
||||
}
|
||||
|
||||
return storage.Connector{
|
||||
ID: c.ID,
|
||||
Type: c.Type,
|
||||
Name: c.Name,
|
||||
Config: data,
|
||||
ID: c.ID,
|
||||
Type: c.Type,
|
||||
Name: c.Name,
|
||||
Config: data,
|
||||
GrantTypes: c.GrantTypes,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -466,6 +658,12 @@ type Logger struct {
|
||||
|
||||
// Format specifies the format to be used for logging.
|
||||
Format string `json:"format"`
|
||||
|
||||
// ExcludeFields specifies log attribute keys that should be dropped from all
|
||||
// log output. This is useful for suppressing PII fields like email, username,
|
||||
// preferred_username, or groups in environments subject to GDPR or similar
|
||||
// data-handling constraints.
|
||||
ExcludeFields []string `json:"excludeFields"`
|
||||
}
|
||||
|
||||
type RefreshToken struct {
|
||||
@@ -474,3 +672,72 @@ type RefreshToken struct {
|
||||
AbsoluteLifetime string `json:"absoluteLifetime"`
|
||||
ValidIfNotUsedFor string `json:"validIfNotUsedFor"`
|
||||
}
|
||||
|
||||
// Sessions holds authentication session configuration.
|
||||
type Sessions struct {
|
||||
// CookieName is the name of the session cookie. Defaults to "dex_session".
|
||||
CookieName string `json:"cookieName"`
|
||||
// AbsoluteLifetime is the maximum session lifetime from creation. Defaults to "24h".
|
||||
AbsoluteLifetime string `json:"absoluteLifetime"`
|
||||
// ValidIfNotUsedFor is the idle timeout. Defaults to "1h".
|
||||
ValidIfNotUsedFor string `json:"validIfNotUsedFor"`
|
||||
// RememberMeCheckedByDefault controls the default state of the "remember me" checkbox.
|
||||
RememberMeCheckedByDefault *bool `json:"rememberMeCheckedByDefault"`
|
||||
// CookieEncryptionKey is the AES key for encrypting session cookies.
|
||||
// Must be 16, 24, or 32 bytes for AES-128, AES-192, or AES-256.
|
||||
// If empty, cookies are not encrypted.
|
||||
CookieEncryptionKey string `json:"cookieEncryptionKey"`
|
||||
// SSOSharedWithDefault is the default SSO sharing policy for clients without explicit ssoSharedWith.
|
||||
// "all" = share with all clients, "none" = share with no one (default: "none").
|
||||
SSOSharedWithDefault string `json:"ssoSharedWithDefault"`
|
||||
}
|
||||
|
||||
// MFAAuthenticator defines a multi-factor authentication provider.
|
||||
type MFAAuthenticator struct {
|
||||
ID string `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Config json.RawMessage `json:"config"`
|
||||
|
||||
// ConnectorTypes limits this authenticator to specific connector types (e.g., "ldap", "oidc", "saml").
|
||||
// If empty, the authenticator applies to all connector types.
|
||||
ConnectorTypes []string `json:"connectorTypes"`
|
||||
}
|
||||
|
||||
// TOTPConfig holds configuration for a TOTP authenticator.
|
||||
type TOTPConfig struct {
|
||||
// Issuer is the name of the service shown in the authenticator app.
|
||||
Issuer string `json:"issuer"`
|
||||
}
|
||||
|
||||
// WebAuthnConfig holds configuration for a WebAuthn authenticator.
|
||||
type WebAuthnConfig struct {
|
||||
// RPDisplayName is the human-readable relying party name shown in the browser
|
||||
// dialog during key registration and authentication (e.g., "My Company SSO").
|
||||
RPDisplayName string `json:"rpDisplayName"`
|
||||
// RPID is the relying party identifier — must match the domain in the browser
|
||||
// address bar. If empty, derived from the issuer URL hostname.
|
||||
// Example: "auth.example.com"
|
||||
RPID string `json:"rpID"`
|
||||
// RPOrigins is the list of allowed origins for WebAuthn ceremonies.
|
||||
// If empty, derived from the issuer URL (scheme + host).
|
||||
// Example: ["https://auth.example.com"]
|
||||
RPOrigins []string `json:"rpOrigins"`
|
||||
// AttestationPreference controls what attestation data the authenticator should provide:
|
||||
// "none" — don't request attestation (simpler, more private)
|
||||
// "indirect" — authenticator may anonymize attestation (default)
|
||||
// "direct" — request full attestation (for enterprise key model verification)
|
||||
AttestationPreference string `json:"attestationPreference"`
|
||||
// UserVerification controls whether PIN or biometric verification is required:
|
||||
// "required" — always require (PIN, fingerprint, etc.)
|
||||
// "preferred" — request if the authenticator supports it (default)
|
||||
// "discouraged" — skip verification, presence check only
|
||||
UserVerification string `json:"userVerification"`
|
||||
// AuthenticatorAttachment restricts which authenticator types are allowed:
|
||||
// "platform" — built-in only (Touch ID, Windows Hello)
|
||||
// "cross-platform" — external only (YubiKey, USB security keys)
|
||||
// "" — any authenticator (default)
|
||||
AuthenticatorAttachment string `json:"authenticatorAttachment"`
|
||||
// Timeout is the duration allowed for the browser WebAuthn ceremony
|
||||
// (registration or login). Defaults to "60s".
|
||||
Timeout string `json:"timeout"`
|
||||
}
|
||||
|
||||
+227
-4
@@ -1,22 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/go-jose/go-jose/v4"
|
||||
"github.com/kylelemons/godebug/pretty"
|
||||
|
||||
"github.com/dexidp/dex/connector/mock"
|
||||
"github.com/dexidp/dex/connector/oidc"
|
||||
"github.com/dexidp/dex/server"
|
||||
"github.com/dexidp/dex/server/signer"
|
||||
"github.com/dexidp/dex/storage"
|
||||
"github.com/dexidp/dex/storage/sql"
|
||||
)
|
||||
|
||||
var _ = yaml.YAMLToJSON
|
||||
|
||||
func boolPtr(v bool) *bool {
|
||||
return &v
|
||||
}
|
||||
|
||||
func TestValidConfiguration(t *testing.T) {
|
||||
configuration := Config{
|
||||
Issuer: "http://127.0.0.1:5556/dex",
|
||||
@@ -101,6 +109,9 @@ connectors:
|
||||
- type: mockCallback
|
||||
id: mock
|
||||
name: Example
|
||||
grantTypes:
|
||||
- authorization_code
|
||||
- "urn:ietf:params:oauth:grant-type:token-exchange"
|
||||
- type: oidc
|
||||
id: google
|
||||
name: Google
|
||||
@@ -116,6 +127,12 @@ staticPasswords:
|
||||
# bcrypt hash of the string "password"
|
||||
hash: "$2a$10$33EMT0cVYVlPy6WAMCLsceLYjWhuHpbz5yuZxu/GAFj03J9Lytjuy"
|
||||
username: "admin"
|
||||
name: "Admin User"
|
||||
emailVerified: false
|
||||
preferredUsername: "admin-public"
|
||||
groups:
|
||||
- "team-a"
|
||||
- "team-a/admins"
|
||||
userID: "08a8684b-db88-4b73-90a9-3cd1661f5466"
|
||||
- email: "foo@example.com"
|
||||
# base64'd value of the same bcrypt hash above. We want to be able to parse both of these
|
||||
@@ -190,6 +207,10 @@ additionalFeatures: [
|
||||
ID: "mock",
|
||||
Name: "Example",
|
||||
Config: &mock.CallbackConfig{},
|
||||
GrantTypes: []string{
|
||||
"authorization_code",
|
||||
"urn:ietf:params:oauth:grant-type:token-exchange",
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: "oidc",
|
||||
@@ -206,10 +227,17 @@ additionalFeatures: [
|
||||
EnablePasswordDB: true,
|
||||
StaticPasswords: []password{
|
||||
{
|
||||
Email: "admin@example.com",
|
||||
Hash: []byte("$2a$10$33EMT0cVYVlPy6WAMCLsceLYjWhuHpbz5yuZxu/GAFj03J9Lytjuy"),
|
||||
Username: "admin",
|
||||
UserID: "08a8684b-db88-4b73-90a9-3cd1661f5466",
|
||||
Email: "admin@example.com",
|
||||
Hash: []byte("$2a$10$33EMT0cVYVlPy6WAMCLsceLYjWhuHpbz5yuZxu/GAFj03J9Lytjuy"),
|
||||
Username: "admin",
|
||||
Name: "Admin User",
|
||||
EmailVerified: boolPtr(false),
|
||||
PreferredUsername: "admin-public",
|
||||
UserID: "08a8684b-db88-4b73-90a9-3cd1661f5466",
|
||||
Groups: []string{
|
||||
"team-a",
|
||||
"team-a/admins",
|
||||
},
|
||||
},
|
||||
{
|
||||
Email: "foo@example.com",
|
||||
@@ -452,3 +480,198 @@ logger:
|
||||
t.Errorf("got!=want: %s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignerConfigUnmarshal(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
config string
|
||||
wantErr bool
|
||||
errContains string
|
||||
check func(*Config) error
|
||||
}{
|
||||
{
|
||||
name: "local signer with rotation period",
|
||||
config: `
|
||||
issuer: http://127.0.0.1:5556/dex
|
||||
storage:
|
||||
type: memory
|
||||
web:
|
||||
http: 0.0.0.0:5556
|
||||
signer:
|
||||
type: local
|
||||
config:
|
||||
keysRotationPeriod: 6h
|
||||
enablePasswordDB: true
|
||||
`,
|
||||
wantErr: false,
|
||||
check: func(c *Config) error {
|
||||
if c.Signer.Type != "local" {
|
||||
t.Errorf("expected signer type 'local', got %q", c.Signer.Type)
|
||||
}
|
||||
if localConfig, ok := c.Signer.Config.(*signer.LocalConfig); !ok {
|
||||
t.Error("expected LocalConfig")
|
||||
} else {
|
||||
if localConfig.KeysRotationPeriod != "6h" {
|
||||
t.Errorf("expected keys rotation period '6h', got %q", localConfig.KeysRotationPeriod)
|
||||
}
|
||||
if localConfig.Algorithm != jose.RS256 {
|
||||
t.Errorf("expected default algorithm 'RS256', got %q", localConfig.Algorithm)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "local signer with ES256 algorithm",
|
||||
config: `
|
||||
issuer: http://127.0.0.1:5556/dex
|
||||
storage:
|
||||
type: memory
|
||||
web:
|
||||
http: 0.0.0.0:5556
|
||||
signer:
|
||||
type: local
|
||||
config:
|
||||
keysRotationPeriod: 6h
|
||||
algorithm: ES256
|
||||
enablePasswordDB: true
|
||||
`,
|
||||
wantErr: false,
|
||||
check: func(c *Config) error {
|
||||
localConfig, ok := c.Signer.Config.(*signer.LocalConfig)
|
||||
if !ok {
|
||||
t.Error("expected LocalConfig")
|
||||
return nil
|
||||
}
|
||||
if localConfig.Algorithm != jose.ES256 {
|
||||
t.Errorf("expected algorithm 'ES256', got %q", localConfig.Algorithm)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "local signer with invalid algorithm",
|
||||
config: `
|
||||
issuer: http://127.0.0.1:5556/dex
|
||||
storage:
|
||||
type: memory
|
||||
web:
|
||||
http: 0.0.0.0:5556
|
||||
signer:
|
||||
type: local
|
||||
config:
|
||||
keysRotationPeriod: 6h
|
||||
algorithm: ES512
|
||||
enablePasswordDB: true
|
||||
`,
|
||||
wantErr: true,
|
||||
errContains: `parse signer config: unsupported local signer algorithm "ES512"`,
|
||||
},
|
||||
{
|
||||
name: "local signer without config",
|
||||
config: `
|
||||
issuer: http://127.0.0.1:5556/dex
|
||||
storage:
|
||||
type: memory
|
||||
web:
|
||||
http: 0.0.0.0:5556
|
||||
signer:
|
||||
type: local
|
||||
enablePasswordDB: true
|
||||
`,
|
||||
wantErr: false,
|
||||
check: func(c *Config) error {
|
||||
localConfig, ok := c.Signer.Config.(*signer.LocalConfig)
|
||||
if !ok {
|
||||
t.Error("expected LocalConfig")
|
||||
return nil
|
||||
}
|
||||
if localConfig.Algorithm != jose.RS256 {
|
||||
t.Errorf("expected default algorithm 'RS256', got %q", localConfig.Algorithm)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "vault signer",
|
||||
config: `
|
||||
issuer: http://127.0.0.1:5556/dex
|
||||
storage:
|
||||
type: memory
|
||||
web:
|
||||
http: 0.0.0.0:5556
|
||||
signer:
|
||||
type: vault
|
||||
config:
|
||||
addr: http://localhost:8200
|
||||
token: test-token
|
||||
keyName: test-key
|
||||
enablePasswordDB: true
|
||||
`,
|
||||
wantErr: false,
|
||||
check: func(c *Config) error {
|
||||
if c.Signer.Type != "vault" {
|
||||
t.Errorf("expected signer type 'vault', got %q", c.Signer.Type)
|
||||
}
|
||||
if vaultConfig, ok := c.Signer.Config.(*signer.VaultConfig); !ok {
|
||||
t.Error("expected VaultConfig")
|
||||
} else {
|
||||
if vaultConfig.Addr != "http://localhost:8200" {
|
||||
t.Errorf("expected addr 'http://localhost:8200', got %q", vaultConfig.Addr)
|
||||
}
|
||||
if vaultConfig.Token != "test-token" {
|
||||
t.Errorf("expected token 'test-token', got %q", vaultConfig.Token)
|
||||
}
|
||||
if vaultConfig.KeyName != "test-key" {
|
||||
t.Errorf("expected keyName 'test-key', got %q", vaultConfig.KeyName)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "default to local when no signer specified",
|
||||
config: `
|
||||
issuer: http://127.0.0.1:5556/dex
|
||||
storage:
|
||||
type: memory
|
||||
web:
|
||||
http: 0.0.0.0:5556
|
||||
enablePasswordDB: true
|
||||
`,
|
||||
wantErr: false,
|
||||
check: func(c *Config) error {
|
||||
if c.Signer.Type != "" {
|
||||
t.Errorf("expected signer type '', got %q", c.Signer.Type)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var c Config
|
||||
data, err := yaml.YAMLToJSON([]byte(tt.config))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to convert yaml to json: %v", err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(data, &c)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("Unmarshal() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if tt.errContains != "" && (err == nil || !strings.Contains(err.Error(), tt.errContains)) {
|
||||
t.Errorf("Unmarshal() error = %v, want substring %q", err, tt.errContains)
|
||||
return
|
||||
}
|
||||
|
||||
if err == nil && tt.check != nil {
|
||||
if err := tt.check(&c); err != nil {
|
||||
t.Errorf("check failed: %v", err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
// excludingHandler is an slog.Handler wrapper that drops log attributes
|
||||
// whose keys match a configured set. This allows PII fields like email,
|
||||
// username, or groups to be redacted at the logger level rather than
|
||||
// requiring per-callsite suppression logic.
|
||||
type excludingHandler struct {
|
||||
inner slog.Handler
|
||||
exclude map[string]bool
|
||||
}
|
||||
|
||||
func newExcludingHandler(inner slog.Handler, fields []string) slog.Handler {
|
||||
if len(fields) == 0 {
|
||||
return inner
|
||||
}
|
||||
m := make(map[string]bool, len(fields))
|
||||
for _, f := range fields {
|
||||
m[f] = true
|
||||
}
|
||||
return &excludingHandler{inner: inner, exclude: m}
|
||||
}
|
||||
|
||||
func (h *excludingHandler) Enabled(ctx context.Context, level slog.Level) bool {
|
||||
return h.inner.Enabled(ctx, level)
|
||||
}
|
||||
|
||||
func (h *excludingHandler) Handle(ctx context.Context, record slog.Record) error {
|
||||
// Rebuild the record without excluded attributes.
|
||||
filtered := slog.NewRecord(record.Time, record.Level, record.Message, record.PC)
|
||||
record.Attrs(func(a slog.Attr) bool {
|
||||
if !h.exclude[a.Key] {
|
||||
filtered.AddAttrs(a)
|
||||
}
|
||||
return true
|
||||
})
|
||||
return h.inner.Handle(ctx, filtered)
|
||||
}
|
||||
|
||||
func (h *excludingHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
|
||||
var kept []slog.Attr
|
||||
for _, a := range attrs {
|
||||
if !h.exclude[a.Key] {
|
||||
kept = append(kept, a)
|
||||
}
|
||||
}
|
||||
return &excludingHandler{inner: h.inner.WithAttrs(kept), exclude: h.exclude}
|
||||
}
|
||||
|
||||
func (h *excludingHandler) WithGroup(name string) slog.Handler {
|
||||
return &excludingHandler{inner: h.inner.WithGroup(name), exclude: h.exclude}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user